diff options
371 files changed, 5975 insertions, 2447 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index fabc064..9b1f6ca 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -136,7 +136,7 @@ quiet_cmd_db2ps = PS $@ %.ps : %.xml $(call cmd,db2ps) -quiet_cmd_db2pdf = PDF $@ +quiet_cmd_db2pdf = PDF $@ cmd_db2pdf = $(subst TYPE,pdf, $($(PDF_METHOD)template)) %.pdf : %.xml $(call cmd,db2pdf) @@ -148,7 +148,7 @@ build_main_index = rm -rf $(main_idx) && \ echo '<h2>Kernel Version: $(KERNELVERSION)</h2>' >> $(main_idx) && \ cat $(HTML) >> $(main_idx) -quiet_cmd_db2html = HTML $@ +quiet_cmd_db2html = HTML $@ cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \ echo '<a HREF="$(patsubst %.html,%,$(notdir $@))/index.html"> \ $(patsubst %.html,%,$(notdir $@))</a><p>' > $@ diff --git a/Documentation/DocBook/deviceiobook.tmpl b/Documentation/DocBook/deviceiobook.tmpl index 60d6e0b..3ed8812 100644 --- a/Documentation/DocBook/deviceiobook.tmpl +++ b/Documentation/DocBook/deviceiobook.tmpl @@ -24,7 +24,7 @@ <surname>Cox</surname> <affiliation> <address> - <email>alan@redhat.com</email> + <email>alan@lxorguk.ukuu.org.uk</email> </address> </affiliation> </author> diff --git a/Documentation/DocBook/mcabook.tmpl b/Documentation/DocBook/mcabook.tmpl index 499eddc..467ccac 100644 --- a/Documentation/DocBook/mcabook.tmpl +++ b/Documentation/DocBook/mcabook.tmpl @@ -12,7 +12,7 @@ <surname>Cox</surname> <affiliation> <address> - <email>alan@redhat.com</email> + <email>alan@lxorguk.ukuu.org.uk</email> </address> </affiliation> </author> diff --git a/Documentation/DocBook/wanbook.tmpl b/Documentation/DocBook/wanbook.tmpl index 9eebcc3..8c93db1 100644 --- a/Documentation/DocBook/wanbook.tmpl +++ b/Documentation/DocBook/wanbook.tmpl @@ -12,7 +12,7 @@ <surname>Cox</surname> <affiliation> <address> - <email>alan@redhat.com</email> + <email>alan@lxorguk.ukuu.org.uk</email> </address> </affiliation> </author> diff --git a/Documentation/DocBook/z8530book.tmpl b/Documentation/DocBook/z8530book.tmpl index a42a8a4..6f3883b 100644 --- a/Documentation/DocBook/z8530book.tmpl +++ b/Documentation/DocBook/z8530book.tmpl @@ -12,7 +12,7 @@ <surname>Cox</surname> <affiliation> <address> - <email>alan@redhat.com</email> + <email>alan@lxorguk.ukuu.org.uk</email> </address> </affiliation> </author> diff --git a/Documentation/ManagementStyle b/Documentation/ManagementStyle index 49a8efa..a5f0ea5 100644 --- a/Documentation/ManagementStyle +++ b/Documentation/ManagementStyle @@ -17,7 +17,7 @@ companies. If you sign purchase orders or you have any clue about the budget of your group, you're almost certainly not a kernel manager. These suggestions may or may not apply to you. -First off, I'd suggest buying "Seven Habits of Highly Successful +First off, I'd suggest buying "Seven Habits of Highly Effective People", and NOT read it. Burn it, it's a great symbolic gesture. (*) This document does so not so much by answering the question, but by diff --git a/Documentation/accounting/.gitignore b/Documentation/accounting/.gitignore new file mode 100644 index 0000000..8648520 --- /dev/null +++ b/Documentation/accounting/.gitignore @@ -0,0 +1 @@ +getdelays diff --git a/Documentation/auxdisplay/.gitignore b/Documentation/auxdisplay/.gitignore new file mode 100644 index 0000000..7af2228 --- /dev/null +++ b/Documentation/auxdisplay/.gitignore @@ -0,0 +1 @@ +cfag12864b-example diff --git a/Documentation/connector/.gitignore b/Documentation/connector/.gitignore new file mode 100644 index 0000000..d2b9c32 --- /dev/null +++ b/Documentation/connector/.gitignore @@ -0,0 +1 @@ +ucon diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 8362860..23d2f44 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -161,8 +161,12 @@ prototypes: int (*set_page_dirty)(struct page *page); int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages); - int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); - int (*commit_write)(struct file *, struct page *, unsigned, unsigned); + int (*write_begin)(struct file *, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata); + int (*write_end)(struct file *, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata); sector_t (*bmap)(struct address_space *, sector_t); int (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, int); @@ -180,8 +184,6 @@ sync_page: no maybe writepages: no set_page_dirty no no readpages: no -prepare_write: no yes yes -commit_write: no yes yes write_begin: no locks the page yes write_end: no yes, unlocks yes perform_write: no n/a yes @@ -191,7 +193,7 @@ releasepage: no yes direct_IO: no launder_page: no yes - ->prepare_write(), ->commit_write(), ->sync_page() and ->readpage() + ->write_begin(), ->write_end(), ->sync_page() and ->readpage() may be called from the request handler (/dev/loop). ->readpage() unlocks the page, either synchronously or via I/O diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index c4d348d..5579bda 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -492,7 +492,7 @@ written-back to storage typically in whole pages, however the address_space has finer control of write sizes. The read process essentially only requires 'readpage'. The write -process is more complicated and uses prepare_write/commit_write or +process is more complicated and uses write_begin/write_end or set_page_dirty to write data into the address_space, and writepage, sync_page, and writepages to writeback data to storage. @@ -521,8 +521,6 @@ struct address_space_operations { int (*set_page_dirty)(struct page *page); int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages); - int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); - int (*commit_write)(struct file *, struct page *, unsigned, unsigned); int (*write_begin)(struct file *, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); @@ -598,37 +596,7 @@ struct address_space_operations { readpages is only used for read-ahead, so read errors are ignored. If anything goes wrong, feel free to give up. - prepare_write: called by the generic write path in VM to set up a write - request for a page. This indicates to the address space that - the given range of bytes is about to be written. The - address_space should check that the write will be able to - complete, by allocating space if necessary and doing any other - internal housekeeping. If the write will update parts of - any basic-blocks on storage, then those blocks should be - pre-read (if they haven't been read already) so that the - updated blocks can be written out properly. - The page will be locked. - - Note: the page _must not_ be marked uptodate in this function - (or anywhere else) unless it actually is uptodate right now. As - soon as a page is marked uptodate, it is possible for a concurrent - read(2) to copy it to userspace. - - commit_write: If prepare_write succeeds, new data will be copied - into the page and then commit_write will be called. It will - typically update the size of the file (if appropriate) and - mark the inode as dirty, and do any other related housekeeping - operations. It should avoid returning an error if possible - - errors should have been handled by prepare_write. - - write_begin: This is intended as a replacement for prepare_write. The - key differences being that: - - it returns a locked page (in *pagep) rather than being - given a pre locked page; - - it must be able to cope with short writes (where the - length passed to write_begin is greater than the number - of bytes copied into the page). - + write_begin: Called by the generic buffered write code to ask the filesystem to prepare to write len bytes at the given offset in the file. The address_space should check that the write will be able to complete, @@ -640,6 +608,9 @@ struct address_space_operations { The filesystem must return the locked pagecache page for the specified offset, in *pagep, for the caller to write into. + It must be able to cope with short writes (where the length passed to + write_begin is greater than the number of bytes copied into the page). + flags is a field for AOP_FLAG_xxx flags, described in include/linux/fs.h. diff --git a/Documentation/i2c/busses/i2c-sis96x b/Documentation/i2c/busses/i2c-sis96x index 266481f..70e6a0c 100644 --- a/Documentation/i2c/busses/i2c-sis96x +++ b/Documentation/i2c/busses/i2c-sis96x @@ -42,7 +42,7 @@ I suspect that this driver could be made to work for the following SiS chipsets as well: 635, and 635T. If anyone owns a board with those chips AND is willing to risk crashing & burning an otherwise well-behaved kernel in the name of progress... please contact me at <mhoffman@lightlink.com> or -via the project's mailing list: <i2c@lm-sensors.org>. Please send bug +via the linux-i2c mailing list: <linux-i2c@vger.kernel.org>. Please send bug reports and/or success stories as well. diff --git a/Documentation/ia64/.gitignore b/Documentation/ia64/.gitignore new file mode 100644 index 0000000..ab806ed --- /dev/null +++ b/Documentation/ia64/.gitignore @@ -0,0 +1 @@ +aliasing-test diff --git a/Documentation/isdn/CREDITS b/Documentation/isdn/CREDITS index 8cac6c2..c1679e9 100644 --- a/Documentation/isdn/CREDITS +++ b/Documentation/isdn/CREDITS @@ -5,7 +5,7 @@ I want to thank all who contributed to this project and especially to: Thomas Bogendörfer (tsbogend@bigbug.franken.de) Tester, lots of bugfixes and hints. -Alan Cox (alan@redhat.com) +Alan Cox (alan@lxorguk.ukuu.org.uk) For help getting into standard-kernel. Henner Eisen (eis@baty.hanse.de) diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index 0775cf4..5547698 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO @@ -11,14 +11,14 @@ for non English (read: Japanese) speakers and is not intended as a fork. So if you have any comments or updates for this file, please try to update the original English file first. -Last Updated: 2008/08/21 +Last Updated: 2008/10/24 ================================== ã“ã‚Œã¯ã€ -linux-2.6.27/Documentation/HOWTO +linux-2.6.28/Documentation/HOWTO ã®å’Œè¨³ã§ã™ã€‚ 翻訳団体: JF プãƒã‚¸ã‚§ã‚¯ãƒˆ < http://www.linux.or.jp/JF/ > -翻訳日: 2008/8/5 +翻訳日: 2008/10/24 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com> æ ¡æ£è€…: æ¾å€‰ã•ã‚“ <nbh--mats at nifty dot com> å°æž— é›…å…¸ã•ã‚“ (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp> @@ -110,8 +110,8 @@ Linux カーãƒãƒ«ã‚½ãƒ¼ã‚¹ãƒ„リーã¯å¹…広ã„範囲ã®ãƒ‰ã‚ュメントをå æ–°ã—ã„ドã‚ãƒ¥ãƒ¡ãƒ³ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ã‚‚è¿½åŠ ã™ã‚‹ã“ã¨ã‚’勧ã‚ã¾ã™ã€‚ カーãƒãƒ«ã®å¤‰æ›´ãŒã€ã‚«ãƒ¼ãƒãƒ«ãŒãƒ¦ãƒ¼ã‚¶ç©ºé–“ã«å…¬é–‹ã—ã¦ã„るインターフェイス㮠変更を引ãèµ·ã“ã™å ´åˆã€ãã®å¤‰æ›´ã‚’説明ã™ã‚‹ãƒžãƒ‹ãƒ¥ã‚¢ãƒ«ãƒšãƒ¼ã‚¸ã®ãƒ‘ッãƒã‚„æƒ…å ± -をマニュアルページã®ãƒ¡ãƒ³ãƒ†ãƒŠ mtk.manpages@gmail.com ã«é€ã‚‹ã“ã¨ã‚’勧ã‚ã¾ -ã™ã€‚ +をマニュアルページã®ãƒ¡ãƒ³ãƒ†ãƒŠ mtk.manpages@gmail.com ã«é€ã‚Šã€CC ã‚’ +linux-api@ver.kernel.org ã«é€ã‚‹ã“ã¨ã‚’勧ã‚ã¾ã™ã€‚ 以下ã¯ã‚«ãƒ¼ãƒãƒ«ã‚½ãƒ¼ã‚¹ãƒ„リーã«å«ã¾ã‚Œã¦ã„ã‚‹èªã‚“ã§ãŠãã¹ãファイルã®ä¸€è¦§ã§ ã™- @@ -149,7 +149,7 @@ Linux カーãƒãƒ«ã‚½ãƒ¼ã‚¹ãƒ„リーã¯å¹…広ã„範囲ã®ãƒ‰ã‚ュメントをå ã“ã®ä»–ã«ãƒ‘ッãƒã‚’作る方法ã«ã¤ã„ã¦ã®ã‚ˆãã§ããŸè¨˜è¿°ã¯- "The Perfect Patch" - http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt + http://userweb.kernel.org/~akpm/stuff/tpp.txt "Linux kernel patch submission format" http://linux.yyz.us/patch-format.html @@ -664,7 +664,7 @@ Linux カーãƒãƒ«ã‚³ãƒŸãƒ¥ãƒ‹ãƒ†ã‚£ã¯ã€ä¸€åº¦ã«å¤§é‡ã®ã‚³ãƒ¼ãƒ‰ã®å¡Šã‚’å– ã“ã‚Œã«ã¤ã„ã¦å…¨ã¦ãŒã©ã®ã‚ˆã†ã«ã‚ã‚‹ã¹ãã‹ã«ã¤ã„ã¦ã®è©³ç´°ã¯ã€ä»¥ä¸‹ã®ãƒ‰ã‚ュメ ント㮠ChangeLog セクションを見ã¦ãã ã•ã„- "The Perfect Patch" - http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt + http://userweb.kernel.org/~akpm/stuff/tpp.txt ã“れらã®ã©ã‚Œã‚‚ãŒã€æ™‚ã«ã¯ã¨ã¦ã‚‚困難ã§ã™ã€‚ã“れらã®æ…£ä¾‹ã‚’完璧ã«å®Ÿæ–½ã™ã‚‹ã« ã¯æ•°å¹´ã‹ã‹ã‚‹ã‹ã‚‚ã—ã‚Œã¾ã›ã‚“。ã“ã‚Œã¯ç¶™ç¶šçš„ãªæ”¹å–„ã®ãƒ—ãƒã‚»ã‚¹ã§ã‚ã‚Šã€ãã®ãŸ diff --git a/Documentation/networking/.gitignore b/Documentation/networking/.gitignore new file mode 100644 index 0000000..286a568 --- /dev/null +++ b/Documentation/networking/.gitignore @@ -0,0 +1 @@ +ifenslave diff --git a/Documentation/networking/dmfe.txt b/Documentation/networking/dmfe.txt index b1b7499..8006c22 100644 --- a/Documentation/networking/dmfe.txt +++ b/Documentation/networking/dmfe.txt @@ -60,6 +60,6 @@ Tobias Ringstrom <tori@unhappy.mine.nu> : Current Maintainer Contributors: Marcelo Tosatti <marcelo@conectiva.com.br> -Alan Cox <alan@redhat.com> +Alan Cox <alan@lxorguk.ukuu.org.uk> Jeff Garzik <jgarzik@pobox.com> Vojtech Pavlik <vojtech@suse.cz> diff --git a/Documentation/pcmcia/.gitignore b/Documentation/pcmcia/.gitignore new file mode 100644 index 0000000..53d0813 --- /dev/null +++ b/Documentation/pcmcia/.gitignore @@ -0,0 +1 @@ +crc32hash diff --git a/Documentation/scheduler/sched-design-CFS.txt b/Documentation/scheduler/sched-design-CFS.txt index 9d8eb55..eb471c7 100644 --- a/Documentation/scheduler/sched-design-CFS.txt +++ b/Documentation/scheduler/sched-design-CFS.txt @@ -92,7 +92,7 @@ other HZ detail. Thus the CFS scheduler has no notion of "timeslices" in the way the previous scheduler had, and has no heuristics whatsoever. There is only one central tunable (you have to switch on CONFIG_SCHED_DEBUG): - /proc/sys/kernel/sched_granularity_ns + /proc/sys/kernel/sched_min_granularity_ns which can be used to tune the scheduler from "desktop" (i.e., low latencies) to "server" (i.e., good batching) workloads. It defaults to a setting suitable diff --git a/Documentation/scsi/aacraid.txt b/Documentation/scsi/aacraid.txt index 709ca99..ddace3a 100644 --- a/Documentation/scsi/aacraid.txt +++ b/Documentation/scsi/aacraid.txt @@ -128,7 +128,7 @@ Supported Cards/Chipsets People ------------------------- -Alan Cox <alan@redhat.com> +Alan Cox <alan@lxorguk.ukuu.org.uk> Christoph Hellwig <hch@infradead.org> (updates for new-style PCI probing and SCSI host registration, small cleanups/fixes) Matt Domsch <matt_domsch@dell.com> (revision ioctl, adapter messages) diff --git a/Documentation/spi/.gitignore b/Documentation/spi/.gitignore new file mode 100644 index 0000000..4280576 --- /dev/null +++ b/Documentation/spi/.gitignore @@ -0,0 +1,2 @@ +spidev_fdx +spidev_test diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index 4cfc788..a452227 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -12,6 +12,7 @@ Rules on what kind of patches are accepted, and which ones are not, into the marked CONFIG_BROKEN), an oops, a hang, data corruption, a real security issue, or some "oh, that's not good" issue. In short, something critical. + - New device IDs and quirks are also accepted. - No "theoretical race condition" issues, unless an explanation of how the race can be exploited is also provided. - It cannot contain any "trivial" fixes in it (spelling changes, diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index bde799e..a4ccdd1 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -363,11 +363,21 @@ tainted: Non-zero if the kernel has been tainted. Numeric values, which can be ORed together: - 1 - A module with a non-GPL license has been loaded, this - includes modules with no license. - Set by modutils >= 2.4.9 and module-init-tools. - 2 - A module was force loaded by insmod -f. - Set by modutils >= 2.4.9 and module-init-tools. - 4 - Unsafe SMP processors: SMP with CPUs not designed for SMP. - 64 - A module from drivers/staging was loaded. + 1 - A module with a non-GPL license has been loaded, this + includes modules with no license. + Set by modutils >= 2.4.9 and module-init-tools. + 2 - A module was force loaded by insmod -f. + Set by modutils >= 2.4.9 and module-init-tools. + 4 - Unsafe SMP processors: SMP with CPUs not designed for SMP. + 8 - A module was forcibly unloaded from the system by rmmod -f. + 16 - A hardware machine check error occurred on the system. + 32 - A bad page was discovered on the system. + 64 - The user has asked that the system be marked "tainted". This + could be because they are running software that directly modifies + the hardware, or for other reasons. + 128 - The system has died. + 256 - The ACPI DSDT has been overridden with one supplied by the user + instead of using the one provided by the hardware. + 512 - A kernel warning has occurred. +1024 - A module from drivers/staging was loaded. diff --git a/Documentation/video4linux/.gitignore b/Documentation/video4linux/.gitignore new file mode 100644 index 0000000..9527039 --- /dev/null +++ b/Documentation/video4linux/.gitignore @@ -0,0 +1 @@ +v4lgrab diff --git a/Documentation/video4linux/bttv/CONTRIBUTORS b/Documentation/video4linux/bttv/CONTRIBUTORS index 8aad6dd..eb41b26 100644 --- a/Documentation/video4linux/bttv/CONTRIBUTORS +++ b/Documentation/video4linux/bttv/CONTRIBUTORS @@ -3,7 +3,7 @@ Contributors to bttv: Michael Chu <mmchu@pobox.com> AverMedia fix and more flexible card recognition -Alan Cox <alan@redhat.com> +Alan Cox <alan@lxorguk.ukuu.org.uk> Video4Linux interface and 2.1.x kernel adaptation Chris Kleitsch diff --git a/Documentation/vm/.gitignore b/Documentation/vm/.gitignore new file mode 100644 index 0000000..33e8a02 --- /dev/null +++ b/Documentation/vm/.gitignore @@ -0,0 +1 @@ +slabinfo diff --git a/Documentation/watchdog/src/.gitignore b/Documentation/watchdog/src/.gitignore new file mode 100644 index 0000000..ac90997 --- /dev/null +++ b/Documentation/watchdog/src/.gitignore @@ -0,0 +1,2 @@ +watchdog-simple +watchdog-test diff --git a/MAINTAINERS b/MAINTAINERS index 16202c8..c842ec3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -347,7 +347,7 @@ S: Maintained ALI1563 I2C DRIVER P: Rudolf Marek M: r.marek@assembler.cz -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained ALPHA PORT @@ -1749,7 +1749,7 @@ FREESCALE I2C CPM DRIVER P: Jochen Friedrich M: jochen@scram.de L: linuxppc-dev@ozlabs.org -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained FREESCALE SOC FS_ENET DRIVER @@ -2022,7 +2022,7 @@ S: Maintained I2C/SMBUS STUB DRIVER P: Mark M. Hoffman M: mhoffman@lightlink.com -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained I2C SUBSYSTEM @@ -2030,14 +2030,14 @@ P: Jean Delvare (PC drivers, core) M: khali@linux-fr.org P: Ben Dooks (embedded platforms) M: ben-linux@fluff.org -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ S: Maintained I2C-TINY-USB DRIVER P: Till Harbaum M: till@harbaum.org -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org T: http://www.harbaum.org/till/i2c_tiny_usb S: Maintained @@ -2701,6 +2701,16 @@ M: matthew@wil.cx L: linux-scsi@vger.kernel.org S: Maintained +LTP (Linux Test Project) +P: Subrata Modak +M: subrata@linux.vnet.ibm.com +P: Mike Frysinger +M: vapier@gentoo.org +L: ltp-list@lists.sourceforge.net (subscribers-only) +W: http://ltp.sourceforge.net/ +T: git kernel.org/pub/scm/linux/kernel/git/galak/ltp.git +S: Maintained + M32R ARCHITECTURE P: Hirokazu Takata M: takata@linux-m32r.org @@ -3143,7 +3153,7 @@ S: Maintained OPENCORES I2C BUS DRIVER P: Peter Korsgaard M: jacmet@sunsite.dk -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained OPROFILE @@ -3190,7 +3200,7 @@ S: Maintained PA SEMI SMBUS DRIVER P: Olof Johansson M: olof@lixom.net -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained PANASONIC LAPTOP ACPI EXTRAS DRIVER @@ -3335,7 +3345,7 @@ S: Maintained PNXxxxx I2C DRIVER P: Vitaly Wool M: vitalywool@gmail.com -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained PPP PROTOCOL DRIVERS AND COMPRESSORS @@ -3799,7 +3809,7 @@ S: Maintained SIS 96X I2C/SMBUS DRIVER P: Mark M. Hoffman M: mhoffman@lightlink.com -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained SIS FRAMEBUFFER DRIVER @@ -4546,7 +4556,7 @@ S: Maintained VIAPRO SMBUS DRIVER P: Jean Delvare M: khali@linux-fr.org -L: i2c@lm-sensors.org +L: linux-i2c@vger.kernel.org S: Maintained VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER @@ -536,7 +536,7 @@ KBUILD_CFLAGS += -g KBUILD_AFLAGS += -gdwarf-2 endif -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER KBUILD_CFLAGS += -pg endif diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5021db2..9722f8b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -16,8 +16,7 @@ config ARM select HAVE_ARCH_KGDB select HAVE_KPROBES if (!XIP_KERNEL) select HAVE_KRETPROBES if (HAVE_KPROBES) - select HAVE_FTRACE if (!XIP_KERNEL) - select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE) + select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) select HAVE_GENERIC_DMA_COHERENT help The ARM series is a line of low-power-consumption RISC chip designs diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 7a03f20..c47f2a3 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -70,7 +70,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ targets := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c \ head.o misc.o $(OBJS) -ifeq ($(CONFIG_FTRACE),y) +ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) endif diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index 584ef9a..39c8bc1 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h @@ -1,7 +1,7 @@ #ifndef _ASM_ARM_FTRACE #define _ASM_ARM_FTRACE -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_ADDR ((long)(mcount)) #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 2357b1c..c74f766 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -183,6 +183,6 @@ EXPORT_SYMBOL(_find_next_bit_be); EXPORT_SYMBOL(copy_page); -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER EXPORT_SYMBOL(mcount); #endif diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 3aa14dc..06269ea 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -101,7 +101,7 @@ ENDPROC(ret_from_fork) #undef CALL #define CALL(x) .long x -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(mcount) stmdb sp!, {r0-r3, lr} @@ -149,7 +149,7 @@ trace: ftrace_stub: mov pc, lr -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ /*============================================================================= * SWI handler diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 76d50e6..6c90479 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -95,19 +95,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } -int ftrace_mcount_set(unsigned long *data) -{ - unsigned long pc, old; - unsigned long *addr = data; - unsigned char *new; - - pc = (unsigned long)&mcount_call; - memcpy(&old, &mcount_call, MCOUNT_INSN_SIZE); - new = ftrace_call_replace(pc, *addr); - *addr = ftrace_modify_code(pc, (unsigned char *)&old, new); - return 0; -} - /* run from kstop_machine */ int __init ftrace_dyn_arch_init(void *data) { diff --git a/arch/ia64/include/asm/iommu.h b/arch/ia64/include/asm/iommu.h index 5fb2bb9..0490794 100644 --- a/arch/ia64/include/asm/iommu.h +++ b/arch/ia64/include/asm/iommu.h @@ -11,6 +11,5 @@ extern int force_iommu, no_iommu; extern int iommu_detected; extern void iommu_dma_init(void); extern void machvec_init(const char *name); -extern int forbid_dac; #endif diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h index 85db124..c60d324 100644 --- a/arch/ia64/include/asm/kvm_host.h +++ b/arch/ia64/include/asm/kvm_host.h @@ -365,7 +365,8 @@ struct kvm_vcpu_arch { long itc_offset; unsigned long itc_check; unsigned long timer_check; - unsigned long timer_pending; + unsigned int timer_pending; + unsigned int timer_fired; unsigned long vrr[8]; unsigned long ibr[8]; @@ -417,6 +418,9 @@ struct kvm_arch { struct list_head assigned_dev_head; struct dmar_domain *intel_iommu_domain; struct hlist_head irq_ack_notifier_list; + + unsigned long irq_sources_bitmap; + unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; }; union cpuid3_t { diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index 10a75b5..031abbf 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -89,13 +89,6 @@ int iommu_dma_supported(struct device *dev, u64 mask) { struct dma_mapping_ops *ops = get_dma_ops(dev); -#ifdef CONFIG_PCI - if (mask > 0xffffffff && forbid_dac > 0) { - dev_info(dev, "Disallowing DAC for device\n"); - return 0; - } -#endif - if (ops->dma_supported_op) return ops->dma_supported_op(dev, mask); diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile index cf37f8f..3ab4d6d 100644 --- a/arch/ia64/kvm/Makefile +++ b/arch/ia64/kvm/Makefile @@ -29,13 +29,18 @@ define cmd_offsets echo ""; \ echo "#endif" ) > $@ endef + # We use internal rules to avoid the "is up to date" message from make -arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c +arch/ia64/kvm/asm-offsets.s: arch/ia64/kvm/asm-offsets.c \ + $(wildcard $(srctree)/arch/ia64/include/asm/*.h)\ + $(wildcard $(srctree)/include/linux/*.h) $(call if_changed_dep,cc_s_c) $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s $(call cmd,offsets) +FORCE : $(obj)/$(offsets-file) + # # Makefile for Kernel-based Virtual Machine module # @@ -53,7 +58,6 @@ endif kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o obj-$(CONFIG_KVM) += kvm.o -FORCE : $(obj)/$(offsets-file) EXTRA_CFLAGS_vcpu.o += -mfixed-range=f2-f5,f12-f127 kvm-intel-objs = vmm.o vmm_ivt.o trampoline.o vcpu.o optvfault.o mmio.o \ vtlb.o process.o diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index a312c9e..3caac47 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -385,6 +385,7 @@ static int handle_global_purge(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) struct kvm *kvm = vcpu->kvm; struct call_data call_data; int i; + call_data.ptc_g_data = p->u.ptc_g_data; for (i = 0; i < KVM_MAX_VCPUS; i++) { @@ -418,33 +419,41 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu) ktime_t kt; long itc_diff; unsigned long vcpu_now_itc; - unsigned long expires; struct hrtimer *p_ht = &vcpu->arch.hlt_timer; unsigned long cyc_per_usec = local_cpu_data->cyc_per_usec; struct vpd *vpd = to_host(vcpu->kvm, vcpu->arch.vpd); - vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset; + if (irqchip_in_kernel(vcpu->kvm)) { - if (time_after(vcpu_now_itc, vpd->itm)) { - vcpu->arch.timer_check = 1; - return 1; - } - itc_diff = vpd->itm - vcpu_now_itc; - if (itc_diff < 0) - itc_diff = -itc_diff; + vcpu_now_itc = ia64_getreg(_IA64_REG_AR_ITC) + vcpu->arch.itc_offset; - expires = div64_u64(itc_diff, cyc_per_usec); - kt = ktime_set(0, 1000 * expires); - vcpu->arch.ht_active = 1; - hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); + if (time_after(vcpu_now_itc, vpd->itm)) { + vcpu->arch.timer_check = 1; + return 1; + } + itc_diff = vpd->itm - vcpu_now_itc; + if (itc_diff < 0) + itc_diff = -itc_diff; + + expires = div64_u64(itc_diff, cyc_per_usec); + kt = ktime_set(0, 1000 * expires); + + down_read(&vcpu->kvm->slots_lock); + vcpu->arch.ht_active = 1; + hrtimer_start(p_ht, kt, HRTIMER_MODE_ABS); - if (irqchip_in_kernel(vcpu->kvm)) { vcpu->arch.mp_state = KVM_MP_STATE_HALTED; kvm_vcpu_block(vcpu); hrtimer_cancel(p_ht); vcpu->arch.ht_active = 0; + if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests)) + if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) + vcpu->arch.mp_state = + KVM_MP_STATE_RUNNABLE; + up_read(&vcpu->kvm->slots_lock); + if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE) return -EINTR; return 1; @@ -484,10 +493,6 @@ static int (*kvm_vti_exit_handlers[])(struct kvm_vcpu *vcpu, static const int kvm_vti_max_exit_handlers = sizeof(kvm_vti_exit_handlers)/sizeof(*kvm_vti_exit_handlers); -static void kvm_prepare_guest_switch(struct kvm_vcpu *vcpu) -{ -} - static uint32_t kvm_get_exit_reason(struct kvm_vcpu *vcpu) { struct exit_ctl_data *p_exit_data; @@ -600,8 +605,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) again: preempt_disable(); - - kvm_prepare_guest_switch(vcpu); local_irq_disable(); if (signal_pending(current)) { @@ -614,7 +617,7 @@ again: vcpu->guest_mode = 1; kvm_guest_enter(); - + down_read(&vcpu->kvm->slots_lock); r = vti_vcpu_run(vcpu, kvm_run); if (r < 0) { local_irq_enable(); @@ -634,9 +637,8 @@ again: * But we need to prevent reordering, hence this barrier(): */ barrier(); - kvm_guest_exit(); - + up_read(&vcpu->kvm->slots_lock); preempt_enable(); r = kvm_handle_exit(kvm_run, vcpu); @@ -673,6 +675,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) { kvm_vcpu_block(vcpu); + clear_bit(KVM_REQ_UNHALT, &vcpu->requests); vcpu_put(vcpu); return -EAGAIN; } @@ -778,6 +781,9 @@ static void kvm_init_vm(struct kvm *kvm) kvm_build_io_pmt(kvm); INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); + + /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ + set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); } struct kvm *kvm_arch_create_vm(void) @@ -941,9 +947,8 @@ long kvm_arch_vm_ioctl(struct file *filp, goto out; if (irqchip_in_kernel(kvm)) { mutex_lock(&kvm->lock); - kvm_ioapic_set_irq(kvm->arch.vioapic, - irq_event.irq, - irq_event.level); + kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, + irq_event.irq, irq_event.level); mutex_unlock(&kvm->lock); r = 0; } @@ -1123,15 +1128,16 @@ static enum hrtimer_restart hlt_timer_fn(struct hrtimer *data) wait_queue_head_t *q; vcpu = container_of(data, struct kvm_vcpu, arch.hlt_timer); + q = &vcpu->wq; + if (vcpu->arch.mp_state != KVM_MP_STATE_HALTED) goto out; - q = &vcpu->wq; - if (waitqueue_active(q)) { - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + if (waitqueue_active(q)) wake_up_interruptible(q); - } + out: + vcpu->arch.timer_fired = 1; vcpu->arch.timer_check = 1; return HRTIMER_NORESTART; } @@ -1700,12 +1706,14 @@ static void vcpu_kick_intr(void *info) void kvm_vcpu_kick(struct kvm_vcpu *vcpu) { int ipi_pcpu = vcpu->cpu; + int cpu = get_cpu(); if (waitqueue_active(&vcpu->wq)) wake_up_interruptible(&vcpu->wq); - if (vcpu->guest_mode) + if (vcpu->guest_mode && cpu != ipi_pcpu) smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0); + put_cpu(); } int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) @@ -1715,13 +1723,7 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, u8 vec, u8 trig) if (!test_and_set_bit(vec, &vpd->irr[0])) { vcpu->arch.irq_new_pending = 1; - if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE) - kvm_vcpu_kick(vcpu); - else if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) { - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; - if (waitqueue_active(&vcpu->wq)) - wake_up_interruptible(&vcpu->wq); - } + kvm_vcpu_kick(vcpu); return 1; } return 0; @@ -1791,7 +1793,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu) int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) { - return 0; + return vcpu->arch.timer_fired; } gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) diff --git a/arch/ia64/kvm/kvm_fw.c b/arch/ia64/kvm/kvm_fw.c index 0c69d9e..cb7600b 100644 --- a/arch/ia64/kvm/kvm_fw.c +++ b/arch/ia64/kvm/kvm_fw.c @@ -286,6 +286,12 @@ static u64 kvm_get_pal_call_index(struct kvm_vcpu *vcpu) return index; } +static void prepare_for_halt(struct kvm_vcpu *vcpu) +{ + vcpu->arch.timer_pending = 1; + vcpu->arch.timer_fired = 0; +} + int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run) { @@ -304,11 +310,10 @@ int kvm_pal_emul(struct kvm_vcpu *vcpu, struct kvm_run *run) break; case PAL_HALT_LIGHT: { - vcpu->arch.timer_pending = 1; INIT_PAL_STATUS_SUCCESS(result); + prepare_for_halt(vcpu); if (kvm_highest_pending_irq(vcpu) == -1) ret = kvm_emulate_halt(vcpu); - } break; diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c index 3417783..8008173 100644 --- a/arch/ia64/kvm/process.c +++ b/arch/ia64/kvm/process.c @@ -713,7 +713,7 @@ void leave_hypervisor_tail(void) if (!(VCPU(v, itv) & (1 << 16))) { vcpu_pend_interrupt(v, VCPU(v, itv) & 0xff); - VMX(v, itc_check) = 0; + VMX(v, itc_check) = 0; } else { v->arch.timer_pending = 1; } diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 5f149b0..653574b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -238,21 +238,8 @@ config MIPS_SIM This option enables support for MIPS Technologies MIPSsim software emulator. -config MARKEINS - bool "NEC EMMA2RH Mark-eins" - select CEVT_R4K - select CSRC_R4K - select DMA_NONCOHERENT - select HW_HAS_PCI - select IRQ_CPU - select SWAP_IO_SPACE - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_HAS_CPU_R5000 - help - This enables support for the R5432-based NEC Mark-eins - boards with R5500 CPU. +config MACH_EMMA + bool "NEC EMMA series based machines" config MACH_VR41XX bool "NEC VR4100 series based machines" @@ -261,6 +248,19 @@ config MACH_VR41XX select SYS_HAS_CPU_VR41XX select GENERIC_HARDIRQS_NO__DO_IRQ +config NXP_STB220 + bool "NXP STB220 board" + select SOC_PNX833X + help + Support for NXP Semiconductors STB220 Development Board. + +config NXP_STB225 + bool "NXP 225 board" + select SOC_PNX833X + select SOC_PNX8335 + help + Support for NXP Semiconductors STB225 Development Board. + config PNX8550_JBS bool "NXP PNX8550 based JBS board" select PNX8550 @@ -601,6 +601,7 @@ endchoice source "arch/mips/alchemy/Kconfig" source "arch/mips/basler/excite/Kconfig" +source "arch/mips/emma/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/lasat/Kconfig" source "arch/mips/pmc-sierra/Kconfig" @@ -849,6 +850,24 @@ config MIPS_RM9122 bool select SERIAL_RM9000 +config SOC_PNX833X + bool + select CEVT_R4K + select CSRC_R4K + select IRQ_CPU + select DMA_NONCOHERENT + select SYS_HAS_CPU_MIPS32_R2 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_BIG_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ + select GENERIC_GPIO + select CPU_MIPSR2_IRQ_VI + +config SOC_PNX8335 + bool + select SOC_PNX833X + config PNX8550 bool select SOC_PNX8550 @@ -1092,6 +1111,16 @@ config CPU_R5432 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL +config CPU_R5500 + bool "R5500" + depends on SYS_HAS_CPU_R5500 + select CPU_HAS_LLSC + select CPU_SUPPORTS_32BIT_KERNEL + select CPU_SUPPORTS_64BIT_KERNEL + help + NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV + instruction set. + config CPU_R6000 bool "R6000" depends on EXPERIMENTAL @@ -1202,6 +1231,9 @@ config SYS_HAS_CPU_R5000 config SYS_HAS_CPU_R5432 bool +config SYS_HAS_CPU_R5500 + bool + config SYS_HAS_CPU_R6000 bool diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 7f39fd8..28c55f6 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -131,6 +131,8 @@ cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_ cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ -Wa,--trap +cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \ + -Wa,--trap cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ -Wa,--trap cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ @@ -381,6 +383,14 @@ load-$(CONFIG_CASIO_E55) += 0xffffffff80004000 # load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000 +# NXP STB225 +core-$(CONFIG_SOC_PNX833X) += arch/mips/nxp/pnx833x/common/ +cflags-$(CONFIG_SOC_PNX833X) += -Iarch/mips/include/asm/mach-pnx833x +libs-$(CONFIG_NXP_STB220) += arch/mips/nxp/pnx833x/stb22x/ +load-$(CONFIG_NXP_STB220) += 0xffffffff80001000 +libs-$(CONFIG_NXP_STB225) += arch/mips/nxp/pnx833x/stb22x/ +load-$(CONFIG_NXP_STB225) += 0xffffffff80001000 + # # Common NXP PNX8550 # @@ -399,14 +409,17 @@ load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000 libs-$(CONFIG_PNX8550_STB810) += arch/mips/nxp/pnx8550/stb810/ load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000 -# NEC EMMA2RH boards # -core-$(CONFIG_EMMA2RH) += arch/mips/emma2rh/common/ -cflags-$(CONFIG_EMMA2RH) += -I$(srctree)/arch/mips/include/asm/mach-emma2rh +# Common NEC EMMAXXX +# +core-$(CONFIG_SOC_EMMA) += arch/mips/emma/common/ +cflags-$(CONFIG_SOC_EMMA2RH) += -I$(srctree)/arch/mips/include/asm/mach-emma2rh +# # NEC EMMA2RH Mark-eins -core-$(CONFIG_MARKEINS) += arch/mips/emma2rh/markeins/ -load-$(CONFIG_MARKEINS) += 0xffffffff88100000 +# +core-$(CONFIG_NEC_MARKEINS) += arch/mips/emma/markeins/ +load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000 # # SGI IP22 (Indy/Indigo2) diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index dc8a67e..5c76c64 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -17,6 +17,8 @@ #include <linux/init.h> #include <asm/mach-au1x00/au1xxx.h> +#include <asm/mach-au1x00/au1xxx_dbdma.h> +#include <asm/mach-au1x00/au1100_mmc.h> #define PORT(_base, _irq) \ { \ @@ -163,24 +165,6 @@ static struct resource au1xxx_usb_gdt_resources[] = { }, }; -static struct resource au1xxx_mmc_resources[] = { - [0] = { - .start = SD0_PHYS_ADDR, - .end = SD0_PHYS_ADDR + 0x7ffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SD1_PHYS_ADDR, - .end = SD1_PHYS_ADDR + 0x7ffff, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = AU1200_SD_INT, - .end = AU1200_SD_INT, - .flags = IORESOURCE_IRQ, - } -}; - static u64 udc_dmamask = DMA_32BIT_MASK; static struct platform_device au1xxx_usb_gdt_device = { @@ -249,16 +233,79 @@ static struct platform_device au1200_lcd_device = { static u64 au1xxx_mmc_dmamask = DMA_32BIT_MASK; -static struct platform_device au1xxx_mmc_device = { +extern struct au1xmmc_platform_data au1xmmc_platdata[2]; + +static struct resource au1200_mmc0_resources[] = { + [0] = { + .start = SD0_PHYS_ADDR, + .end = SD0_PHYS_ADDR + 0x7ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AU1200_SD_INT, + .end = AU1200_SD_INT, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = DSCR_CMD0_SDMS_TX0, + .end = DSCR_CMD0_SDMS_TX0, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DSCR_CMD0_SDMS_RX0, + .end = DSCR_CMD0_SDMS_RX0, + .flags = IORESOURCE_DMA, + } +}; + +static struct platform_device au1200_mmc0_device = { .name = "au1xxx-mmc", .id = 0, .dev = { - .dma_mask = &au1xxx_mmc_dmamask, - .coherent_dma_mask = DMA_32BIT_MASK, + .dma_mask = &au1xxx_mmc_dmamask, + .coherent_dma_mask = DMA_32BIT_MASK, + .platform_data = &au1xmmc_platdata[0], }, - .num_resources = ARRAY_SIZE(au1xxx_mmc_resources), - .resource = au1xxx_mmc_resources, + .num_resources = ARRAY_SIZE(au1200_mmc0_resources), + .resource = au1200_mmc0_resources, }; + +#ifndef CONFIG_MIPS_DB1200 +static struct resource au1200_mmc1_resources[] = { + [0] = { + .start = SD1_PHYS_ADDR, + .end = SD1_PHYS_ADDR + 0x7ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AU1200_SD_INT, + .end = AU1200_SD_INT, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = DSCR_CMD0_SDMS_TX1, + .end = DSCR_CMD0_SDMS_TX1, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DSCR_CMD0_SDMS_RX1, + .end = DSCR_CMD0_SDMS_RX1, + .flags = IORESOURCE_DMA, + } +}; + +static struct platform_device au1200_mmc1_device = { + .name = "au1xxx-mmc", + .id = 1, + .dev = { + .dma_mask = &au1xxx_mmc_dmamask, + .coherent_dma_mask = DMA_32BIT_MASK, + .platform_data = &au1xmmc_platdata[1], + }, + .num_resources = ARRAY_SIZE(au1200_mmc1_resources), + .resource = au1200_mmc1_resources, +}; +#endif /* #ifndef CONFIG_MIPS_DB1200 */ #endif /* #ifdef CONFIG_SOC_AU1200 */ static struct platform_device au1x00_pcmcia_device = { @@ -296,7 +343,10 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { &au1xxx_usb_gdt_device, &au1xxx_usb_otg_device, &au1200_lcd_device, - &au1xxx_mmc_device, + &au1200_mmc0_device, +#ifndef CONFIG_MIPS_DB1200 + &au1200_mmc1_device, +#endif #endif #ifdef SMBUS_PSC_BASE &pbdb_smbus_device, diff --git a/arch/mips/alchemy/pb1200/platform.c b/arch/mips/alchemy/pb1200/platform.c index f8fb0ae..9530329 100644 --- a/arch/mips/alchemy/pb1200/platform.c +++ b/arch/mips/alchemy/pb1200/platform.c @@ -20,9 +20,90 @@ #include <linux/dma-mapping.h> #include <linux/init.h> +#include <linux/leds.h> #include <linux/platform_device.h> #include <asm/mach-au1x00/au1xxx.h> +#include <asm/mach-au1x00/au1100_mmc.h> + +static int mmc_activity; + +static void pb1200mmc0_set_power(void *mmc_host, int state) +{ + if (state) + bcsr->board |= BCSR_BOARD_SD0PWR; + else + bcsr->board &= ~BCSR_BOARD_SD0PWR; + + au_sync_delay(1); +} + +static int pb1200mmc0_card_readonly(void *mmc_host) +{ + return (bcsr->status & BCSR_STATUS_SD0WP) ? 1 : 0; +} + +static int pb1200mmc0_card_inserted(void *mmc_host) +{ + return (bcsr->sig_status & BCSR_INT_SD0INSERT) ? 1 : 0; +} + +static void pb1200_mmcled_set(struct led_classdev *led, + enum led_brightness brightness) +{ + if (brightness != LED_OFF) { + if (++mmc_activity == 1) + bcsr->disk_leds &= ~(1 << 8); + } else { + if (--mmc_activity == 0) + bcsr->disk_leds |= (1 << 8); + } +} + +static struct led_classdev pb1200mmc_led = { + .brightness_set = pb1200_mmcled_set, +}; + +#ifndef CONFIG_MIPS_DB1200 +static void pb1200mmc1_set_power(void *mmc_host, int state) +{ + if (state) + bcsr->board |= BCSR_BOARD_SD1PWR; + else + bcsr->board &= ~BCSR_BOARD_SD1PWR; + + au_sync_delay(1); +} + +static int pb1200mmc1_card_readonly(void *mmc_host) +{ + return (bcsr->status & BCSR_STATUS_SD1WP) ? 1 : 0; +} + +static int pb1200mmc1_card_inserted(void *mmc_host) +{ + return (bcsr->sig_status & BCSR_INT_SD1INSERT) ? 1 : 0; +} +#endif + +const struct au1xmmc_platform_data au1xmmc_platdata[2] = { + [0] = { + .set_power = pb1200mmc0_set_power, + .card_inserted = pb1200mmc0_card_inserted, + .card_readonly = pb1200mmc0_card_readonly, + .cd_setup = NULL, /* use poll-timer in driver */ + .led = &pb1200mmc_led, + }, +#ifndef CONFIG_MIPS_DB1200 + [1] = { + .set_power = pb1200mmc1_set_power, + .card_inserted = pb1200mmc1_card_inserted, + .card_readonly = pb1200mmc1_card_readonly, + .cd_setup = NULL, /* use poll-timer in driver */ + .led = &pb1200mmc_led, + }, +#endif +}; static struct resource ide_resources[] = { [0] = { diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335-stb225_defconfig new file mode 100644 index 0000000..d953652 --- /dev/null +++ b/arch/mips/configs/pnx8335-stb225_defconfig @@ -0,0 +1,1149 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26 +# Sat Jul 26 09:02:59 2008 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MACH_ALCHEMY is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_BCM47XX is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_LEMOTE_FULONG is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MARKEINS is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_NXP_STB220 is not set +CONFIG_NXP_STB225=y +# CONFIG_PNX8550_JBS is not set +# CONFIG_PNX8550_STB810 is not set +# CONFIG_PMC_MSP is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP28 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SNI_RM is not set +# CONFIG_MACH_TX39XX is not set +# CONFIG_MACH_TX49XX is not set +# CONFIG_WR_PPMC is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_SUPPORTS_OPROFILE=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_CEVT_R4K=y +CONFIG_CSRC_R4K=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_HOTPLUG_CPU is not set +# CONFIG_NO_IOPORT is not set +CONFIG_GENERIC_GPIO=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_SOC_PNX833X=y +CONFIG_SOC_PNX8335=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_LOONGSON2 is not set +# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R2=y +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R2=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR2=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_MIPSR2_IRQ_VI=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=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=0 +CONFIG_VIRT_TO_BUS=y +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_128=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=128 +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set +# CONFIG_KEXEC is not set +# CONFIG_SECCOMP is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=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 is not set +# 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=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 is not set +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_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_PCSPKR_PLATFORM=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 is not set +# CONFIG_HAVE_KRETPROBES is not set +# CONFIG_HAVE_DMA_ATTRS is not set +# CONFIG_USE_GENERIC_SMP_HELPERS 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_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 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 + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_MMU=y +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Power management options +# +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y + +# +# 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=y +# 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 is not set +CONFIG_INET_AH=y +# 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=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# 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_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=y +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 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=y +CONFIG_MTD_PHYSMAP_START=0x18000000 +CONFIG_MTD_PHYSMAP_LEN=0x04000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# 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_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_RAM 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 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 is not set +# CONFIG_SCSI_DH is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_SATA_PMP=y +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +# CONFIG_PATA_PLATFORM 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_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_AX88796 is not set +# CONFIG_DM9000 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 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=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=m +CONFIG_INPUT_EVBUG=m + +# +# 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 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +# CONFIG_VT_CONSOLE is not set +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_PNX8XXX=y +CONFIG_SERIAL_PNX8XXX_CONSOLE=y +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_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 + +# +# 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_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_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 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 + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +CONFIG_DVB_CORE=y +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_SIMPLE=y +CONFIG_MEDIA_TUNER_TDA8290=y +CONFIG_MEDIA_TUNER_TDA9887=y +CONFIG_MEDIA_TUNER_TEA5761=y +CONFIG_MEDIA_TUNER_TEA5767=y +CONFIG_MEDIA_TUNER_MT20XX=y +CONFIG_MEDIA_TUNER_XC2028=y +CONFIG_MEDIA_TUNER_XC5000=y +CONFIG_DVB_CAPTURE_DRIVERS=y +# CONFIG_TTPCI_EEPROM is not set +# 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 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=y +# 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 is not set + +# +# Graphics support +# +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_CFB_FILLRECT is not set +# CONFIG_FB_CFB_COPYAREA is not set +# CONFIG_FB_CFB_IMAGEBLIT is not set +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL 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_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=m +CONFIG_SND=m +CONFIG_SND_TIMER=m +CONFIG_SND_PCM=m +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQ_DUMMY 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_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_MIPS=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=y +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# +# 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 is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +# 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 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_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +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 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_ROOT_NFS=y +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +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=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# 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=m +# 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=m +CONFIG_NLS_ISO8859_1=m +# 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=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m +# CONFIG_DLM is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# 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 is not set +# CONFIG_SAMPLES is not set +# CONFIG_KERNEL_TESTS is not set +CONFIG_CMDLINE="" + +# +# 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_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 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=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=y +# 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 + +# +# Random Number Generation +# +# CONFIG_CRYPTO_PRNG is not set +CONFIG_CRYPTO_HW=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_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_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/arch/mips/emma/Kconfig b/arch/mips/emma/Kconfig new file mode 100644 index 0000000..9669c72 --- /dev/null +++ b/arch/mips/emma/Kconfig @@ -0,0 +1,29 @@ +choice + prompt "Machine type" + depends on MACH_EMMA + default NEC_MARKEINS + +config NEC_MARKEINS + bool "NEC EMMA2RH Mark-eins board" + select SOC_EMMA2RH + select HW_HAS_PCI + help + This enables support for the NEC Electronics Mark-eins boards. + +endchoice + +config SOC_EMMA2RH + bool + select SOC_EMMA + select SYS_HAS_CPU_R5500 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + +config SOC_EMMA + bool + select CEVT_R4K + select CSRC_R4K + select DMA_NONCOHERENT + select IRQ_CPU + select SWAP_IO_SPACE + select SYS_SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/emma2rh/common/Makefile b/arch/mips/emma/common/Makefile index 859121b..c392d28 100644 --- a/arch/mips/emma2rh/common/Makefile +++ b/arch/mips/emma/common/Makefile @@ -10,4 +10,4 @@ # (at your option) any later version. # -obj-$(CONFIG_MARKEINS) += irq.o irq_emma2rh.o prom.o +obj-$(CONFIG_NEC_MARKEINS) += prom.o diff --git a/arch/mips/emma2rh/common/prom.c b/arch/mips/emma/common/prom.c index e14a2e3..120f53f 100644 --- a/arch/mips/emma2rh/common/prom.c +++ b/arch/mips/emma/common/prom.c @@ -29,11 +29,11 @@ #include <asm/addrspace.h> #include <asm/bootinfo.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> const char *get_system_type(void) { -#if defined(CONFIG_MARKEINS) +#ifdef CONFIG_NEC_MARKEINS return "NEC EMMA2RH Mark-eins"; #else #error Unknown NEC board @@ -60,7 +60,7 @@ void __init prom_init(void) strcat(arcs_cmdline, " "); } -#if defined(CONFIG_MARKEINS) +#ifdef CONFIG_NEC_MARKEINS add_memory_region(0, EMMA2RH_RAM_SIZE, BOOT_MEM_RAM); #else #error Unknown NEC board diff --git a/arch/mips/emma2rh/markeins/Makefile b/arch/mips/emma/markeins/Makefile index 14fc268..16e0017 100644 --- a/arch/mips/emma2rh/markeins/Makefile +++ b/arch/mips/emma/markeins/Makefile @@ -10,4 +10,4 @@ # (at your option) any later version. # -obj-$(CONFIG_MARKEINS) += irq.o irq_markeins.o setup.o led.o platform.o +obj-$(CONFIG_NEC_MARKEINS) += irq.o setup.o led.o platform.o diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c new file mode 100644 index 0000000..c2583ec --- /dev/null +++ b/arch/mips/emma/markeins/irq.c @@ -0,0 +1,331 @@ +/* + * arch/mips/emma2rh/markeins/irq.c + * This file defines the irq handler for EMMA2RH. + * + * Copyright (C) NEC Electronics Corporation 2004-2006 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c + * + * Copyright 2001 MontaVista Software 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 program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/types.h> +#include <linux/ptrace.h> +#include <linux/delay.h> + +#include <asm/irq_cpu.h> +#include <asm/system.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/bootinfo.h> + +#include <asm/emma/emma2rh.h> + +static void emma2rh_irq_enable(unsigned int irq) +{ + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + irq -= EMMA2RH_IRQ_BASE; + + reg_index = EMMA2RH_BHIF_INT_EN_0 + + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); + reg_value = emma2rh_in32(reg_index); + reg_bitmask = 0x1 << (irq % 32); + emma2rh_out32(reg_index, reg_value | reg_bitmask); +} + +static void emma2rh_irq_disable(unsigned int irq) +{ + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + irq -= EMMA2RH_IRQ_BASE; + + reg_index = EMMA2RH_BHIF_INT_EN_0 + + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) * (irq / 32); + reg_value = emma2rh_in32(reg_index); + reg_bitmask = 0x1 << (irq % 32); + emma2rh_out32(reg_index, reg_value & ~reg_bitmask); +} + +struct irq_chip emma2rh_irq_controller = { + .name = "emma2rh_irq", + .ack = emma2rh_irq_disable, + .mask = emma2rh_irq_disable, + .mask_ack = emma2rh_irq_disable, + .unmask = emma2rh_irq_enable, +}; + +void emma2rh_irq_init(void) +{ + u32 i; + + for (i = 0; i < NUM_EMMA2RH_IRQ; i++) + set_irq_chip_and_handler(EMMA2RH_IRQ_BASE + i, + &emma2rh_irq_controller, + handle_level_irq); +} + +static void emma2rh_sw_irq_enable(unsigned int irq) +{ + u32 reg; + + irq -= EMMA2RH_SW_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); +} + +static void emma2rh_sw_irq_disable(unsigned int irq) +{ + u32 reg; + + irq -= EMMA2RH_SW_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); + reg &= ~(1 << irq); + emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); +} + +struct irq_chip emma2rh_sw_irq_controller = { + .name = "emma2rh_sw_irq", + .ack = emma2rh_sw_irq_disable, + .mask = emma2rh_sw_irq_disable, + .mask_ack = emma2rh_sw_irq_disable, + .unmask = emma2rh_sw_irq_enable, +}; + +void emma2rh_sw_irq_init(void) +{ + u32 i; + + for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++) + set_irq_chip_and_handler(EMMA2RH_SW_IRQ_BASE + i, + &emma2rh_sw_irq_controller, + handle_level_irq); +} + +static void emma2rh_gpio_irq_enable(unsigned int irq) +{ + u32 reg; + + irq -= EMMA2RH_GPIO_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); +} + +static void emma2rh_gpio_irq_disable(unsigned int irq) +{ + u32 reg; + + irq -= EMMA2RH_GPIO_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + reg &= ~(1 << irq); + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); +} + +static void emma2rh_gpio_irq_ack(unsigned int irq) +{ + u32 reg; + + irq -= EMMA2RH_GPIO_IRQ_BASE; + emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); + + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + reg &= ~(1 << irq); + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); +} + +static void emma2rh_gpio_irq_end(unsigned int irq) +{ + u32 reg; + + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + + irq -= EMMA2RH_GPIO_IRQ_BASE; + + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); + } +} + +struct irq_chip emma2rh_gpio_irq_controller = { + .name = "emma2rh_gpio_irq", + .ack = emma2rh_gpio_irq_ack, + .mask = emma2rh_gpio_irq_disable, + .mask_ack = emma2rh_gpio_irq_ack, + .unmask = emma2rh_gpio_irq_enable, + .end = emma2rh_gpio_irq_end, +}; + +void emma2rh_gpio_irq_init(void) +{ + u32 i; + + for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++) + set_irq_chip(EMMA2RH_GPIO_IRQ_BASE + i, + &emma2rh_gpio_irq_controller); +} + +static struct irqaction irq_cascade = { + .handler = no_action, + .flags = 0, + .mask = CPU_MASK_NONE, + .name = "cascade", + .dev_id = NULL, + .next = NULL, +}; + +/* + * the first level int-handler will jump here if it is a emma2rh irq + */ +void emma2rh_irq_dispatch(void) +{ + u32 intStatus; + u32 bitmask; + u32 i; + + intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_0) & + emma2rh_in32(EMMA2RH_BHIF_INT_EN_0); + +#ifdef EMMA2RH_SW_CASCADE + if (intStatus & + (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { + u32 swIntStatus; + swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT) + & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); + for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { + if (swIntStatus & bitmask) { + do_IRQ(EMMA2RH_SW_IRQ_BASE + i); + return; + } + } + } +#endif + + for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { + if (intStatus & bitmask) { + do_IRQ(EMMA2RH_IRQ_BASE + i); + return; + } + } + + intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_1) & + emma2rh_in32(EMMA2RH_BHIF_INT_EN_1); + +#ifdef EMMA2RH_GPIO_CASCADE + if (intStatus & + (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { + u32 gpioIntStatus; + gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST) + & emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { + if (gpioIntStatus & bitmask) { + do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i); + return; + } + } + } +#endif + + for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { + if (intStatus & bitmask) { + do_IRQ(EMMA2RH_IRQ_BASE + i); + return; + } + } + + intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_2) & + emma2rh_in32(EMMA2RH_BHIF_INT_EN_2); + + for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) { + if (intStatus & bitmask) { + do_IRQ(EMMA2RH_IRQ_BASE + i); + return; + } + } +} + +void __init arch_init_irq(void) +{ + u32 reg; + + /* by default, interrupts are disabled. */ + emma2rh_out32(EMMA2RH_BHIF_INT_EN_0, 0); + emma2rh_out32(EMMA2RH_BHIF_INT_EN_1, 0); + emma2rh_out32(EMMA2RH_BHIF_INT_EN_2, 0); + emma2rh_out32(EMMA2RH_BHIF_INT1_EN_0, 0); + emma2rh_out32(EMMA2RH_BHIF_INT1_EN_1, 0); + emma2rh_out32(EMMA2RH_BHIF_INT1_EN_2, 0); + emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, 0); + + clear_c0_status(0xff00); + set_c0_status(0x0400); + +#define GPIO_PCI (0xf<<15) + /* setup GPIO interrupt for PCI interface */ + /* direction input */ + reg = emma2rh_in32(EMMA2RH_GPIO_DIR); + emma2rh_out32(EMMA2RH_GPIO_DIR, reg & ~GPIO_PCI); + /* disable interrupt */ + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); + emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg & ~GPIO_PCI); + /* level triggerd */ + reg = emma2rh_in32(EMMA2RH_GPIO_INT_MODE); + emma2rh_out32(EMMA2RH_GPIO_INT_MODE, reg | GPIO_PCI); + reg = emma2rh_in32(EMMA2RH_GPIO_INT_CND_A); + emma2rh_out32(EMMA2RH_GPIO_INT_CND_A, reg & (~GPIO_PCI)); + /* interrupt clear */ + emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~GPIO_PCI); + + /* init all controllers */ + emma2rh_irq_init(); + emma2rh_sw_irq_init(); + emma2rh_gpio_irq_init(); + mips_cpu_irq_init(); + + /* setup cascade interrupts */ + setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade); + setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade); + setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade); +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; + + if (pending & STATUSF_IP7) + do_IRQ(CPU_IRQ_BASE + 7); + else if (pending & STATUSF_IP2) + emma2rh_irq_dispatch(); + else if (pending & STATUSF_IP1) + do_IRQ(CPU_IRQ_BASE + 1); + else if (pending & STATUSF_IP0) + do_IRQ(CPU_IRQ_BASE + 0); + else + spurious_interrupt(); +} diff --git a/arch/mips/emma2rh/markeins/led.c b/arch/mips/emma/markeins/led.c index b65254c..377a181 100644 --- a/arch/mips/emma2rh/markeins/led.c +++ b/arch/mips/emma/markeins/led.c @@ -21,7 +21,7 @@ #include <linux/kernel.h> #include <linux/types.h> #include <linux/string.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> const unsigned long clear = 0x20202020; diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma/markeins/platform.c index fb9cda2..88e87f6 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma/markeins/platform.c @@ -36,7 +36,7 @@ #include <asm/reboot.h> #include <asm/traps.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */ diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma/markeins/setup.c index b6a23ad..67f4565 100644 --- a/arch/mips/emma2rh/markeins/setup.c +++ b/arch/mips/emma/markeins/setup.c @@ -29,7 +29,7 @@ #include <asm/time.h> #include <asm/reboot.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ diff --git a/arch/mips/emma2rh/common/irq.c b/arch/mips/emma2rh/common/irq.c deleted file mode 100644 index 91cbd95..0000000 --- a/arch/mips/emma2rh/common/irq.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * arch/mips/emma2rh/common/irq.c - * This file is common irq dispatcher. - * - * Copyright (C) NEC Electronics Corporation 2005-2006 - * - * This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c - * - * Copyright 2001 MontaVista Software 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/types.h> - -#include <asm/system.h> -#include <asm/mipsregs.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> - -#include <asm/emma2rh/emma2rh.h> - -/* - * the first level int-handler will jump here if it is a emma2rh irq - */ -void emma2rh_irq_dispatch(void) -{ - u32 intStatus; - u32 bitmask; - u32 i; - - intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_0) - & emma2rh_in32(EMMA2RH_BHIF_INT_EN_0); - -#ifdef EMMA2RH_SW_CASCADE - if (intStatus & - (1 << ((EMMA2RH_SW_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { - u32 swIntStatus; - swIntStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT) - & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); - for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { - if (swIntStatus & bitmask) { - do_IRQ(EMMA2RH_SW_IRQ_BASE + i); - return; - } - } - } -#endif - - for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { - if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); - return; - } - } - - intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_1) - & emma2rh_in32(EMMA2RH_BHIF_INT_EN_1); - -#ifdef EMMA2RH_GPIO_CASCADE - if (intStatus & - (1 << ((EMMA2RH_GPIO_CASCADE - EMMA2RH_IRQ_INT0) & (32 - 1)))) { - u32 gpioIntStatus; - gpioIntStatus = emma2rh_in32(EMMA2RH_GPIO_INT_ST) - & emma2rh_in32(EMMA2RH_GPIO_INT_MASK); - for (i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { - if (gpioIntStatus & bitmask) { - do_IRQ(EMMA2RH_GPIO_IRQ_BASE + i); - return; - } - } - } -#endif - - for (i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { - if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); - return; - } - } - - intStatus = emma2rh_in32(EMMA2RH_BHIF_INT_ST_2) - & emma2rh_in32(EMMA2RH_BHIF_INT_EN_2); - - for (i = 64, bitmask = 1; i < 96; i++, bitmask <<= 1) { - if (intStatus & bitmask) { - do_IRQ(EMMA2RH_IRQ_BASE + i); - return; - } - } -} diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c deleted file mode 100644 index 96df37b..0000000 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * arch/mips/emma2rh/common/irq_emma2rh.c - * This file defines the irq handler for EMMA2RH. - * - * Copyright (C) NEC Electronics Corporation 2005-2006 - * - * This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c - * - * Copyright 2001 MontaVista Software 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 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 - */ - -/* - * EMMA2RH defines 64 IRQs. - * - * This file exports one function: - * emma2rh_irq_init(u32 irq_base); - */ - -#include <linux/interrupt.h> -#include <linux/types.h> -#include <linux/ptrace.h> - -#include <asm/debug.h> - -#include <asm/emma2rh/emma2rh.h> - -/* number of total irqs supported by EMMA2RH */ -#define NUM_EMMA2RH_IRQ 96 - -static int emma2rh_irq_base = -1; - -void ll_emma2rh_irq_enable(int); -void ll_emma2rh_irq_disable(int); - -static void emma2rh_irq_enable(unsigned int irq) -{ - ll_emma2rh_irq_enable(irq - emma2rh_irq_base); -} - -static void emma2rh_irq_disable(unsigned int irq) -{ - ll_emma2rh_irq_disable(irq - emma2rh_irq_base); -} - -struct irq_chip emma2rh_irq_controller = { - .name = "emma2rh_irq", - .ack = emma2rh_irq_disable, - .mask = emma2rh_irq_disable, - .mask_ack = emma2rh_irq_disable, - .unmask = emma2rh_irq_enable, -}; - -void emma2rh_irq_init(u32 irq_base) -{ - u32 i; - - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) - set_irq_chip_and_handler(i, &emma2rh_irq_controller, - handle_level_irq); - - emma2rh_irq_base = irq_base; -} - -void ll_emma2rh_irq_enable(int emma2rh_irq) -{ - u32 reg_value; - u32 reg_bitmask; - u32 reg_index; - - reg_index = EMMA2RH_BHIF_INT_EN_0 - + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) - * (emma2rh_irq / 32); - reg_value = emma2rh_in32(reg_index); - reg_bitmask = 0x1 << (emma2rh_irq % 32); - db_assert((reg_value & reg_bitmask) == 0); - emma2rh_out32(reg_index, reg_value | reg_bitmask); -} - -void ll_emma2rh_irq_disable(int emma2rh_irq) -{ - u32 reg_value; - u32 reg_bitmask; - u32 reg_index; - - reg_index = EMMA2RH_BHIF_INT_EN_0 - + (EMMA2RH_BHIF_INT_EN_1 - EMMA2RH_BHIF_INT_EN_0) - * (emma2rh_irq / 32); - reg_value = emma2rh_in32(reg_index); - reg_bitmask = 0x1 << (emma2rh_irq % 32); - db_assert((reg_value & reg_bitmask) != 0); - emma2rh_out32(reg_index, reg_value & ~reg_bitmask); -} diff --git a/arch/mips/emma2rh/markeins/irq.c b/arch/mips/emma2rh/markeins/irq.c deleted file mode 100644 index 6bcf6a0..0000000 --- a/arch/mips/emma2rh/markeins/irq.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * arch/mips/emma2rh/markeins/irq.c - * This file defines the irq handler for EMMA2RH. - * - * Copyright (C) NEC Electronics Corporation 2004-2006 - * - * This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c - * - * Copyright 2001 MontaVista Software 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/types.h> -#include <linux/ptrace.h> -#include <linux/delay.h> - -#include <asm/irq_cpu.h> -#include <asm/system.h> -#include <asm/mipsregs.h> -#include <asm/debug.h> -#include <asm/addrspace.h> -#include <asm/bootinfo.h> - -#include <asm/emma2rh/emma2rh.h> - -/* - * IRQ mapping - * - * 0-7: 8 CPU interrupts - * 0 - software interrupt 0 - * 1 - software interrupt 1 - * 2 - most Vrc5477 interrupts are routed to this pin - * 3 - (optional) some other interrupts routed to this pin for debugg - * 4 - not used - * 5 - not used - * 6 - not used - * 7 - cpu timer (used by default) - * - */ - -extern void emma2rh_sw_irq_init(u32 base); -extern void emma2rh_gpio_irq_init(u32 base); -extern void emma2rh_irq_init(u32 base); -extern void emma2rh_irq_dispatch(void); - -static struct irqaction irq_cascade = { - .handler = no_action, - .flags = 0, - .mask = CPU_MASK_NONE, - .name = "cascade", - .dev_id = NULL, - .next = NULL, -}; - -void __init arch_init_irq(void) -{ - u32 reg; - - db_run(printk("markeins_irq_setup invoked.\n")); - - /* by default, interrupts are disabled. */ - emma2rh_out32(EMMA2RH_BHIF_INT_EN_0, 0); - emma2rh_out32(EMMA2RH_BHIF_INT_EN_1, 0); - emma2rh_out32(EMMA2RH_BHIF_INT_EN_2, 0); - emma2rh_out32(EMMA2RH_BHIF_INT1_EN_0, 0); - emma2rh_out32(EMMA2RH_BHIF_INT1_EN_1, 0); - emma2rh_out32(EMMA2RH_BHIF_INT1_EN_2, 0); - emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, 0); - - clear_c0_status(0xff00); - set_c0_status(0x0400); - -#define GPIO_PCI (0xf<<15) - /* setup GPIO interrupt for PCI interface */ - /* direction input */ - reg = emma2rh_in32(EMMA2RH_GPIO_DIR); - emma2rh_out32(EMMA2RH_GPIO_DIR, reg & ~GPIO_PCI); - /* disable interrupt */ - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); - emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg & ~GPIO_PCI); - /* level triggerd */ - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MODE); - emma2rh_out32(EMMA2RH_GPIO_INT_MODE, reg | GPIO_PCI); - reg = emma2rh_in32(EMMA2RH_GPIO_INT_CND_A); - emma2rh_out32(EMMA2RH_GPIO_INT_CND_A, reg & (~GPIO_PCI)); - /* interrupt clear */ - emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~GPIO_PCI); - - /* init all controllers */ - emma2rh_irq_init(EMMA2RH_IRQ_BASE); - emma2rh_sw_irq_init(EMMA2RH_SW_IRQ_BASE); - emma2rh_gpio_irq_init(EMMA2RH_GPIO_IRQ_BASE); - mips_cpu_irq_init(); - - /* setup cascade interrupts */ - setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade); - setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade); - setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade); -} - -asmlinkage void plat_irq_dispatch(void) -{ - unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; - - if (pending & STATUSF_IP7) - do_IRQ(CPU_IRQ_BASE + 7); - else if (pending & STATUSF_IP2) - emma2rh_irq_dispatch(); - else if (pending & STATUSF_IP1) - do_IRQ(CPU_IRQ_BASE + 1); - else if (pending & STATUSF_IP0) - do_IRQ(CPU_IRQ_BASE + 0); - else - spurious_interrupt(); -} - - diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c deleted file mode 100644 index fba5c15..0000000 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * arch/mips/emma2rh/markeins/irq_markeins.c - * This file defines the irq handler for Mark-eins. - * - * Copyright (C) NEC Electronics Corporation 2004-2006 - * - * This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c - * - * Copyright 2001 MontaVista Software 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 program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/types.h> -#include <linux/ptrace.h> - -#include <asm/debug.h> -#include <asm/emma2rh/emma2rh.h> - -static int emma2rh_sw_irq_base = -1; -static int emma2rh_gpio_irq_base = -1; - -void ll_emma2rh_sw_irq_enable(int reg); -void ll_emma2rh_sw_irq_disable(int reg); -void ll_emma2rh_gpio_irq_enable(int reg); -void ll_emma2rh_gpio_irq_disable(int reg); - -static void emma2rh_sw_irq_enable(unsigned int irq) -{ - ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base); -} - -static void emma2rh_sw_irq_disable(unsigned int irq) -{ - ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); -} - -struct irq_chip emma2rh_sw_irq_controller = { - .name = "emma2rh_sw_irq", - .ack = emma2rh_sw_irq_disable, - .mask = emma2rh_sw_irq_disable, - .mask_ack = emma2rh_sw_irq_disable, - .unmask = emma2rh_sw_irq_enable, -}; - -void emma2rh_sw_irq_init(u32 irq_base) -{ - u32 i; - - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) - set_irq_chip_and_handler(i, &emma2rh_sw_irq_controller, - handle_level_irq); - - emma2rh_sw_irq_base = irq_base; -} - -void ll_emma2rh_sw_irq_enable(int irq) -{ - u32 reg; - - db_assert(irq >= 0); - db_assert(irq < NUM_EMMA2RH_IRQ_SW); - - reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); - reg |= 1 << irq; - emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); -} - -void ll_emma2rh_sw_irq_disable(int irq) -{ - u32 reg; - - db_assert(irq >= 0); - db_assert(irq < 32); - - reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN); - reg &= ~(1 << irq); - emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN, reg); -} - -static void emma2rh_gpio_irq_enable(unsigned int irq) -{ - ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); -} - -static void emma2rh_gpio_irq_disable(unsigned int irq) -{ - ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base); -} - -static void emma2rh_gpio_irq_ack(unsigned int irq) -{ - irq -= emma2rh_gpio_irq_base; - emma2rh_out32(EMMA2RH_GPIO_INT_ST, ~(1 << irq)); - ll_emma2rh_gpio_irq_disable(irq); -} - -static void emma2rh_gpio_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); -} - -struct irq_chip emma2rh_gpio_irq_controller = { - .name = "emma2rh_gpio_irq", - .ack = emma2rh_gpio_irq_ack, - .mask = emma2rh_gpio_irq_disable, - .mask_ack = emma2rh_gpio_irq_ack, - .unmask = emma2rh_gpio_irq_enable, - .end = emma2rh_gpio_irq_end, -}; - -void emma2rh_gpio_irq_init(u32 irq_base) -{ - u32 i; - - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) - set_irq_chip(i, &emma2rh_gpio_irq_controller); - - emma2rh_gpio_irq_base = irq_base; -} - -void ll_emma2rh_gpio_irq_enable(int irq) -{ - u32 reg; - - db_assert(irq >= 0); - db_assert(irq < NUM_EMMA2RH_IRQ_GPIO); - - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); - reg |= 1 << irq; - emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); -} - -void ll_emma2rh_gpio_irq_disable(int irq) -{ - u32 reg; - - db_assert(irq >= 0); - db_assert(irq < NUM_EMMA2RH_IRQ_GPIO); - - reg = emma2rh_in32(EMMA2RH_GPIO_INT_MASK); - reg &= ~(1 << irq); - emma2rh_out32(EMMA2RH_GPIO_INT_MASK, reg); -} diff --git a/arch/mips/include/asm/emma2rh/emma2rh.h b/arch/mips/include/asm/emma/emma2rh.h index 6a1af0a..30aea91 100644 --- a/arch/mips/include/asm/emma2rh/emma2rh.h +++ b/arch/mips/include/asm/emma/emma2rh.h @@ -1,5 +1,5 @@ /* - * include/asm-mips/emma2rh/emma2rh.h + * arch/mips/include/asm/emma/emma2rh.h * This file is EMMA2RH common header. * * Copyright (C) NEC Electronics Corporation 2005-2006 @@ -21,8 +21,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __ASM_EMMA2RH_EMMA2RH_H -#define __ASM_EMMA2RH_EMMA2RH_H +#ifndef __ASM_EMMA_EMMA2RH_H +#define __ASM_EMMA_EMMA2RH_H #include <irq.h> @@ -206,7 +206,6 @@ static inline void emma2rh_out32(u32 offset, u32 val) static inline u32 emma2rh_in32(u32 offset) { u32 val = *(volatile u32 *)(EMMA2RH_BASE | offset); - emma2rh_sync(); return val; } @@ -219,7 +218,6 @@ static inline void emma2rh_out16(u32 offset, u16 val) static inline u16 emma2rh_in16(u32 offset) { u16 val = *(volatile u16 *)(EMMA2RH_BASE | offset); - emma2rh_sync(); return val; } @@ -232,7 +230,6 @@ static inline void emma2rh_out8(u32 offset, u8 val) static inline u8 emma2rh_in8(u32 offset) { u8 val = *(volatile u8 *)(EMMA2RH_BASE | offset); - emma2rh_sync(); return val; } @@ -324,10 +321,10 @@ static inline u8 emma2rh_in8(u32 offset) /* * include the board dependent part */ -#if defined(CONFIG_MARKEINS) -#include <asm/emma2rh/markeins.h> +#ifdef CONFIG_NEC_MARKEINS +#include <asm/emma/markeins.h> #else #error "Unknown EMMA2RH board!" #endif -#endif /* __ASM_EMMA2RH_EMMA2RH_H */ +#endif /* __ASM_EMMA_EMMA2RH_H */ diff --git a/arch/mips/include/asm/emma2rh/markeins.h b/arch/mips/include/asm/emma/markeins.h index 973b062..973b062 100644 --- a/arch/mips/include/asm/emma2rh/markeins.h +++ b/arch/mips/include/asm/emma/markeins.h diff --git a/arch/mips/include/asm/mach-lemote/pci.h b/arch/mips/include/asm/mach-lemote/pci.h new file mode 100644 index 0000000..ea6aa14 --- /dev/null +++ b/arch/mips/include/asm/mach-lemote/pci.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2008 Zhang Le <r0bertz@gentoo.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, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + * 02139, USA. + */ + +#ifndef _LEMOTE_PCI_H_ +#define _LEMOTE_PCI_H_ + +#define LOONGSON2E_PCI_MEM_START 0x14000000UL +#define LOONGSON2E_PCI_MEM_END 0x1fffffffUL +#define LOONGSON2E_PCI_IO_START 0x00004000UL +#define LOONGSON2E_IO_PORT_BASE 0x1fd00000UL + +#endif /* !_LEMOTE_PCI_H_ */ diff --git a/arch/mips/include/asm/mach-pnx833x/gpio.h b/arch/mips/include/asm/mach-pnx833x/gpio.h new file mode 100644 index 0000000..8de0eb9 --- /dev/null +++ b/arch/mips/include/asm/mach-pnx833x/gpio.h @@ -0,0 +1,172 @@ +/* + * gpio.h: GPIO Support for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __ASM_MIPS_MACH_PNX833X_GPIO_H +#define __ASM_MIPS_MACH_PNX833X_GPIO_H + +/* BIG FAT WARNING: races danger! + No protections exist here. Current users are only early init code, + when locking is not needed because no cuncurency yet exists there, + and GPIO IRQ dispatcher, which does locking. + However, if many uses will ever happen, proper locking will be needed + - including locking between different uses +*/ + +#include "pnx833x.h" + +#define SET_REG_BIT(reg, bit) do { (reg |= (1 << (bit))); } while (0) +#define CLEAR_REG_BIT(reg, bit) do { (reg &= ~(1 << (bit))); } while (0) + +/* Initialize GPIO to a known state */ +static inline void pnx833x_gpio_init(void) +{ + PNX833X_PIO_DIR = 0; + PNX833X_PIO_DIR2 = 0; + PNX833X_PIO_SEL = 0; + PNX833X_PIO_SEL2 = 0; + PNX833X_PIO_INT_EDGE = 0; + PNX833X_PIO_INT_HI = 0; + PNX833X_PIO_INT_LO = 0; + + /* clear any GPIO interrupt requests */ + PNX833X_PIO_INT_CLEAR = 0xffff; + PNX833X_PIO_INT_CLEAR = 0; + PNX833X_PIO_INT_ENABLE = 0; +} + +/* Select GPIO direction for a pin */ +static inline void pnx833x_gpio_select_input(unsigned int pin) +{ + if (pin < 32) + CLEAR_REG_BIT(PNX833X_PIO_DIR, pin); + else + CLEAR_REG_BIT(PNX833X_PIO_DIR2, pin & 31); +} +static inline void pnx833x_gpio_select_output(unsigned int pin) +{ + if (pin < 32) + SET_REG_BIT(PNX833X_PIO_DIR, pin); + else + SET_REG_BIT(PNX833X_PIO_DIR2, pin & 31); +} + +/* Select GPIO or alternate function for a pin */ +static inline void pnx833x_gpio_select_function_io(unsigned int pin) +{ + if (pin < 32) + CLEAR_REG_BIT(PNX833X_PIO_SEL, pin); + else + CLEAR_REG_BIT(PNX833X_PIO_SEL2, pin & 31); +} +static inline void pnx833x_gpio_select_function_alt(unsigned int pin) +{ + if (pin < 32) + SET_REG_BIT(PNX833X_PIO_SEL, pin); + else + SET_REG_BIT(PNX833X_PIO_SEL2, pin & 31); +} + +/* Read GPIO pin */ +static inline int pnx833x_gpio_read(unsigned int pin) +{ + if (pin < 32) + return (PNX833X_PIO_IN >> pin) & 1; + else + return (PNX833X_PIO_IN2 >> (pin & 31)) & 1; +} + +/* Write GPIO pin */ +static inline void pnx833x_gpio_write(unsigned int val, unsigned int pin) +{ + if (pin < 32) { + if (val) + SET_REG_BIT(PNX833X_PIO_OUT, pin); + else + CLEAR_REG_BIT(PNX833X_PIO_OUT, pin); + } else { + if (val) + SET_REG_BIT(PNX833X_PIO_OUT2, pin & 31); + else + CLEAR_REG_BIT(PNX833X_PIO_OUT2, pin & 31); + } +} + +/* Configure GPIO interrupt */ +#define GPIO_INT_NONE 0 +#define GPIO_INT_LEVEL_LOW 1 +#define GPIO_INT_LEVEL_HIGH 2 +#define GPIO_INT_EDGE_RISING 3 +#define GPIO_INT_EDGE_FALLING 4 +#define GPIO_INT_EDGE_BOTH 5 +static inline void pnx833x_gpio_setup_irq(int when, unsigned int pin) +{ + switch (when) { + case GPIO_INT_LEVEL_LOW: + CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); + SET_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + case GPIO_INT_LEVEL_HIGH: + CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + SET_REG_BIT(PNX833X_PIO_INT_HI, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + case GPIO_INT_EDGE_RISING: + SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + SET_REG_BIT(PNX833X_PIO_INT_HI, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + case GPIO_INT_EDGE_FALLING: + SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); + SET_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + case GPIO_INT_EDGE_BOTH: + SET_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + SET_REG_BIT(PNX833X_PIO_INT_HI, pin); + SET_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + default: + CLEAR_REG_BIT(PNX833X_PIO_INT_EDGE, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_HI, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_LO, pin); + break; + } +} + +/* Enable/disable GPIO interrupt */ +static inline void pnx833x_gpio_enable_irq(unsigned int pin) +{ + SET_REG_BIT(PNX833X_PIO_INT_ENABLE, pin); +} +static inline void pnx833x_gpio_disable_irq(unsigned int pin) +{ + CLEAR_REG_BIT(PNX833X_PIO_INT_ENABLE, pin); +} + +/* Clear GPIO interrupt request */ +static inline void pnx833x_gpio_clear_irq(unsigned int pin) +{ + SET_REG_BIT(PNX833X_PIO_INT_CLEAR, pin); + CLEAR_REG_BIT(PNX833X_PIO_INT_CLEAR, pin); +} + +#endif diff --git a/arch/mips/include/asm/mach-pnx833x/irq-mapping.h b/arch/mips/include/asm/mach-pnx833x/irq-mapping.h new file mode 100644 index 0000000..657f089 --- /dev/null +++ b/arch/mips/include/asm/mach-pnx833x/irq-mapping.h @@ -0,0 +1,126 @@ + +/* + * irq.h: IRQ mappings for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H +#define __ASM_MIPS_MACH_PNX833X_IRQ_MAPPING_H +/* + * The "IRQ numbers" are completely virtual. + * + * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48. + * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt, + * numbers 49..64 for (virtual) GPIO interrupts. + * + * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57, + * connected to PIC, which uses core hardware interrupt 2, and also + * a timer interrupt through hardware interrupt 5. + * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt, + * numbers 65..80 for (virtual) GPIO interrupts. + * + */ +#include <irq.h> + +#define PNX833X_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 7) + +/* Interrupts supported by PIC */ +#define PNX833X_PIC_I2C0_INT (PNX833X_PIC_IRQ_BASE + 1) +#define PNX833X_PIC_I2C1_INT (PNX833X_PIC_IRQ_BASE + 2) +#define PNX833X_PIC_UART0_INT (PNX833X_PIC_IRQ_BASE + 3) +#define PNX833X_PIC_UART1_INT (PNX833X_PIC_IRQ_BASE + 4) +#define PNX833X_PIC_TS_IN0_DV_INT (PNX833X_PIC_IRQ_BASE + 5) +#define PNX833X_PIC_TS_IN0_DMA_INT (PNX833X_PIC_IRQ_BASE + 6) +#define PNX833X_PIC_GPIO_INT (PNX833X_PIC_IRQ_BASE + 7) +#define PNX833X_PIC_AUDIO_DEC_INT (PNX833X_PIC_IRQ_BASE + 8) +#define PNX833X_PIC_VIDEO_DEC_INT (PNX833X_PIC_IRQ_BASE + 9) +#define PNX833X_PIC_CONFIG_INT (PNX833X_PIC_IRQ_BASE + 10) +#define PNX833X_PIC_AOI_INT (PNX833X_PIC_IRQ_BASE + 11) +#define PNX833X_PIC_SYNC_INT (PNX833X_PIC_IRQ_BASE + 12) +#define PNX8330_PIC_SPU_INT (PNX833X_PIC_IRQ_BASE + 13) +#define PNX8335_PIC_SATA_INT (PNX833X_PIC_IRQ_BASE + 13) +#define PNX833X_PIC_OSD_INT (PNX833X_PIC_IRQ_BASE + 14) +#define PNX833X_PIC_DISP1_INT (PNX833X_PIC_IRQ_BASE + 15) +#define PNX833X_PIC_DEINTERLACER_INT (PNX833X_PIC_IRQ_BASE + 16) +#define PNX833X_PIC_DISPLAY2_INT (PNX833X_PIC_IRQ_BASE + 17) +#define PNX833X_PIC_VC_INT (PNX833X_PIC_IRQ_BASE + 18) +#define PNX833X_PIC_SC_INT (PNX833X_PIC_IRQ_BASE + 19) +#define PNX833X_PIC_IDE_INT (PNX833X_PIC_IRQ_BASE + 20) +#define PNX833X_PIC_IDE_DMA_INT (PNX833X_PIC_IRQ_BASE + 21) +#define PNX833X_PIC_TS_IN1_DV_INT (PNX833X_PIC_IRQ_BASE + 22) +#define PNX833X_PIC_TS_IN1_DMA_INT (PNX833X_PIC_IRQ_BASE + 23) +#define PNX833X_PIC_SGDX_DMA_INT (PNX833X_PIC_IRQ_BASE + 24) +#define PNX833X_PIC_TS_OUT_INT (PNX833X_PIC_IRQ_BASE + 25) +#define PNX833X_PIC_IR_INT (PNX833X_PIC_IRQ_BASE + 26) +#define PNX833X_PIC_VMSP1_INT (PNX833X_PIC_IRQ_BASE + 27) +#define PNX833X_PIC_VMSP2_INT (PNX833X_PIC_IRQ_BASE + 28) +#define PNX833X_PIC_PIBC_INT (PNX833X_PIC_IRQ_BASE + 29) +#define PNX833X_PIC_TS_IN0_TRD_INT (PNX833X_PIC_IRQ_BASE + 30) +#define PNX833X_PIC_SGDX_TPD_INT (PNX833X_PIC_IRQ_BASE + 31) +#define PNX833X_PIC_USB_INT (PNX833X_PIC_IRQ_BASE + 32) +#define PNX833X_PIC_TS_IN1_TRD_INT (PNX833X_PIC_IRQ_BASE + 33) +#define PNX833X_PIC_CLOCK_INT (PNX833X_PIC_IRQ_BASE + 34) +#define PNX833X_PIC_SGDX_PARSER_INT (PNX833X_PIC_IRQ_BASE + 35) +#define PNX833X_PIC_VMSP_DMA_INT (PNX833X_PIC_IRQ_BASE + 36) + +#if defined(CONFIG_SOC_PNX8335) +#define PNX8335_PIC_MIU_INT (PNX833X_PIC_IRQ_BASE + 37) +#define PNX8335_PIC_AVCHIP_IRQ_INT (PNX833X_PIC_IRQ_BASE + 38) +#define PNX8335_PIC_SYNC_HD_INT (PNX833X_PIC_IRQ_BASE + 39) +#define PNX8335_PIC_DISP_HD_INT (PNX833X_PIC_IRQ_BASE + 40) +#define PNX8335_PIC_DISP_SCALER_INT (PNX833X_PIC_IRQ_BASE + 41) +#define PNX8335_PIC_OSD_HD1_INT (PNX833X_PIC_IRQ_BASE + 42) +#define PNX8335_PIC_DTL_WRITER_Y_INT (PNX833X_PIC_IRQ_BASE + 43) +#define PNX8335_PIC_DTL_WRITER_C_INT (PNX833X_PIC_IRQ_BASE + 44) +#define PNX8335_PIC_DTL_EMULATOR_Y_IR_INT (PNX833X_PIC_IRQ_BASE + 45) +#define PNX8335_PIC_DTL_EMULATOR_C_IR_INT (PNX833X_PIC_IRQ_BASE + 46) +#define PNX8335_PIC_DENC_TTX_INT (PNX833X_PIC_IRQ_BASE + 47) +#define PNX8335_PIC_MMI_SIF0_INT (PNX833X_PIC_IRQ_BASE + 48) +#define PNX8335_PIC_MMI_SIF1_INT (PNX833X_PIC_IRQ_BASE + 49) +#define PNX8335_PIC_MMI_CDMMU_INT (PNX833X_PIC_IRQ_BASE + 50) +#define PNX8335_PIC_PIBCS_INT (PNX833X_PIC_IRQ_BASE + 51) +#define PNX8335_PIC_ETHERNET_INT (PNX833X_PIC_IRQ_BASE + 52) +#define PNX8335_PIC_VMSP1_0_INT (PNX833X_PIC_IRQ_BASE + 53) +#define PNX8335_PIC_VMSP1_1_INT (PNX833X_PIC_IRQ_BASE + 54) +#define PNX8335_PIC_VMSP1_DMA_INT (PNX833X_PIC_IRQ_BASE + 55) +#define PNX8335_PIC_TDGR_DE_INT (PNX833X_PIC_IRQ_BASE + 56) +#define PNX8335_PIC_IR1_IRQ_INT (PNX833X_PIC_IRQ_BASE + 57) +#endif + +/* GPIO interrupts */ +#define PNX833X_GPIO_0_INT (PNX833X_GPIO_IRQ_BASE + 0) +#define PNX833X_GPIO_1_INT (PNX833X_GPIO_IRQ_BASE + 1) +#define PNX833X_GPIO_2_INT (PNX833X_GPIO_IRQ_BASE + 2) +#define PNX833X_GPIO_3_INT (PNX833X_GPIO_IRQ_BASE + 3) +#define PNX833X_GPIO_4_INT (PNX833X_GPIO_IRQ_BASE + 4) +#define PNX833X_GPIO_5_INT (PNX833X_GPIO_IRQ_BASE + 5) +#define PNX833X_GPIO_6_INT (PNX833X_GPIO_IRQ_BASE + 6) +#define PNX833X_GPIO_7_INT (PNX833X_GPIO_IRQ_BASE + 7) +#define PNX833X_GPIO_8_INT (PNX833X_GPIO_IRQ_BASE + 8) +#define PNX833X_GPIO_9_INT (PNX833X_GPIO_IRQ_BASE + 9) +#define PNX833X_GPIO_10_INT (PNX833X_GPIO_IRQ_BASE + 10) +#define PNX833X_GPIO_11_INT (PNX833X_GPIO_IRQ_BASE + 11) +#define PNX833X_GPIO_12_INT (PNX833X_GPIO_IRQ_BASE + 12) +#define PNX833X_GPIO_13_INT (PNX833X_GPIO_IRQ_BASE + 13) +#define PNX833X_GPIO_14_INT (PNX833X_GPIO_IRQ_BASE + 14) +#define PNX833X_GPIO_15_INT (PNX833X_GPIO_IRQ_BASE + 15) + +#endif + diff --git a/arch/mips/include/asm/mach-pnx833x/irq.h b/arch/mips/include/asm/mach-pnx833x/irq.h new file mode 100644 index 0000000..745114b --- /dev/null +++ b/arch/mips/include/asm/mach-pnx833x/irq.h @@ -0,0 +1,53 @@ +/* + * irq.h: IRQ mappings for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ASM_MIPS_MACH_PNX833X_IRQ_H +#define __ASM_MIPS_MACH_PNX833X_IRQ_H +/* + * The "IRQ numbers" are completely virtual. + * + * In PNX8330/1, we have 48 interrupt lines, numbered from 1 to 48. + * Let's use numbers 1..48 for PIC interrupts, number 0 for timer interrupt, + * numbers 49..64 for (virtual) GPIO interrupts. + * + * In PNX8335, we have 57 interrupt lines, numbered from 1 to 57, + * connected to PIC, which uses core hardware interrupt 2, and also + * a timer interrupt through hardware interrupt 5. + * Let's use numbers 1..64 for PIC interrupts, number 0 for timer interrupt, + * numbers 65..80 for (virtual) GPIO interrupts. + * + */ +#if defined(CONFIG_SOC_PNX8335) + #define PNX833X_PIC_NUM_IRQ 58 +#else + #define PNX833X_PIC_NUM_IRQ 37 +#endif + +#define MIPS_CPU_NUM_IRQ 8 +#define PNX833X_GPIO_NUM_IRQ 16 + +#define MIPS_CPU_IRQ_BASE 0 +#define PNX833X_PIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + MIPS_CPU_NUM_IRQ) +#define PNX833X_GPIO_IRQ_BASE (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ) +#define NR_IRQS (MIPS_CPU_NUM_IRQ + PNX833X_PIC_NUM_IRQ + PNX833X_GPIO_NUM_IRQ) + +#endif diff --git a/arch/mips/include/asm/mach-pnx833x/pnx833x.h b/arch/mips/include/asm/mach-pnx833x/pnx833x.h new file mode 100644 index 0000000..100f528 --- /dev/null +++ b/arch/mips/include/asm/mach-pnx833x/pnx833x.h @@ -0,0 +1,202 @@ +/* + * pnx833x.h: Register mappings for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __ASM_MIPS_MACH_PNX833X_PNX833X_H +#define __ASM_MIPS_MACH_PNX833X_PNX833X_H + +/* All regs are accessed in KSEG1 */ +#define PNX833X_BASE (0xa0000000ul + 0x17E00000ul) + +#define PNX833X_REG(offs) (*((volatile unsigned long *)(PNX833X_BASE + offs))) + +/* Registers are named exactly as in PNX833X docs, just with PNX833X_ prefix */ + +/* Read access to multibit fields */ +#define PNX833X_BIT(val, reg, field) ((val) & PNX833X_##reg##_##field) +#define PNX833X_REGBIT(reg, field) PNX833X_BIT(PNX833X_##reg, reg, field) + +/* Use PNX833X_FIELD to extract a field from val */ +#define PNX_FIELD(cpu, val, reg, field) \ + (((val) & PNX##cpu##_##reg##_##field##_MASK) >> \ + PNX##cpu##_##reg##_##field##_SHIFT) +#define PNX833X_FIELD(val, reg, field) PNX_FIELD(833X, val, reg, field) +#define PNX8330_FIELD(val, reg, field) PNX_FIELD(8330, val, reg, field) +#define PNX8335_FIELD(val, reg, field) PNX_FIELD(8335, val, reg, field) + +/* Use PNX833X_REGFIELD to extract a field from a register */ +#define PNX833X_REGFIELD(reg, field) PNX833X_FIELD(PNX833X_##reg, reg, field) +#define PNX8330_REGFIELD(reg, field) PNX8330_FIELD(PNX8330_##reg, reg, field) +#define PNX8335_REGFIELD(reg, field) PNX8335_FIELD(PNX8335_##reg, reg, field) + + +#define PNX_WRITEFIELD(cpu, val, reg, field) \ + (PNX##cpu##_##reg = (PNX##cpu##_##reg & ~(PNX##cpu##_##reg##_##field##_MASK)) | \ + ((val) << PNX##cpu##_##reg##_##field##_SHIFT)) +#define PNX833X_WRITEFIELD(val, reg, field) \ + PNX_WRITEFIELD(833X, val, reg, field) +#define PNX8330_WRITEFIELD(val, reg, field) \ + PNX_WRITEFIELD(8330, val, reg, field) +#define PNX8335_WRITEFIELD(val, reg, field) \ + PNX_WRITEFIELD(8335, val, reg, field) + + +/* Macros to detect CPU type */ + +#define PNX833X_CONFIG_MODULE_ID PNX833X_REG(0x7FFC) +#define PNX833X_CONFIG_MODULE_ID_MAJREV_MASK 0x0000f000 +#define PNX833X_CONFIG_MODULE_ID_MAJREV_SHIFT 12 +#define PNX8330_CONFIG_MODULE_MAJREV 4 +#define PNX8335_CONFIG_MODULE_MAJREV 5 +#define CPU_IS_PNX8330 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \ + PNX8330_CONFIG_MODULE_MAJREV) +#define CPU_IS_PNX8335 (PNX833X_REGFIELD(CONFIG_MODULE_ID, MAJREV) == \ + PNX8335_CONFIG_MODULE_MAJREV) + + + +#define PNX833X_RESET_CONTROL PNX833X_REG(0x8004) +#define PNX833X_RESET_CONTROL_2 PNX833X_REG(0x8014) + +#define PNX833X_PIC_REG(offs) PNX833X_REG(0x01000 + (offs)) +#define PNX833X_PIC_INT_PRIORITY PNX833X_PIC_REG(0x0) +#define PNX833X_PIC_INT_SRC PNX833X_PIC_REG(0x4) +#define PNX833X_PIC_INT_SRC_INT_SRC_MASK 0x00000FF8ul /* bits 11:3 */ +#define PNX833X_PIC_INT_SRC_INT_SRC_SHIFT 3 +#define PNX833X_PIC_INT_REG(irq) PNX833X_PIC_REG(0x10 + 4*(irq)) + +#define PNX833X_CLOCK_CPUCP_CTL PNX833X_REG(0x9228) +#define PNX833X_CLOCK_CPUCP_CTL_EXIT_RESET 0x00000002ul /* bit 1 */ +#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_MASK 0x00000018ul /* bits 4:3 */ +#define PNX833X_CLOCK_CPUCP_CTL_DIV_CLOCK_SHIFT 3 + +#define PNX8335_CLOCK_PLL_CPU_CTL PNX833X_REG(0x9020) +#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_MASK 0x1f +#define PNX8335_CLOCK_PLL_CPU_CTL_FREQ_SHIFT 0 + +#define PNX833X_CONFIG_MUX PNX833X_REG(0x7004) +#define PNX833X_CONFIG_MUX_IDE_MUX 0x00000080 /* bit 7 */ + +#define PNX8330_CONFIG_POLYFUSE_7 PNX833X_REG(0x7040) +#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_MASK 0x00180000 +#define PNX8330_CONFIG_POLYFUSE_7_BOOT_MODE_SHIFT 19 + +#define PNX833X_PIO_IN PNX833X_REG(0xF000) +#define PNX833X_PIO_OUT PNX833X_REG(0xF004) +#define PNX833X_PIO_DIR PNX833X_REG(0xF008) +#define PNX833X_PIO_SEL PNX833X_REG(0xF014) +#define PNX833X_PIO_INT_EDGE PNX833X_REG(0xF020) +#define PNX833X_PIO_INT_HI PNX833X_REG(0xF024) +#define PNX833X_PIO_INT_LO PNX833X_REG(0xF028) +#define PNX833X_PIO_INT_STATUS PNX833X_REG(0xFFE0) +#define PNX833X_PIO_INT_ENABLE PNX833X_REG(0xFFE4) +#define PNX833X_PIO_INT_CLEAR PNX833X_REG(0xFFE8) +#define PNX833X_PIO_IN2 PNX833X_REG(0xF05C) +#define PNX833X_PIO_OUT2 PNX833X_REG(0xF060) +#define PNX833X_PIO_DIR2 PNX833X_REG(0xF064) +#define PNX833X_PIO_SEL2 PNX833X_REG(0xF068) + +#define PNX833X_UART0_PORTS_START (PNX833X_BASE + 0xB000) +#define PNX833X_UART0_PORTS_END (PNX833X_BASE + 0xBFFF) +#define PNX833X_UART1_PORTS_START (PNX833X_BASE + 0xC000) +#define PNX833X_UART1_PORTS_END (PNX833X_BASE + 0xCFFF) + +#define PNX833X_USB_PORTS_START (PNX833X_BASE + 0x19000) +#define PNX833X_USB_PORTS_END (PNX833X_BASE + 0x19FFF) + +#define PNX833X_CONFIG_USB PNX833X_REG(0x7008) + +#define PNX833X_I2C0_PORTS_START (PNX833X_BASE + 0xD000) +#define PNX833X_I2C0_PORTS_END (PNX833X_BASE + 0xDFFF) +#define PNX833X_I2C1_PORTS_START (PNX833X_BASE + 0xE000) +#define PNX833X_I2C1_PORTS_END (PNX833X_BASE + 0xEFFF) + +#define PNX833X_IDE_PORTS_START (PNX833X_BASE + 0x1A000) +#define PNX833X_IDE_PORTS_END (PNX833X_BASE + 0x1AFFF) +#define PNX833X_IDE_MODULE_ID PNX833X_REG(0x1AFFC) + +#define PNX833X_IDE_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 +#define PNX833X_IDE_MODULE_ID_MODULE_ID_SHIFT 16 +#define PNX833X_IDE_MODULE_ID_VALUE 0xA009 + + +#define PNX833X_MIU_SEL0 PNX833X_REG(0x2004) +#define PNX833X_MIU_SEL0_TIMING PNX833X_REG(0x2008) +#define PNX833X_MIU_SEL1 PNX833X_REG(0x200C) +#define PNX833X_MIU_SEL1_TIMING PNX833X_REG(0x2010) +#define PNX833X_MIU_SEL2 PNX833X_REG(0x2014) +#define PNX833X_MIU_SEL2_TIMING PNX833X_REG(0x2018) +#define PNX833X_MIU_SEL3 PNX833X_REG(0x201C) +#define PNX833X_MIU_SEL3_TIMING PNX833X_REG(0x2020) + +#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_MASK (1 << 14) +#define PNX833X_MIU_SEL0_SPI_MODE_ENABLE_SHIFT 14 + +#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_MASK (1 << 7) +#define PNX833X_MIU_SEL0_BURST_MODE_ENABLE_SHIFT 7 + +#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_MASK (0xF << 9) +#define PNX833X_MIU_SEL0_BURST_PAGE_LEN_SHIFT 9 + +#define PNX833X_MIU_CONFIG_SPI PNX833X_REG(0x2000) + +#define PNX833X_MIU_CONFIG_SPI_OPCODE_MASK (0xFF << 3) +#define PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT 3 + +#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_MASK (1 << 2) +#define PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT 2 + +#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_MASK (1 << 1) +#define PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT 1 + +#define PNX833X_MIU_CONFIG_SPI_SYNC_MASK (1 << 0) +#define PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT 0 + +#define PNX833X_WRITE_CONFIG_SPI(opcode, data_enable, addr_enable, sync) \ + (PNX833X_MIU_CONFIG_SPI = \ + ((opcode) << PNX833X_MIU_CONFIG_SPI_OPCODE_SHIFT) | \ + ((data_enable) << PNX833X_MIU_CONFIG_SPI_DATA_ENABLE_SHIFT) | \ + ((addr_enable) << PNX833X_MIU_CONFIG_SPI_ADDR_ENABLE_SHIFT) | \ + ((sync) << PNX833X_MIU_CONFIG_SPI_SYNC_SHIFT)) + +#define PNX8335_IP3902_PORTS_START (PNX833X_BASE + 0x2F000) +#define PNX8335_IP3902_PORTS_END (PNX833X_BASE + 0x2FFFF) +#define PNX8335_IP3902_MODULE_ID PNX833X_REG(0x2FFFC) + +#define PNX8335_IP3902_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 +#define PNX8335_IP3902_MODULE_ID_MODULE_ID_SHIFT 16 +#define PNX8335_IP3902_MODULE_ID_VALUE 0x3902 + + /* I/O location(gets remapped)*/ +#define PNX8335_NAND_BASE 0x18000000 +/* I/O location with CLE high */ +#define PNX8335_NAND_CLE_MASK 0x00100000 +/* I/O location with ALE high */ +#define PNX8335_NAND_ALE_MASK 0x00010000 + +#define PNX8335_SATA_PORTS_START (PNX833X_BASE + 0x2E000) +#define PNX8335_SATA_PORTS_END (PNX833X_BASE + 0x2EFFF) +#define PNX8335_SATA_MODULE_ID PNX833X_REG(0x2EFFC) + +#define PNX8335_SATA_MODULE_ID_MODULE_ID_MASK 0xFFFF0000 +#define PNX8335_SATA_MODULE_ID_MODULE_ID_SHIFT 16 +#define PNX8335_SATA_MODULE_ID_VALUE 0xA099 + +#endif diff --git a/arch/mips/include/asm/mach-pnx833x/war.h b/arch/mips/include/asm/mach-pnx833x/war.h new file mode 100644 index 0000000..82cd1e9 --- /dev/null +++ b/arch/mips/include/asm/mach-pnx833x/war.h @@ -0,0 +1,25 @@ +/* + * 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) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> + */ +#ifndef __ASM_MIPS_MACH_PNX833X_WAR_H +#define __ASM_MIPS_MACH_PNX833X_WAR_H + +#define R4600_V1_INDEX_ICACHEOP_WAR 0 +#define R4600_V1_HIT_CACHEOP_WAR 0 +#define R4600_V2_HIT_CACHEOP_WAR 0 +#define R5432_CP0_INTERRUPT_WAR 0 +#define BCM1250_M3_WAR 0 +#define SIBYTE_1956_WAR 0 +#define MIPS4K_ICACHE_REFILL_WAR 0 +#define MIPS_CACHE_SYNC_WAR 0 +#define TX49XX_ICACHE_INDEX_INV_WAR 0 +#define RM9000_CDEX_SMP_WAR 0 +#define ICACHE_REFILLS_WORKAROUND_WAR 0 +#define R10000_LLSC_WAR 0 +#define MIPS34K_MISSED_ITLB_WAR 0 + +#endif /* __ASM_MIPS_MACH_PNX8550_WAR_H */ diff --git a/arch/mips/include/asm/mach-tx49xx/mangle-port.h b/arch/mips/include/asm/mach-tx49xx/mangle-port.h new file mode 100644 index 0000000..5e6912f --- /dev/null +++ b/arch/mips/include/asm/mach-tx49xx/mangle-port.h @@ -0,0 +1,26 @@ +#ifndef __ASM_MACH_TX49XX_MANGLE_PORT_H +#define __ASM_MACH_TX49XX_MANGLE_PORT_H + +#define __swizzle_addr_b(port) (port) +#define __swizzle_addr_w(port) (port) +#define __swizzle_addr_l(port) (port) +#define __swizzle_addr_q(port) (port) + +#define ioswabb(a, x) (x) +#define __mem_ioswabb(a, x) (x) +#if defined(CONFIG_TOSHIBA_RBTX4939) && \ + (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) && \ + defined(__BIG_ENDIAN) +#define NEEDS_TXX9_IOSWABW +extern u16 (*ioswabw)(volatile u16 *a, u16 x); +extern u16 (*__mem_ioswabw)(volatile u16 *a, u16 x); +#else +#define ioswabw(a, x) le16_to_cpu(x) +#define __mem_ioswabw(a, x) (x) +#endif +#define ioswabl(a, x) le32_to_cpu(x) +#define __mem_ioswabl(a, x) (x) +#define ioswabq(a, x) le64_to_cpu(x) +#define __mem_ioswabq(a, x) (x) + +#endif /* __ASM_MACH_TX49XX_MANGLE_PORT_H */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 9798660..9316324 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -192,6 +192,7 @@ #define PM_16M 0x01ffe000 #define PM_64M 0x07ffe000 #define PM_256M 0x1fffe000 +#define PM_1G 0x7fffe000 #endif diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index de6d09e..e2e09b2 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h @@ -98,6 +98,8 @@ search_module_dbetables(unsigned long addr) #define MODULE_PROC_FAMILY "R5000 " #elif defined CONFIG_CPU_R5432 #define MODULE_PROC_FAMILY "R5432 " +#elif defined CONFIG_CPU_R5500 +#define MODULE_PROC_FAMILY "R5500 " #elif defined CONFIG_CPU_R6000 #define MODULE_PROC_FAMILY "R6000 " #elif defined CONFIG_CPU_NEVADA diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 9c22571..813abd1 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -80,25 +80,25 @@ enum pt_watch_style { pt_watch_style_mips64 }; struct mips32_watch_regs { - uint32_t watchlo[8]; + unsigned int watchlo[8]; /* Lower 16 bits of watchhi. */ - uint16_t watchhi[8]; + unsigned short watchhi[8]; /* Valid mask and I R W bits. * bit 0 -- 1 if W bit is usable. * bit 1 -- 1 if R bit is usable. * bit 2 -- 1 if I bit is usable. * bits 3 - 11 -- Valid watchhi mask bits. */ - uint16_t watch_masks[8]; + unsigned short watch_masks[8]; /* The number of valid watch register pairs. */ - uint32_t num_valid; + unsigned int num_valid; } __attribute__((aligned(8))); struct mips64_watch_regs { - uint64_t watchlo[8]; - uint16_t watchhi[8]; - uint16_t watch_masks[8]; - uint32_t num_valid; + unsigned long long watchlo[8]; + unsigned short watchhi[8]; + unsigned short watch_masks[8]; + unsigned int num_valid; } __attribute__((aligned(8))); struct pt_watch_regs { @@ -116,6 +116,7 @@ struct pt_watch_regs { #include <linux/compiler.h> #include <linux/linkage.h> +#include <linux/types.h> #include <asm/isadep.h> struct task_struct; diff --git a/arch/mips/include/asm/txx9/generic.h b/arch/mips/include/asm/txx9/generic.h index 4316a3e..9cde009 100644 --- a/arch/mips/include/asm/txx9/generic.h +++ b/arch/mips/include/asm/txx9/generic.h @@ -86,4 +86,9 @@ void txx9_iocled_init(unsigned long baseaddr, int basenum, unsigned int num, int lowactive, const char *color, char **deftriggers); +/* 7SEG LED */ +void txx9_7segled_init(unsigned int num, + void (*putc)(unsigned int pos, unsigned char val)); +int txx9_7segled_putc(unsigned int pos, char c); + #endif /* __ASM_TXX9_GENERIC_H */ diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index d9da711..b1372c2 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5432) += r4k_fpu.o r4k_switch.o +obj-$(CONFIG_CPU_R5500) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R8000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM7000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_RM9000) += r4k_fpu.o r4k_switch.o diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 5e75a31..759f680 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -180,7 +180,7 @@ bad_stack: * The system call does not exist in this kernel */ illegal_syscall: - li v0, -ENOSYS # error + li v0, ENOSYS # error sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) @@ -293,7 +293,7 @@ bad_alignment: jr t2 /* Unreached */ -einval: li v0, -EINVAL +einval: li v0, -ENOSYS jr ra END(sys_syscall) diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3d58204..a9e1716 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -117,7 +117,7 @@ syscall_trace_entry: illegal_syscall: /* This also isn't a 64-bit syscall, throw an error. */ - li v0, -ENOSYS # error + li v0, ENOSYS # error sd v0, PT_R2(sp) li t0, 1 # set error flag sd t0, PT_R7(sp) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 16f8edf..4430a1f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -601,8 +601,8 @@ static int __init debugfs_mips(void) struct dentry *d; d = debugfs_create_dir("mips", NULL); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; mips_debugfs_dir = d; return 0; } diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 7b59cfb..b79ea70 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -163,8 +163,10 @@ static void stop_this_cpu(void *dummy) * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); - local_irq_enable(); /* May need to service _machine_restart IPI */ - for (;;); /* Wait if available. */ + for (;;) { + if (cpu_wait) + (*cpu_wait)(); /* Wait if available. */ + } } void smp_send_stop(void) diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index c327b21..20709669 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -560,12 +560,12 @@ static int __init debugfs_unaligned(void) return -ENODEV; d = debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir, &unaligned_instructions); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR, mips_debugfs_dir, &unaligned_action); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; return 0; } __initcall(debugfs_unaligned); diff --git a/arch/mips/lemote/lm2e/pci.c b/arch/mips/lemote/lm2e/pci.c index c1e41f1..8be03a8 100644 --- a/arch/mips/lemote/lm2e/pci.c +++ b/arch/mips/lemote/lm2e/pci.c @@ -30,19 +30,20 @@ #include <linux/kernel.h> #include <linux/init.h> #include <asm/mips-boards/bonito64.h> +#include <asm/mach-lemote/pci.h> extern struct pci_ops bonito64_pci_ops; static struct resource loongson2e_pci_mem_resource = { .name = "LOONGSON2E PCI MEM", - .start = 0x14000000UL, - .end = 0x1fffffffUL, + .start = LOONGSON2E_PCI_MEM_START, + .end = LOONGSON2E_PCI_MEM_END, .flags = IORESOURCE_MEM, }; static struct resource loongson2e_pci_io_resource = { .name = "LOONGSON2E PCI IO MEM", - .start = 0x00004000UL, + .start = LOONGSON2E_PCI_IO_START, .end = IO_SPACE_LIMIT, .flags = IORESOURCE_IO, }; @@ -82,6 +83,12 @@ static void __init ict_pcimap(void) static int __init pcibios_init(void) { ict_pcimap(); + + loongson2e_pci_controller.io_map_base = + (unsigned long) ioremap(LOONGSON2E_IO_PORT_BASE, + loongson2e_pci_io_resource.end - + loongson2e_pci_io_resource.start + 1); + register_pci_controller(&loongson2e_pci_controller); return 0; diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c index 2cc6745..ebd6cea 100644 --- a/arch/mips/lemote/lm2e/setup.c +++ b/arch/mips/lemote/lm2e/setup.c @@ -34,6 +34,7 @@ #include <asm/mc146818-time.h> #include <asm/time.h> #include <asm/wbflush.h> +#include <asm/mach-lemote/pci.h> #ifdef CONFIG_VT #include <linux/console.h> @@ -42,12 +43,6 @@ extern void mips_reboot_setup(void); -#ifdef CONFIG_64BIT -#define PTR_PAD(p) ((0xffffffff00000000)|((unsigned long long)(p))) -#else -#define PTR_PAD(p) (p) -#endif - unsigned long cpu_clock_freq; unsigned long bus_clock; unsigned int memsize; @@ -80,8 +75,8 @@ static void wbflush_loongson2e(void) void __init plat_mem_setup(void) { - set_io_port_base(PTR_PAD(0xbfd00000)); - + set_io_port_base((unsigned long)ioremap(LOONGSON2E_IO_PORT_BASE, + IO_SPACE_LIMIT - LOONGSON2E_PCI_IO_START + 1)); mips_reboot_setup(); __wbflush = wbflush_loongson2e; diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 8810dfb..dbcf651 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_CPU_R4300) += dump_tlb.o obj-$(CONFIG_CPU_R4X00) += dump_tlb.o obj-$(CONFIG_CPU_R5000) += dump_tlb.o obj-$(CONFIG_CPU_R5432) += dump_tlb.o +obj-$(CONFIG_CPU_R5500) += dump_tlb.o obj-$(CONFIG_CPU_R6000) += obj-$(CONFIG_CPU_R8000) += obj-$(CONFIG_CPU_RM7000) += dump_tlb.o diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 465ff0e..779821c 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c @@ -25,6 +25,7 @@ static inline const char *msk2str(unsigned int mask) case PM_16M: return "16Mb"; case PM_64M: return "64Mb"; case PM_256M: return "256Mb"; + case PM_1G: return "1Gb"; #endif } return ""; diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index b08fc65..7ec0b21 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -1299,12 +1299,12 @@ static int __init debugfs_fpuemu(void) if (!mips_debugfs_dir) return -ENODEV; dir = debugfs_create_dir("fpuemustats", mips_debugfs_dir); - if (IS_ERR(dir)) - return PTR_ERR(dir); + if (!dir) + return -ENOMEM; for (i = 0; i < ARRAY_SIZE(vars); i++) { d = debugfs_create_u32(vars[i].name, S_IRUGO, dir, vars[i].v); - if (IS_ERR(d)) - return PTR_ERR(d); + if (!d) + return -ENOMEM; } return 0; } diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 44e8dd8..95ba32b 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_CPU_R4300) += c-r4k.o cex-gen.o tlb-r4k.o obj-$(CONFIG_CPU_R4X00) += c-r4k.o cex-gen.o tlb-r4k.o obj-$(CONFIG_CPU_R5000) += c-r4k.o cex-gen.o tlb-r4k.o obj-$(CONFIG_CPU_R5432) += c-r4k.o cex-gen.o tlb-r4k.o +obj-$(CONFIG_CPU_R5500) += c-r4k.o cex-gen.o tlb-r4k.o obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o obj-$(CONFIG_CPU_RM7000) += c-r4k.o cex-gen.o tlb-r4k.o obj-$(CONFIG_CPU_RM9000) += c-r4k.o cex-gen.o tlb-r4k.o diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 891312f..5b98d0e 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -324,7 +324,6 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, if (cpu_is_noncoherent_r10000(dev)) __dma_sync((unsigned long)page_address(sg_page(sg)), sg->length, direction); - plat_unmap_dma_mem(sg->dma_address); } } @@ -342,7 +341,6 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele if (!plat_device_is_coherent(dev)) __dma_sync((unsigned long)page_address(sg_page(sg)), sg->length, direction); - plat_unmap_dma_mem(sg->dma_address); } } diff --git a/arch/mips/nxp/pnx833x/common/Makefile b/arch/mips/nxp/pnx833x/common/Makefile new file mode 100644 index 0000000..4a16f3b --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/Makefile @@ -0,0 +1,3 @@ +obj-y := interrupts.o platform.o prom.o setup.o reset.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/nxp/pnx833x/common/interrupts.c new file mode 100644 index 0000000..30533ba --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/interrupts.c @@ -0,0 +1,380 @@ +/* + * interrupts.c: Interrupt mappings for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <linux/kernel.h> +#include <linux/irq.h> +#include <linux/hardirq.h> +#include <linux/interrupt.h> +#include <asm/mipsregs.h> +#include <asm/irq_cpu.h> +#include <irq.h> +#include <irq-mapping.h> +#include <gpio.h> + +static int mips_cpu_timer_irq; + +static const unsigned int irq_prio[PNX833X_PIC_NUM_IRQ] = +{ + 0, /* unused */ + 4, /* PNX833X_PIC_I2C0_INT 1 */ + 4, /* PNX833X_PIC_I2C1_INT 2 */ + 1, /* PNX833X_PIC_UART0_INT 3 */ + 1, /* PNX833X_PIC_UART1_INT 4 */ + 6, /* PNX833X_PIC_TS_IN0_DV_INT 5 */ + 6, /* PNX833X_PIC_TS_IN0_DMA_INT 6 */ + 7, /* PNX833X_PIC_GPIO_INT 7 */ + 4, /* PNX833X_PIC_AUDIO_DEC_INT 8 */ + 5, /* PNX833X_PIC_VIDEO_DEC_INT 9 */ + 4, /* PNX833X_PIC_CONFIG_INT 10 */ + 4, /* PNX833X_PIC_AOI_INT 11 */ + 9, /* PNX833X_PIC_SYNC_INT 12 */ + 9, /* PNX8335_PIC_SATA_INT 13 */ + 4, /* PNX833X_PIC_OSD_INT 14 */ + 9, /* PNX833X_PIC_DISP1_INT 15 */ + 4, /* PNX833X_PIC_DEINTERLACER_INT 16 */ + 9, /* PNX833X_PIC_DISPLAY2_INT 17 */ + 4, /* PNX833X_PIC_VC_INT 18 */ + 4, /* PNX833X_PIC_SC_INT 19 */ + 9, /* PNX833X_PIC_IDE_INT 20 */ + 9, /* PNX833X_PIC_IDE_DMA_INT 21 */ + 6, /* PNX833X_PIC_TS_IN1_DV_INT 22 */ + 6, /* PNX833X_PIC_TS_IN1_DMA_INT 23 */ + 4, /* PNX833X_PIC_SGDX_DMA_INT 24 */ + 4, /* PNX833X_PIC_TS_OUT_INT 25 */ + 4, /* PNX833X_PIC_IR_INT 26 */ + 3, /* PNX833X_PIC_VMSP1_INT 27 */ + 3, /* PNX833X_PIC_VMSP2_INT 28 */ + 4, /* PNX833X_PIC_PIBC_INT 29 */ + 4, /* PNX833X_PIC_TS_IN0_TRD_INT 30 */ + 4, /* PNX833X_PIC_SGDX_TPD_INT 31 */ + 5, /* PNX833X_PIC_USB_INT 32 */ + 4, /* PNX833X_PIC_TS_IN1_TRD_INT 33 */ + 4, /* PNX833X_PIC_CLOCK_INT 34 */ + 4, /* PNX833X_PIC_SGDX_PARSER_INT 35 */ + 4, /* PNX833X_PIC_VMSP_DMA_INT 36 */ +#if defined(CONFIG_SOC_PNX8335) + 4, /* PNX8335_PIC_MIU_INT 37 */ + 4, /* PNX8335_PIC_AVCHIP_IRQ_INT 38 */ + 9, /* PNX8335_PIC_SYNC_HD_INT 39 */ + 9, /* PNX8335_PIC_DISP_HD_INT 40 */ + 9, /* PNX8335_PIC_DISP_SCALER_INT 41 */ + 4, /* PNX8335_PIC_OSD_HD1_INT 42 */ + 4, /* PNX8335_PIC_DTL_WRITER_Y_INT 43 */ + 4, /* PNX8335_PIC_DTL_WRITER_C_INT 44 */ + 4, /* PNX8335_PIC_DTL_EMULATOR_Y_IR_INT 45 */ + 4, /* PNX8335_PIC_DTL_EMULATOR_C_IR_INT 46 */ + 4, /* PNX8335_PIC_DENC_TTX_INT 47 */ + 4, /* PNX8335_PIC_MMI_SIF0_INT 48 */ + 4, /* PNX8335_PIC_MMI_SIF1_INT 49 */ + 4, /* PNX8335_PIC_MMI_CDMMU_INT 50 */ + 4, /* PNX8335_PIC_PIBCS_INT 51 */ + 12, /* PNX8335_PIC_ETHERNET_INT 52 */ + 3, /* PNX8335_PIC_VMSP1_0_INT 53 */ + 3, /* PNX8335_PIC_VMSP1_1_INT 54 */ + 4, /* PNX8335_PIC_VMSP1_DMA_INT 55 */ + 4, /* PNX8335_PIC_TDGR_DE_INT 56 */ + 4, /* PNX8335_PIC_IR1_IRQ_INT 57 */ +#endif +}; + +static void pnx833x_timer_dispatch(void) +{ + do_IRQ(mips_cpu_timer_irq); +} + +static void pic_dispatch(void) +{ + unsigned int irq = PNX833X_REGFIELD(PIC_INT_SRC, INT_SRC); + + if ((irq >= 1) && (irq < (PNX833X_PIC_NUM_IRQ))) { + unsigned long priority = PNX833X_PIC_INT_PRIORITY; + PNX833X_PIC_INT_PRIORITY = irq_prio[irq]; + + if (irq == PNX833X_PIC_GPIO_INT) { + unsigned long mask = PNX833X_PIO_INT_STATUS & PNX833X_PIO_INT_ENABLE; + int pin; + while ((pin = ffs(mask & 0xffff))) { + pin -= 1; + do_IRQ(PNX833X_GPIO_IRQ_BASE + pin); + mask &= ~(1 << pin); + } + } else { + do_IRQ(irq + PNX833X_PIC_IRQ_BASE); + } + + PNX833X_PIC_INT_PRIORITY = priority; + } else { + printk(KERN_ERR "plat_irq_dispatch: unexpected irq %u\n", irq); + } +} + +asmlinkage void plat_irq_dispatch(void) +{ + unsigned int pending = read_c0_status() & read_c0_cause(); + + if (pending & STATUSF_IP4) + pic_dispatch(); + else if (pending & STATUSF_IP7) + do_IRQ(PNX833X_TIMER_IRQ); + else + spurious_interrupt(); +} + +static inline void pnx833x_hard_enable_pic_irq(unsigned int irq) +{ + /* Currently we do this by setting IRQ priority to 1. + If priority support is being implemented, 1 should be repalced + by a better value. */ + PNX833X_PIC_INT_REG(irq) = irq_prio[irq]; +} + +static inline void pnx833x_hard_disable_pic_irq(unsigned int irq) +{ + /* Disable IRQ by writing setting it's priority to 0 */ + PNX833X_PIC_INT_REG(irq) = 0; +} + +static int irqflags[PNX833X_PIC_NUM_IRQ]; /* initialized by zeroes */ +#define IRQFLAG_STARTED 1 +#define IRQFLAG_DISABLED 2 + +static DEFINE_SPINLOCK(pnx833x_irq_lock); + +static unsigned int pnx833x_startup_pic_irq(unsigned int irq) +{ + unsigned long flags; + unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + + spin_lock_irqsave(&pnx833x_irq_lock, flags); + + irqflags[pic_irq] = IRQFLAG_STARTED; /* started, not disabled */ + pnx833x_hard_enable_pic_irq(pic_irq); + + spin_unlock_irqrestore(&pnx833x_irq_lock, flags); + return 0; +} + +static void pnx833x_shutdown_pic_irq(unsigned int irq) +{ + unsigned long flags; + unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + + spin_lock_irqsave(&pnx833x_irq_lock, flags); + + irqflags[pic_irq] = 0; /* not started */ + pnx833x_hard_disable_pic_irq(pic_irq); + + spin_unlock_irqrestore(&pnx833x_irq_lock, flags); +} + +static void pnx833x_enable_pic_irq(unsigned int irq) +{ + unsigned long flags; + unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + + spin_lock_irqsave(&pnx833x_irq_lock, flags); + + irqflags[pic_irq] &= ~IRQFLAG_DISABLED; + if (irqflags[pic_irq] == IRQFLAG_STARTED) + pnx833x_hard_enable_pic_irq(pic_irq); + + spin_unlock_irqrestore(&pnx833x_irq_lock, flags); +} + +static void pnx833x_disable_pic_irq(unsigned int irq) +{ + unsigned long flags; + unsigned int pic_irq = irq - PNX833X_PIC_IRQ_BASE; + + spin_lock_irqsave(&pnx833x_irq_lock, flags); + + irqflags[pic_irq] |= IRQFLAG_DISABLED; + pnx833x_hard_disable_pic_irq(pic_irq); + + spin_unlock_irqrestore(&pnx833x_irq_lock, flags); +} + +static void pnx833x_ack_pic_irq(unsigned int irq) +{ +} + +static void pnx833x_end_pic_irq(unsigned int irq) +{ +} + +static DEFINE_SPINLOCK(pnx833x_gpio_pnx833x_irq_lock); + +static unsigned int pnx833x_startup_gpio_irq(unsigned int irq) +{ + int pin = irq - PNX833X_GPIO_IRQ_BASE; + unsigned long flags; + spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); + pnx833x_gpio_enable_irq(pin); + spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); + return 0; +} + +static void pnx833x_enable_gpio_irq(unsigned int irq) +{ + int pin = irq - PNX833X_GPIO_IRQ_BASE; + unsigned long flags; + spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); + pnx833x_gpio_enable_irq(pin); + spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); +} + +static void pnx833x_disable_gpio_irq(unsigned int irq) +{ + int pin = irq - PNX833X_GPIO_IRQ_BASE; + unsigned long flags; + spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); + pnx833x_gpio_disable_irq(pin); + spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); +} + +static void pnx833x_ack_gpio_irq(unsigned int irq) +{ +} + +static void pnx833x_end_gpio_irq(unsigned int irq) +{ + int pin = irq - PNX833X_GPIO_IRQ_BASE; + unsigned long flags; + spin_lock_irqsave(&pnx833x_gpio_pnx833x_irq_lock, flags); + pnx833x_gpio_clear_irq(pin); + spin_unlock_irqrestore(&pnx833x_gpio_pnx833x_irq_lock, flags); +} + +static int pnx833x_set_type_gpio_irq(unsigned int irq, unsigned int flow_type) +{ + int pin = irq - PNX833X_GPIO_IRQ_BASE; + int gpio_mode; + + switch (flow_type) { + case IRQ_TYPE_EDGE_RISING: + gpio_mode = GPIO_INT_EDGE_RISING; + break; + case IRQ_TYPE_EDGE_FALLING: + gpio_mode = GPIO_INT_EDGE_FALLING; + break; + case IRQ_TYPE_EDGE_BOTH: + gpio_mode = GPIO_INT_EDGE_BOTH; + break; + case IRQ_TYPE_LEVEL_HIGH: + gpio_mode = GPIO_INT_LEVEL_HIGH; + break; + case IRQ_TYPE_LEVEL_LOW: + gpio_mode = GPIO_INT_LEVEL_LOW; + break; + default: + gpio_mode = GPIO_INT_NONE; + break; + } + + pnx833x_gpio_setup_irq(gpio_mode, pin); + + return 0; +} + +static struct irq_chip pnx833x_pic_irq_type = { + .typename = "PNX-PIC", + .startup = pnx833x_startup_pic_irq, + .shutdown = pnx833x_shutdown_pic_irq, + .enable = pnx833x_enable_pic_irq, + .disable = pnx833x_disable_pic_irq, + .ack = pnx833x_ack_pic_irq, + .end = pnx833x_end_pic_irq +}; + +static struct irq_chip pnx833x_gpio_irq_type = { + .typename = "PNX-GPIO", + .startup = pnx833x_startup_gpio_irq, + .shutdown = pnx833x_disable_gpio_irq, + .enable = pnx833x_enable_gpio_irq, + .disable = pnx833x_disable_gpio_irq, + .ack = pnx833x_ack_gpio_irq, + .end = pnx833x_end_gpio_irq, + .set_type = pnx833x_set_type_gpio_irq +}; + +void __init arch_init_irq(void) +{ + unsigned int irq; + + /* setup standard internal cpu irqs */ + mips_cpu_irq_init(); + + /* Set IRQ information in irq_desc */ + for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) { + pnx833x_hard_disable_pic_irq(irq); + set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq); + } + + for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++) + set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq); + + /* Set PIC priority limiter register to 0 */ + PNX833X_PIC_INT_PRIORITY = 0; + + /* Setup GPIO IRQ dispatching */ + pnx833x_startup_pic_irq(PNX833X_PIC_GPIO_INT); + + /* Enable PIC IRQs (HWIRQ2) */ + if (cpu_has_vint) + set_vi_handler(4, pic_dispatch); + + write_c0_status(read_c0_status() | IE_IRQ2); +} + +unsigned int __cpuinit get_c0_compare_int(void) +{ + if (cpu_has_vint) + set_vi_handler(cp0_compare_irq, pnx833x_timer_dispatch); + + mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + return mips_cpu_timer_irq; +} + +void __init plat_time_init(void) +{ + /* calculate mips_hpt_frequency based on PNX833X_CLOCK_CPUCP_CTL reg */ + + extern unsigned long mips_hpt_frequency; + unsigned long reg = PNX833X_CLOCK_CPUCP_CTL; + + if (!(PNX833X_BIT(reg, CLOCK_CPUCP_CTL, EXIT_RESET))) { + /* Functional clock is disabled so use crystal frequency */ + mips_hpt_frequency = 25; + } else { +#if defined(CONFIG_SOC_PNX8335) + /* Functional clock is enabled, so get clock multiplier */ + mips_hpt_frequency = 90 + (10 * PNX8335_REGFIELD(CLOCK_PLL_CPU_CTL, FREQ)); +#else + static const unsigned long int freq[4] = {240, 160, 120, 80}; + mips_hpt_frequency = freq[PNX833X_FIELD(reg, CLOCK_CPUCP_CTL, DIV_CLOCK)]; +#endif + } + + printk(KERN_INFO "CPU clock is %ld MHz\n", mips_hpt_frequency); + + mips_hpt_frequency *= 500000; +} + diff --git a/arch/mips/nxp/pnx833x/common/platform.c b/arch/mips/nxp/pnx833x/common/platform.c new file mode 100644 index 0000000..b1ccbcc --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/platform.c @@ -0,0 +1,319 @@ +/* + * platform.c: platform support for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * Based on software written by: + * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. + * + * 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 <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/resource.h> +#include <linux/serial.h> +#include <linux/serial_pnx8xxx.h> +#include <linux/mtd/nand.h> +#include <linux/mtd/partitions.h> + +#ifdef CONFIG_I2C_PNX0105 +/* Until i2c driver available in kernel.*/ +#include <linux/i2c-pnx0105.h> +#endif + +#include <irq.h> +#include <irq-mapping.h> +#include <pnx833x.h> + +static u64 uart_dmamask = DMA_32BIT_MASK; + +static struct resource pnx833x_uart_resources[] = { + [0] = { + .start = PNX833X_UART0_PORTS_START, + .end = PNX833X_UART0_PORTS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX833X_PIC_UART0_INT, + .end = PNX833X_PIC_UART0_INT, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = PNX833X_UART1_PORTS_START, + .end = PNX833X_UART1_PORTS_END, + .flags = IORESOURCE_MEM, + }, + [3] = { + .start = PNX833X_PIC_UART1_INT, + .end = PNX833X_PIC_UART1_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +struct pnx8xxx_port pnx8xxx_ports[] = { + [0] = { + .port = { + .type = PORT_PNX8XXX, + .iotype = UPIO_MEM, + .membase = (void __iomem *)PNX833X_UART0_PORTS_START, + .mapbase = PNX833X_UART0_PORTS_START, + .irq = PNX833X_PIC_UART0_INT, + .uartclk = 3692300, + .fifosize = 16, + .flags = UPF_BOOT_AUTOCONF, + .line = 0, + }, + }, + [1] = { + .port = { + .type = PORT_PNX8XXX, + .iotype = UPIO_MEM, + .membase = (void __iomem *)PNX833X_UART1_PORTS_START, + .mapbase = PNX833X_UART1_PORTS_START, + .irq = PNX833X_PIC_UART1_INT, + .uartclk = 3692300, + .fifosize = 16, + .flags = UPF_BOOT_AUTOCONF, + .line = 1, + }, + }, +}; + +static struct platform_device pnx833x_uart_device = { + .name = "pnx8xxx-uart", + .id = -1, + .dev = { + .dma_mask = &uart_dmamask, + .coherent_dma_mask = DMA_32BIT_MASK, + .platform_data = pnx8xxx_ports, + }, + .num_resources = ARRAY_SIZE(pnx833x_uart_resources), + .resource = pnx833x_uart_resources, +}; + +static u64 ehci_dmamask = DMA_32BIT_MASK; + +static struct resource pnx833x_usb_ehci_resources[] = { + [0] = { + .start = PNX833X_USB_PORTS_START, + .end = PNX833X_USB_PORTS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX833X_PIC_USB_INT, + .end = PNX833X_PIC_USB_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pnx833x_usb_ehci_device = { + .name = "pnx833x-ehci", + .id = -1, + .dev = { + .dma_mask = &ehci_dmamask, + .coherent_dma_mask = DMA_32BIT_MASK, + }, + .num_resources = ARRAY_SIZE(pnx833x_usb_ehci_resources), + .resource = pnx833x_usb_ehci_resources, +}; + +#ifdef CONFIG_I2C_PNX0105 +static struct resource pnx833x_i2c0_resources[] = { + { + .start = PNX833X_I2C0_PORTS_START, + .end = PNX833X_I2C0_PORTS_END, + .flags = IORESOURCE_MEM, + }, + { + .start = PNX833X_PIC_I2C0_INT, + .end = PNX833X_PIC_I2C0_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource pnx833x_i2c1_resources[] = { + { + .start = PNX833X_I2C1_PORTS_START, + .end = PNX833X_I2C1_PORTS_END, + .flags = IORESOURCE_MEM, + }, + { + .start = PNX833X_PIC_I2C1_INT, + .end = PNX833X_PIC_I2C1_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct i2c_pnx0105_dev pnx833x_i2c_dev[] = { + { + .base = PNX833X_I2C0_PORTS_START, + .irq = -1, /* should be PNX833X_PIC_I2C0_INT but polling is faster */ + .clock = 6, /* 0 == 400 kHz, 4 == 100 kHz(Maximum HDMI), 6 = 50kHz(Prefered HDCP) */ + .bus_addr = 0, /* no slave support */ + }, + { + .base = PNX833X_I2C1_PORTS_START, + .irq = -1, /* on high freq, polling is faster */ + /*.irq = PNX833X_PIC_I2C1_INT,*/ + .clock = 4, /* 0 == 400 kHz, 4 == 100 kHz. 100 kHz seems a safe default for now */ + .bus_addr = 0, /* no slave support */ + }, +}; + +static struct platform_device pnx833x_i2c0_device = { + .name = "i2c-pnx0105", + .id = 0, + .dev = { + .platform_data = &pnx833x_i2c_dev[0], + }, + .num_resources = ARRAY_SIZE(pnx833x_i2c0_resources), + .resource = pnx833x_i2c0_resources, +}; + +static struct platform_device pnx833x_i2c1_device = { + .name = "i2c-pnx0105", + .id = 1, + .dev = { + .platform_data = &pnx833x_i2c_dev[1], + }, + .num_resources = ARRAY_SIZE(pnx833x_i2c1_resources), + .resource = pnx833x_i2c1_resources, +}; +#endif + +static u64 ethernet_dmamask = DMA_32BIT_MASK; + +static struct resource pnx833x_ethernet_resources[] = { + [0] = { + .start = PNX8335_IP3902_PORTS_START, + .end = PNX8335_IP3902_PORTS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8335_PIC_ETHERNET_INT, + .end = PNX8335_PIC_ETHERNET_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pnx833x_ethernet_device = { + .name = "ip3902-eth", + .id = -1, + .dev = { + .dma_mask = ðernet_dmamask, + .coherent_dma_mask = DMA_32BIT_MASK, + }, + .num_resources = ARRAY_SIZE(pnx833x_ethernet_resources), + .resource = pnx833x_ethernet_resources, +}; + +static struct resource pnx833x_sata_resources[] = { + [0] = { + .start = PNX8335_SATA_PORTS_START, + .end = PNX8335_SATA_PORTS_END, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = PNX8335_PIC_SATA_INT, + .end = PNX8335_PIC_SATA_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device pnx833x_sata_device = { + .name = "pnx833x-sata", + .id = -1, + .num_resources = ARRAY_SIZE(pnx833x_sata_resources), + .resource = pnx833x_sata_resources, +}; + +static const char *part_probes[] = { + "cmdlinepart", + NULL +}; + +static void +pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *this = mtd->priv; + unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_CLE_MASK)); + else + writeb(cmd, (void __iomem *)(nandaddr + PNX8335_NAND_ALE_MASK)); +} + +static struct platform_nand_data pnx833x_flash_nand_data = { + .chip = { + .chip_delay = 25, + .part_probe_types = part_probes, + }, + .ctrl = { + .cmd_ctrl = pnx833x_flash_nand_cmd_ctrl + } +}; + +/* + * Set start to be the correct address (PNX8335_NAND_BASE with no 0xb!!), + * 12 bytes more seems to be the standard that allows for NAND access. + */ +static struct resource pnx833x_flash_nand_resource = { + .start = PNX8335_NAND_BASE, + .end = PNX8335_NAND_BASE + 12, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device pnx833x_flash_nand = { + .name = "gen_nand", + .id = -1, + .num_resources = 1, + .resource = &pnx833x_flash_nand_resource, + .dev = { + .platform_data = &pnx833x_flash_nand_data, + }, +}; + +static struct platform_device *pnx833x_platform_devices[] __initdata = { + &pnx833x_uart_device, + &pnx833x_usb_ehci_device, +#ifdef CONFIG_I2C_PNX0105 + &pnx833x_i2c0_device, + &pnx833x_i2c1_device, +#endif + &pnx833x_ethernet_device, + &pnx833x_sata_device, + &pnx833x_flash_nand, +}; + +static int __init pnx833x_platform_init(void) +{ + int res; + + res = platform_add_devices(pnx833x_platform_devices, + ARRAY_SIZE(pnx833x_platform_devices)); + + return res; +} + +arch_initcall(pnx833x_platform_init); diff --git a/arch/mips/nxp/pnx833x/common/prom.c b/arch/mips/nxp/pnx833x/common/prom.c new file mode 100644 index 0000000..2a41e8f --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/prom.c @@ -0,0 +1,70 @@ +/* + * prom.c: + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * Based on software written by: + * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. + * + * 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 <linux/init.h> +#include <asm/bootinfo.h> +#include <linux/string.h> + +void __init prom_init_cmdline(void) +{ + int argc = fw_arg0; + char **argv = (char **)fw_arg1; + char *c = &(arcs_cmdline[0]); + int i; + + for (i = 1; i < argc; i++) { + strcpy(c, argv[i]); + c += strlen(argv[i]); + if (i < argc-1) + *c++ = ' '; + } + *c = 0; +} + +char __init *prom_getenv(char *envname) +{ + extern char **prom_envp; + char **env = prom_envp; + int i; + + i = strlen(envname); + + while (*env) { + if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') + return *env + i + 1; + env++; + } + + return 0; +} + +void __init prom_free_prom_memory(void) +{ +} + +char * __init prom_getcmdline(void) +{ + return arcs_cmdline; +} + diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/nxp/pnx833x/common/reset.c new file mode 100644 index 0000000..a9bc9ba --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/reset.c @@ -0,0 +1,45 @@ +/* + * reset.c: reset support for PNX833X. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * Based on software written by: + * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. + * + * 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 <linux/slab.h> +#include <linux/reboot.h> +#include <pnx833x.h> + +void pnx833x_machine_restart(char *command) +{ + PNX833X_RESET_CONTROL_2 = 0; + PNX833X_RESET_CONTROL = 0; +} + +void pnx833x_machine_halt(void) +{ + while (1) + __asm__ __volatile__ ("wait"); + +} + +void pnx833x_machine_power_off(void) +{ + pnx833x_machine_halt(); +} diff --git a/arch/mips/nxp/pnx833x/common/setup.c b/arch/mips/nxp/pnx833x/common/setup.c new file mode 100644 index 0000000..e51fbc4 --- /dev/null +++ b/arch/mips/nxp/pnx833x/common/setup.c @@ -0,0 +1,64 @@ +/* + * setup.c: Setup PNX833X Soc. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * Based on software written by: + * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. + * + * 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 <linux/init.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/pci.h> +#include <asm/reboot.h> +#include <pnx833x.h> +#include <gpio.h> + +extern void pnx833x_board_setup(void); +extern void pnx833x_machine_restart(char *); +extern void pnx833x_machine_halt(void); +extern void pnx833x_machine_power_off(void); + +int __init plat_mem_setup(void) +{ + /* fake pci bus to avoid bounce buffers */ + PCI_DMA_BUS_IS_PHYS = 1; + + /* set mips clock to 320MHz */ +#if defined(CONFIG_SOC_PNX8335) + PNX8335_WRITEFIELD(0x17, CLOCK_PLL_CPU_CTL, FREQ); +#endif + pnx833x_gpio_init(); /* so it will be ready in board_setup() */ + + pnx833x_board_setup(); + + _machine_restart = pnx833x_machine_restart; + _machine_halt = pnx833x_machine_halt; + pm_power_off = pnx833x_machine_power_off; + + /* IO/MEM resources. */ + set_io_port_base(KSEG1); + ioport_resource.start = 0; + ioport_resource.end = ~0; + iomem_resource.start = 0; + iomem_resource.end = ~0; + + return 0; +} diff --git a/arch/mips/nxp/pnx833x/stb22x/Makefile b/arch/mips/nxp/pnx833x/stb22x/Makefile new file mode 100644 index 0000000..f81c580 --- /dev/null +++ b/arch/mips/nxp/pnx833x/stb22x/Makefile @@ -0,0 +1,3 @@ +lib-y := board.o + +EXTRA_CFLAGS += -Werror diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/nxp/pnx833x/stb22x/board.c new file mode 100644 index 0000000..90cc604 --- /dev/null +++ b/arch/mips/nxp/pnx833x/stb22x/board.c @@ -0,0 +1,133 @@ +/* + * board.c: STB225 board support. + * + * Copyright 2008 NXP Semiconductors + * Chris Steel <chris.steel@nxp.com> + * Daniel Laird <daniel.j.laird@nxp.com> + * + * Based on software written by: + * Nikita Youshchenko <yoush@debian.org>, based on PNX8550 code. + * + * 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 <linux/init.h> +#include <asm/bootinfo.h> +#include <linux/mm.h> +#include <pnx833x.h> +#include <gpio.h> + +/* endianess twiddlers */ +#define PNX8335_DEBUG0 0x4400 +#define PNX8335_DEBUG1 0x4404 +#define PNX8335_DEBUG2 0x4408 +#define PNX8335_DEBUG3 0x440c +#define PNX8335_DEBUG4 0x4410 +#define PNX8335_DEBUG5 0x4414 +#define PNX8335_DEBUG6 0x4418 +#define PNX8335_DEBUG7 0x441c + +int prom_argc; +char **prom_argv = 0, **prom_envp = 0; + +extern void prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "NXP STB22x"; +} + +static inline unsigned long env_or_default(char *env, unsigned long dfl) +{ + char *str = prom_getenv(env); + return str ? simple_strtol(str, 0, 0) : dfl; +} + +void __init prom_init(void) +{ + unsigned long memsize; + + prom_argc = fw_arg0; + prom_argv = (char **)fw_arg1; + prom_envp = (char **)fw_arg2; + + prom_init_cmdline(); + + memsize = env_or_default("memsize", 0x02000000); + add_memory_region(0, memsize, BOOT_MEM_RAM); +} + +void __init pnx833x_board_setup(void) +{ + pnx833x_gpio_select_function_alt(4); + pnx833x_gpio_select_output(4); + pnx833x_gpio_select_function_alt(5); + pnx833x_gpio_select_input(5); + pnx833x_gpio_select_function_alt(6); + pnx833x_gpio_select_input(6); + pnx833x_gpio_select_function_alt(7); + pnx833x_gpio_select_output(7); + + pnx833x_gpio_select_function_alt(25); + pnx833x_gpio_select_function_alt(26); + + pnx833x_gpio_select_function_alt(27); + pnx833x_gpio_select_function_alt(28); + pnx833x_gpio_select_function_alt(29); + pnx833x_gpio_select_function_alt(30); + pnx833x_gpio_select_function_alt(31); + pnx833x_gpio_select_function_alt(32); + pnx833x_gpio_select_function_alt(33); + +#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) + /* Setup MIU for NAND access on CS0... + * + * (it seems that we must also configure CS1 for reliable operation, + * otherwise the first read ID command will fail if it's read as 4 bytes + * but pass if it's read as 1 word.) + */ + + /* Setup MIU CS0 & CS1 timing */ + PNX833X_MIU_SEL0 = 0; + PNX833X_MIU_SEL1 = 0; + PNX833X_MIU_SEL0_TIMING = 0x50003081; + PNX833X_MIU_SEL1_TIMING = 0x50003081; + + /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */ + pnx833x_gpio_select_function_alt(0); + + /* Setup GPIO 04 to input NAND read/busy signal */ + pnx833x_gpio_select_function_io(4); + pnx833x_gpio_select_input(4); + + /* Setup GPIO 05 to disable NAND write protect */ + pnx833x_gpio_select_function_io(5); + pnx833x_gpio_select_output(5); + pnx833x_gpio_write(1, 5); + +#elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE) + + /* Set up MIU for 16-bit NOR access on CS0 and CS1... */ + + /* Setup MIU CS0 & CS1 timing */ + PNX833X_MIU_SEL0 = 1; + PNX833X_MIU_SEL1 = 1; + PNX833X_MIU_SEL0_TIMING = 0x6A08D082; + PNX833X_MIU_SEL1_TIMING = 0x6A08D082; + + /* Setup GPIO 00 for use as MIU CS1 (CS0 is not multiplexed, so does not need this) */ + pnx833x_gpio_select_function_alt(0); +#endif +} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index b188624..e8a97f59e 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -13,7 +13,7 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o obj-$(CONFIG_SOC_TX3927) += ops-tx3927.o obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o pci-vr41xx.o -obj-$(CONFIG_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o +obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index 846eae9..fba5aad 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c @@ -30,7 +30,7 @@ #include <asm/bootinfo.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> #define EMMA2RH_PCI_HOST_SLOT 0x09 #define EMMA2RH_USB_SLOT 0x03 diff --git a/arch/mips/pci/fixup-rc32434.c b/arch/mips/pci/fixup-rc32434.c index 75b90dc..3d86823 100644 --- a/arch/mips/pci/fixup-rc32434.c +++ b/arch/mips/pci/fixup-rc32434.c @@ -30,6 +30,7 @@ #include <linux/init.h> #include <asm/mach-rc32434/rc32434.h> +#include <asm/mach-rc32434/irq.h> static int __devinitdata irq_map[2][12] = { {0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1}, diff --git a/arch/mips/pci/ops-emma2rh.c b/arch/mips/pci/ops-emma2rh.c index d31bfc6..5947a70 100644 --- a/arch/mips/pci/ops-emma2rh.c +++ b/arch/mips/pci/ops-emma2rh.c @@ -30,7 +30,7 @@ #include <asm/addrspace.h> #include <asm/debug.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> #define RTABORT (0x1<<9) #define RMABORT (0x1<<10) diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c index 772e283..2df4190 100644 --- a/arch/mips/pci/pci-emma2rh.c +++ b/arch/mips/pci/pci-emma2rh.c @@ -30,7 +30,7 @@ #include <asm/bootinfo.h> -#include <asm/emma2rh/emma2rh.h> +#include <asm/emma/emma2rh.h> static struct resource pci_io_resource = { .name = "pci IO space", diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 31619c6..2f22d71 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -280,7 +280,7 @@ static int __init plat_setup_devices(void) { /* Look for the CF card reader */ if (!readl(IDT434_REG_BASE + DEV1MASK)) - rb532_devs[1] = NULL; + rb532_devs[2] = NULL; /* disable cf_slot0 at index 2 */ else { cf_slot0_res[0].start = readl(IDT434_REG_BASE + DEV1BASE); diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index 76a7fd9..70c4a67 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c @@ -310,6 +310,10 @@ int __init rb532_gpio_init(void) return -ENXIO; } + /* Set the interrupt status and level for the CF pin */ + rb532_gpio_set_int_level(&rb532_gpio_chip->chip, CF_GPIO_NUM, 1); + rb532_gpio_set_int_status(&rb532_gpio_chip->chip, CF_GPIO_NUM, 0); + return 0; } arch_initcall(rb532_gpio_init); diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index f6d9bf4..f8b18af 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -12,20 +12,11 @@ #include <linux/types.h> #include <linux/init.h> #include <linux/kernel_stat.h> -#include <linux/signal.h> -#include <linux/sched.h> #include <linux/interrupt.h> -#include <linux/irq.h> -#include <asm/mipsregs.h> -#include <asm/addrspace.h> #include <asm/irq_cpu.h> -#include <asm/sgi/ioc.h> #include <asm/sgi/hpc3.h> #include <asm/sgi/ip22.h> -#include <asm/time.h> - -/* #define DEBUG_SGINT */ /* So far nothing hangs here */ #undef USE_LIO3_IRQ @@ -68,7 +59,7 @@ static void enable_local1_irq(unsigned int irq) sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); } -void disable_local1_irq(unsigned int irq) +static void disable_local1_irq(unsigned int irq) { sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); } @@ -87,7 +78,7 @@ static void enable_local2_irq(unsigned int irq) sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); } -void disable_local2_irq(unsigned int irq) +static void disable_local2_irq(unsigned int irq) { sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); if (!sgint->cmeimask0) @@ -108,7 +99,7 @@ static void enable_local3_irq(unsigned int irq) sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); } -void disable_local3_irq(unsigned int irq) +static void disable_local3_irq(unsigned int irq) { sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); if (!sgint->cmeimask1) @@ -344,6 +335,6 @@ void __init arch_init_irq(void) #ifdef CONFIG_EISA if (ip22_is_fullhouse()) /* Only Indigo-2 has EISA stuff */ - ip22_eisa_init(); + ip22_eisa_init(); #endif } diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 17052db..226e8bb 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -46,9 +46,10 @@ config TOSHIBA_RBTX4938 support this machine type config TOSHIBA_RBTX4939 - bool "Toshiba RBTX4939 bobard" + bool "Toshiba RBTX4939 board" depends on MACH_TX49XX select SOC_TX4939 + select TXX9_7SEGLED help This Toshiba board is based on the TX4939 processor. Say Y here to support this machine type @@ -86,6 +87,9 @@ config SOC_TX4939 select HW_HAS_PCI select PCI_TX4927 +config TXX9_7SEGLED + bool + config TOSHIBA_FPCIB0 bool "FPCIB0 Backplane Support" depends on PCI && MACH_TXX9 diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c new file mode 100644 index 0000000..727ab21 --- /dev/null +++ b/arch/mips/txx9/generic/7segled.c @@ -0,0 +1,112 @@ +/* + * 7 Segment LED routines + * Based on RBTX49xx patch from CELF patch archive. + * + * 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. + * + * (C) Copyright TOSHIBA CORPORATION 2005-2007 + * All Rights Reserved. + */ +#include <linux/sysdev.h> +#include <linux/slab.h> +#include <linux/map_to_7segment.h> +#include <asm/txx9/generic.h> + +static unsigned int tx_7segled_num; +static void (*tx_7segled_putc)(unsigned int pos, unsigned char val); + +void __init txx9_7segled_init(unsigned int num, + void (*putc)(unsigned int pos, unsigned char val)) +{ + tx_7segled_num = num; + tx_7segled_putc = putc; +} + +static SEG7_CONVERSION_MAP(txx9_seg7map, MAP_ASCII7SEG_ALPHANUM_LC); + +int txx9_7segled_putc(unsigned int pos, char c) +{ + if (pos >= tx_7segled_num) + return -EINVAL; + c = map_to_seg7(&txx9_seg7map, c); + if (c < 0) + return c; + tx_7segled_putc(pos, c); + return 0; +} + +static ssize_t ascii_store(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + unsigned int ch = dev->id; + txx9_7segled_putc(ch, buf[0]); + return size; +} + +static ssize_t raw_store(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, size_t size) +{ + unsigned int ch = dev->id; + tx_7segled_putc(ch, buf[0]); + return size; +} + +static SYSDEV_ATTR(ascii, 0200, NULL, ascii_store); +static SYSDEV_ATTR(raw, 0200, NULL, raw_store); + +static ssize_t map_seg7_show(struct sysdev_class *class, char *buf) +{ + memcpy(buf, &txx9_seg7map, sizeof(txx9_seg7map)); + return sizeof(txx9_seg7map); +} + +static ssize_t map_seg7_store(struct sysdev_class *class, + const char *buf, size_t size) +{ + if (size != sizeof(txx9_seg7map)) + return -EINVAL; + memcpy(&txx9_seg7map, buf, size); + return size; +} + +static SYSDEV_CLASS_ATTR(map_seg7, 0600, map_seg7_show, map_seg7_store); + +static struct sysdev_class tx_7segled_sysdev_class = { + .name = "7segled", +}; + +static int __init tx_7segled_init_sysfs(void) +{ + int error, i; + if (!tx_7segled_num) + return -ENODEV; + error = sysdev_class_register(&tx_7segled_sysdev_class); + if (error) + return error; + error = sysdev_class_create_file(&tx_7segled_sysdev_class, + &attr_map_seg7); + if (error) + return error; + for (i = 0; i < tx_7segled_num; i++) { + struct sys_device *dev; + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) { + error = -ENODEV; + break; + } + dev->id = i; + dev->cls = &tx_7segled_sysdev_class; + error = sysdev_register(dev); + if (!error) { + sysdev_create_file(dev, &attr_ascii); + sysdev_create_file(dev, &attr_raw); + } + } + return error; +} + +device_initcall(tx_7segled_init_sysfs); diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile index 0030d23..f2579ce 100644 --- a/arch/mips/txx9/generic/Makefile +++ b/arch/mips/txx9/generic/Makefile @@ -10,5 +10,6 @@ obj-$(CONFIG_SOC_TX4938) += mem_tx4927.o setup_tx4938.o irq_tx4938.o obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o obj-$(CONFIG_SPI) += spi_eeprom.o +obj-$(CONFIG_TXX9_7SEGLED) += 7segled.o EXTRA_CFLAGS += -Werror diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 5526375..a13a08b 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -156,11 +156,23 @@ static struct txx9_board_vec *__init find_board_byname(const char *name) static void __init prom_init_cmdline(void) { - int argc = (int)fw_arg0; - int *argv32 = (int *)fw_arg1; + int argc; + int *argv32; int i; /* Always ignore the "-c" at argv[0] */ char builtin[CL_SIZE]; + if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) { + /* + * argc is not a valid number, or argv32 is not a valid + * pointer + */ + argc = 0; + argv32 = NULL; + } else { + argc = (int)fw_arg0; + argv32 = (int *)fw_arg1; + } + /* ignore all built-in args if any f/w args given */ /* * But if built-in strings was started with '+', append them @@ -414,10 +426,12 @@ char * __init prom_getcmdline(void) const char *__init prom_getenv(const char *name) { - const s32 *str = (const s32 *)fw_arg2; + const s32 *str; - if (!str) + if (fw_arg2 < CKSEG0) return NULL; + + str = (const s32 *)fw_arg2; /* YAMON style ("name", "value" pairs) */ while (str[0] && str[1]) { if (!strcmp((const char *)(unsigned long)str[0], name)) @@ -622,6 +636,21 @@ unsigned long (*__swizzle_addr_b)(unsigned long port) = __swizzle_addr_none; EXPORT_SYMBOL(__swizzle_addr_b); #endif +#ifdef NEEDS_TXX9_IOSWABW +static u16 ioswabw_default(volatile u16 *a, u16 x) +{ + return le16_to_cpu(x); +} +static u16 __mem_ioswabw_default(volatile u16 *a, u16 x) +{ + return x; +} +u16 (*ioswabw)(volatile u16 *a, u16 x) = ioswabw_default; +EXPORT_SYMBOL(ioswabw); +u16 (*__mem_ioswabw)(volatile u16 *a, u16 x) = __mem_ioswabw_default; +EXPORT_SYMBOL(__mem_ioswabw); +#endif + void __init txx9_physmap_flash_init(int no, unsigned long addr, unsigned long size, const struct physmap_flash_data *pdata) diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 9855d7b..6daee9b 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -14,6 +14,8 @@ #include <linux/types.h> #include <linux/platform_device.h> #include <linux/leds.h> +#include <linux/interrupt.h> +#include <linux/smc91x.h> #include <asm/reboot.h> #include <asm/txx9/generic.h> #include <asm/txx9/pci.h> @@ -33,6 +35,21 @@ static void __init rbtx4939_time_init(void) tx4939_time_init(0); } +#if defined(__BIG_ENDIAN) && \ + (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) +#define HAVE_RBTX4939_IOSWAB +#define IS_CE1_ADDR(addr) \ + ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1)) +static u16 rbtx4939_ioswabw(volatile u16 *a, u16 x) +{ + return IS_CE1_ADDR(a) ? x : le16_to_cpu(x); +} +static u16 rbtx4939_mem_ioswabw(volatile u16 *a, u16 x) +{ + return !IS_CE1_ADDR(a) ? x : le16_to_cpu(x); +} +#endif /* __BIG_ENDIAN && CONFIG_SMC91X */ + static void __init rbtx4939_pci_setup(void) { #ifdef CONFIG_PCI @@ -239,6 +256,32 @@ static inline void rbtx4939_led_setup(void) } #endif +static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) +{ +#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) + unsigned long flags; + local_irq_save(flags); + /* bit7: reserved for LED class */ + led_val[pos] = (led_val[pos] & 0x80) | (val & 0x7f); + val = led_val[pos]; + local_irq_restore(flags); +#endif + writeb(val, rbtx4939_7seg_addr(pos / 4, pos % 4)); +} + +static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val) +{ + /* convert from map_to_seg7() notation */ + val = (val & 0x88) | + ((val & 0x40) >> 6) | + ((val & 0x20) >> 4) | + ((val & 0x10) >> 2) | + ((val & 0x04) << 2) | + ((val & 0x02) << 4) | + ((val & 0x01) << 6); + __rbtx4939_7segled_putc(pos, val); +} + static void __init rbtx4939_arch_init(void) { rbtx4939_pci_setup(); @@ -246,6 +289,22 @@ static void __init rbtx4939_arch_init(void) static void __init rbtx4939_device_init(void) { + unsigned long smc_addr = RBTX4939_ETHER_ADDR - IO_BASE; + struct resource smc_res[] = { + { + .start = smc_addr, + .end = smc_addr + 0x10 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = RBTX4939_IRQ_ETHER, + /* override default irq flag defined in smc91x.h */ + .flags = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, + }, + }; + struct smc91x_platdata smc_pdata = { + .flags = SMC91X_USE_16BIT, + }; + struct platform_device *pdev; #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) int i, j; unsigned char ethaddr[2][6]; @@ -262,6 +321,12 @@ static void __init rbtx4939_device_init(void) } tx4939_ethaddr_init(ethaddr[0], ethaddr[1]); #endif + pdev = platform_device_alloc("smc91x", -1); + if (!pdev || + platform_device_add_resources(pdev, smc_res, ARRAY_SIZE(smc_res)) || + platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) || + platform_device_add(pdev)) + platform_device_put(pdev); rbtx4939_led_setup(); tx4939_wdt_init(); tx4939_ata_init(); @@ -269,6 +334,8 @@ static void __init rbtx4939_device_init(void) static void __init rbtx4939_setup(void) { + int i; + rbtx4939_ebusc_setup(); /* always enable ATA0 */ txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE); @@ -276,9 +343,16 @@ static void __init rbtx4939_setup(void) if (txx9_master_clock == 0) txx9_master_clock = 20000000; tx4939_setup(); +#ifdef HAVE_RBTX4939_IOSWAB + ioswabw = rbtx4939_ioswabw; + __mem_ioswabw = rbtx4939_mem_ioswabw; +#endif _machine_restart = rbtx4939_machine_restart; + txx9_7segled_init(RBTX4939_MAX_7SEGLEDS, rbtx4939_7segled_putc); + for (i = 0; i < RBTX4939_MAX_7SEGLEDS; i++) + txx9_7segled_putc(i, '-'); pr_info("RBTX4939 (Rev %02x) --- FPGA(Rev %02x) DIPSW:%02x,%02x\n", readb(rbtx4939_board_rev_addr), readb(rbtx4939_ioc_rev_addr), readb(rbtx4939_udipsw_addr), readb(rbtx4939_bdipsw_addr)); diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 5b15278..525c13a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -108,8 +108,7 @@ config ARCH_NO_VIRT_TO_BUS config PPC bool default y - select HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE + select HAVE_FUNCTION_TRACER select ARCH_WANT_OPTIONAL_GPIOLIB select HAVE_IDE select HAVE_IOREMAP_PROT diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 24dd1a3..1f06670 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -122,7 +122,7 @@ KBUILD_CFLAGS += -mcpu=powerpc endif # Work around a gcc code-gen bug with -fno-omit-frame-pointer. -ifeq ($(CONFIG_FTRACE),y) +ifeq ($(CONFIG_FUNCTION_TRACER),y) KBUILD_CFLAGS += -mno-sched-epilog endif diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h index de92132..b298f7a 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -1,7 +1,7 @@ #ifndef _ASM_POWERPC_FTRACE #define _ASM_POWERPC_FTRACE -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_ADDR ((long)(_mcount)) #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index fdb5825..92673b4 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -12,7 +12,7 @@ CFLAGS_prom_init.o += -fPIC CFLAGS_btext.o += -fPIC endif -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code CFLAGS_REMOVE_cputable.o = -pg -mno-sched-epilog CFLAGS_REMOVE_prom_init.o = -pg -mno-sched-epilog diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 1cbbf70..7ecc0d1 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -1158,7 +1158,7 @@ machine_check_in_rtas: #endif /* CONFIG_PPC_RTAS */ -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE _GLOBAL(mcount) _GLOBAL(_mcount) diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index fd8b4ba..e6d5284 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -884,7 +884,7 @@ _GLOBAL(enter_prom) mtlr r0 blr -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE _GLOBAL(mcount) _GLOBAL(_mcount) diff --git a/arch/powerpc/kernel/ftrace.c b/arch/powerpc/kernel/ftrace.c index 3855ceb..f4b006e 100644 --- a/arch/powerpc/kernel/ftrace.c +++ b/arch/powerpc/kernel/ftrace.c @@ -28,17 +28,17 @@ static unsigned int ftrace_nop = 0x60000000; #endif -static unsigned int notrace ftrace_calc_offset(long ip, long addr) +static unsigned int ftrace_calc_offset(long ip, long addr) { return (int)(addr - ip); } -notrace unsigned char *ftrace_nop_replace(void) +unsigned char *ftrace_nop_replace(void) { return (char *)&ftrace_nop; } -notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) { static unsigned int op; @@ -68,7 +68,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) # define _ASM_PTR " .long " #endif -notrace int +int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { @@ -113,7 +113,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, return faulted; } -notrace int ftrace_update_ftrace_func(ftrace_func_t func) +int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); unsigned char old[MCOUNT_INSN_SIZE], *new; @@ -126,23 +126,6 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } -notrace int ftrace_mcount_set(unsigned long *data) -{ - unsigned long ip = (long)(&mcount_call); - unsigned long *addr = data; - unsigned char old[MCOUNT_INSN_SIZE], *new; - - /* - * Replace the mcount stub with a pointer to the - * ip recorder function. - */ - memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); - new = ftrace_call_replace(ip, *addr); - *addr = ftrace_modify_code(ip, old, new); - - return 0; -} - int __init ftrace_dyn_arch_init(void *data) { /* This is running in kstop_machine */ diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 8edc235..260089d 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -68,7 +68,7 @@ EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); #endif -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER EXPORT_SYMBOL(_mcount); #endif diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile index be60d64..50f1693 100644 --- a/arch/powerpc/platforms/powermac/Makefile +++ b/arch/powerpc/platforms/powermac/Makefile @@ -1,6 +1,6 @@ CFLAGS_bootx_init.o += -fPIC -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER # Do not trace early boot code CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog endif diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 70b7645..8116a33 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -241,19 +241,17 @@ config PACK_STACK Say Y if you are unsure. config SMALL_STACK - bool "Use 4kb/8kb for kernel stack instead of 8kb/16kb" - depends on PACK_STACK && !LOCKDEP + bool "Use 8kb for kernel stack instead of 16kb" + depends on PACK_STACK && 64BIT && !LOCKDEP help If you say Y here and the compiler supports the -mkernel-backchain - option the kernel will use a smaller kernel stack size. For 31 bit - the reduced size is 4kb instead of 8kb and for 64 bit it is 8kb - instead of 16kb. This allows to run more thread on a system and - reduces the pressure on the memory management for higher order - page allocations. + option the kernel will use a smaller kernel stack size. The reduced + size is 8kb instead of 16kb. This allows to run more threads on a + system and reduces the pressure on the memory management for higher + order page allocations. Say N if you are unsure. - config CHECK_STACK bool "Detect kernel stack overflow" help @@ -384,7 +382,7 @@ config IPL choice prompt "IPL method generated into head.S" depends on IPL - default IPL_TAPE + default IPL_VM help Select "tape" if you want to IPL the image from a Tape. diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index a7f8979..a06a47c 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -424,7 +424,7 @@ out: */ int appldata_register_ops(struct appldata_ops *ops) { - if ((ops->size > APPLDATA_MAX_REC_SIZE) || (ops->size < 0)) + if (ops->size > APPLDATA_MAX_REC_SIZE) return -EINVAL; ops->ctl_table = kzalloc(4 * sizeof(struct ctl_table), GFP_KERNEL); diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h index 1461002..c13568b 100644 --- a/arch/s390/include/asm/kvm_virtio.h +++ b/arch/s390/include/asm/kvm_virtio.h @@ -52,7 +52,7 @@ struct kvm_vqconfig { #ifdef __KERNEL__ /* early virtio console setup */ -#ifdef CONFIG_VIRTIO_CONSOLE +#ifdef CONFIG_S390_GUEST extern void s390_virtio_console_init(void); #else static inline void s390_virtio_console_init(void) diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 5dd5e7b..d2b4ff8 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h @@ -7,7 +7,8 @@ typedef struct { unsigned long asce_bits; unsigned long asce_limit; int noexec; - int pgstes; + int has_pgste; /* The mmu context has extended page tables */ + int alloc_pgste; /* cloned contexts will have extended page tables */ } mm_context_t; #endif diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h index 4c2fbf4..28ec870 100644 --- a/arch/s390/include/asm/mmu_context.h +++ b/arch/s390/include/asm/mmu_context.h @@ -20,12 +20,25 @@ static inline int init_new_context(struct task_struct *tsk, #ifdef CONFIG_64BIT mm->context.asce_bits |= _ASCE_TYPE_REGION3; #endif - if (current->mm->context.pgstes) { + if (current->mm->context.alloc_pgste) { + /* + * alloc_pgste indicates, that any NEW context will be created + * with extended page tables. The old context is unchanged. The + * page table allocation and the page table operations will + * look at has_pgste to distinguish normal and extended page + * tables. The only way to create extended page tables is to + * set alloc_pgste and then create a new context (e.g. dup_mm). + * The page table allocation is called after init_new_context + * and if has_pgste is set, it will create extended page + * tables. + */ mm->context.noexec = 0; - mm->context.pgstes = 1; + mm->context.has_pgste = 1; + mm->context.alloc_pgste = 1; } else { mm->context.noexec = s390_noexec; - mm->context.pgstes = 0; + mm->context.has_pgste = 0; + mm->context.alloc_pgste = 0; } mm->context.asce_limit = STACK_TOP_MAX; crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 1a928f8..7fc7613 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -679,7 +679,7 @@ static inline void pmd_clear(pmd_t *pmd) static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - if (mm->context.pgstes) + if (mm->context.has_pgste) ptep_rcp_copy(ptep); pte_val(*ptep) = _PAGE_TYPE_EMPTY; if (mm->context.noexec) @@ -763,7 +763,7 @@ static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm, struct page *page; unsigned int skey; - if (!mm->context.pgstes) + if (!mm->context.has_pgste) return -EINVAL; rcp_lock(ptep); pgste = (unsigned long *) (ptep + PTRS_PER_PTE); @@ -794,7 +794,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, int young; unsigned long *pgste; - if (!vma->vm_mm->context.pgstes) + if (!vma->vm_mm->context.has_pgste) return 0; physpage = pte_val(*ptep) & PAGE_MASK; pgste = (unsigned long *) (ptep + PTRS_PER_PTE); @@ -844,7 +844,7 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep) static inline void ptep_invalidate(struct mm_struct *mm, unsigned long address, pte_t *ptep) { - if (mm->context.pgstes) { + if (mm->context.has_pgste) { rcp_lock(ptep); __ptep_ipte(address, ptep); ptep_rcp_copy(ptep); diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index de3fad6..c1eaf96 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -15,13 +15,8 @@ * Size of kernel stack for each process */ #ifndef __s390x__ -#ifndef __SMALL_STACK #define THREAD_ORDER 1 #define ASYNC_ORDER 1 -#else -#define THREAD_ORDER 0 -#define ASYNC_ORDER 0 -#endif #else /* __s390x__ */ #ifndef __SMALL_STACK #define THREAD_ORDER 2 diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 9e8b1f9..b559568 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1119,9 +1119,7 @@ out: return rc; } -static ssize_t __ref rescan_store(struct sys_device *dev, - struct sysdev_attribute *attr, - const char *buf, +static ssize_t __ref rescan_store(struct sysdev_class *class, const char *buf, size_t count) { int rc; @@ -1129,12 +1127,10 @@ static ssize_t __ref rescan_store(struct sys_device *dev, rc = smp_rescan_cpus(); return rc ? rc : count; } -static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store); +static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store); #endif /* CONFIG_HOTPLUG_CPU */ -static ssize_t dispatching_show(struct sys_device *dev, - struct sysdev_attribute *attr, - char *buf) +static ssize_t dispatching_show(struct sysdev_class *class, char *buf) { ssize_t count; @@ -1144,9 +1140,8 @@ static ssize_t dispatching_show(struct sys_device *dev, return count; } -static ssize_t dispatching_store(struct sys_device *dev, - struct sysdev_attribute *attr, - const char *buf, size_t count) +static ssize_t dispatching_store(struct sysdev_class *dev, const char *buf, + size_t count) { int val, rc; char delim; @@ -1168,7 +1163,8 @@ out: put_online_cpus(); return rc ? rc : count; } -static SYSDEV_ATTR(dispatching, 0644, dispatching_show, dispatching_store); +static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show, + dispatching_store); static int __init topology_init(void) { @@ -1178,13 +1174,11 @@ static int __init topology_init(void) register_cpu_notifier(&smp_cpu_nb); #ifdef CONFIG_HOTPLUG_CPU - rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, - &attr_rescan.attr); + rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan); if (rc) return rc; #endif - rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, - &attr_dispatching.attr); + rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching); if (rc) return rc; for_each_present_cpu(cpu) { diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 3d98ba8..ef3635b 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -169,7 +169,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) unsigned long *table; unsigned long bits; - bits = (mm->context.noexec || mm->context.pgstes) ? 3UL : 1UL; + bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; spin_lock(&mm->page_table_lock); page = NULL; if (!list_empty(&mm->context.pgtable_list)) { @@ -186,7 +186,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) pgtable_page_ctor(page); page->flags &= ~FRAG_MASK; table = (unsigned long *) page_to_phys(page); - if (mm->context.pgstes) + if (mm->context.has_pgste) clear_table_pgstes(table); else clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); @@ -210,7 +210,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) struct page *page; unsigned long bits; - bits = (mm->context.noexec || mm->context.pgstes) ? 3UL : 1UL; + bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); page = pfn_to_page(__pa(table) >> PAGE_SHIFT); spin_lock(&mm->page_table_lock); @@ -257,7 +257,7 @@ int s390_enable_sie(void) struct mm_struct *mm, *old_mm; /* Do we have pgstes? if yes, we are done */ - if (tsk->mm->context.pgstes) + if (tsk->mm->context.has_pgste) return 0; /* lets check if we are allowed to replace the mm */ @@ -269,14 +269,14 @@ int s390_enable_sie(void) } task_unlock(tsk); - /* we copy the mm with pgstes enabled */ - tsk->mm->context.pgstes = 1; + /* we copy the mm and let dup_mm create the page tables with_pgstes */ + tsk->mm->context.alloc_pgste = 1; mm = dup_mm(tsk); - tsk->mm->context.pgstes = 0; + tsk->mm->context.alloc_pgste = 0; if (!mm) return -ENOMEM; - /* Now lets check again if somebody attached ptrace etc */ + /* Now lets check again if something happened */ task_lock(tsk); if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || tsk->mm != tsk->active_mm || tsk->mm->ioctx_list) { diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 035b15a..3b96e70 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -11,8 +11,7 @@ config SPARC config SPARC64 bool default y - select HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE + select HAVE_FUNCTION_TRACER select HAVE_IDE select HAVE_LMB select HAVE_ARCH_KGDB diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index d6d32d1..c40515c 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -33,7 +33,7 @@ config DEBUG_PAGEALLOC config MCOUNT bool - depends on STACK_DEBUG || FTRACE + depends on STACK_DEBUG || FUNCTION_TRACER default y config FRAME_POINTER diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index c0b8009..b3e0b98 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -5,6 +5,8 @@ EXTRA_AFLAGS := -ansi EXTRA_CFLAGS := -Werror +CFLAGS_REMOVE_ftrace.o = -pg + extra-y := head.o init_task.o vmlinux.lds obj-y := process.o setup.o cpu.o idprom.o reboot.o \ diff --git a/arch/sparc64/kernel/ftrace.c b/arch/sparc64/kernel/ftrace.c index 4298d0a..d0218e7 100644 --- a/arch/sparc64/kernel/ftrace.c +++ b/arch/sparc64/kernel/ftrace.c @@ -9,12 +9,12 @@ static const u32 ftrace_nop = 0x01000000; -notrace unsigned char *ftrace_nop_replace(void) +unsigned char *ftrace_nop_replace(void) { return (char *)&ftrace_nop; } -notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) { static u32 call; s32 off; @@ -25,7 +25,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) return (unsigned char *) &call; } -notrace int +int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { @@ -59,7 +59,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, return faulted; } -notrace int ftrace_update_ftrace_func(ftrace_func_t func) +int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); unsigned char old[MCOUNT_INSN_SIZE], *new; @@ -69,24 +69,6 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func) return ftrace_modify_code(ip, old, new); } -notrace int ftrace_mcount_set(unsigned long *data) -{ - unsigned long ip = (long)(&mcount_call); - unsigned long *addr = data; - unsigned char old[MCOUNT_INSN_SIZE], *new; - - /* - * Replace the mcount stub with a pointer to the - * ip recorder function. - */ - memcpy(old, &mcount_call, MCOUNT_INSN_SIZE); - new = ftrace_call_replace(ip, *addr); - *addr = ftrace_modify_code(ip, old, new); - - return 0; -} - - int __init ftrace_dyn_arch_init(void *data) { ftrace_mcount_set(data); diff --git a/arch/sparc64/lib/mcount.S b/arch/sparc64/lib/mcount.S index fad90dd..7ce9c65 100644 --- a/arch/sparc64/lib/mcount.S +++ b/arch/sparc64/lib/mcount.S @@ -93,7 +93,7 @@ mcount: nop 1: #endif -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE mov %o7, %o0 .globl mcount_call @@ -119,7 +119,7 @@ mcount_call: .size _mcount,.-_mcount .size mcount,.-mcount -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER .globl ftrace_stub .type ftrace_stub,#function ftrace_stub: diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 350bee1..d11d7b5 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -28,7 +28,7 @@ config X86 select HAVE_KRETPROBES select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE + select HAVE_FUNCTION_TRACER select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER select HAVE_ARCH_TRACEHOOK diff --git a/arch/x86/boot/compressed/.gitignore b/arch/x86/boot/compressed/.gitignore index be0ed06..63eff3b 100644 --- a/arch/x86/boot/compressed/.gitignore +++ b/arch/x86/boot/compressed/.gitignore @@ -1 +1,3 @@ relocs +vmlinux.bin.all +vmlinux.relocs diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 4a5397b..7f225a4 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -255,9 +255,11 @@ static inline unsigned long dma_alloc_coherent_mask(struct device *dev, static inline gfp_t dma_alloc_coherent_gfp_flags(struct device *dev, gfp_t gfp) { -#ifdef CONFIG_X86_64 unsigned long dma_mask = dma_alloc_coherent_mask(dev, gfp); + if (dma_mask <= DMA_24BIT_MASK) + gfp |= GFP_DMA; +#ifdef CONFIG_X86_64 if (dma_mask <= DMA_32BIT_MASK && !(gfp & GFP_DMA)) gfp |= GFP_DMA32; #endif diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 47f7e65..9e8bc29 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -1,7 +1,7 @@ #ifndef _ASM_X86_FTRACE_H #define _ASM_X86_FTRACE_H -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_ADDR ((long)(mcount)) #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ @@ -19,6 +19,6 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) } #endif -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ #endif /* _ASM_X86_FTRACE_H */ diff --git a/arch/x86/include/asm/iommu.h b/arch/x86/include/asm/iommu.h index 98e28ea..e4a552d 100644 --- a/arch/x86/include/asm/iommu.h +++ b/arch/x86/include/asm/iommu.h @@ -7,7 +7,6 @@ extern struct dma_mapping_ops nommu_dma_ops; extern int force_iommu, no_iommu; extern int iommu_detected; extern int dmar_disabled; -extern int forbid_dac; extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len); diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 65679d0..8346be8 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -364,6 +364,9 @@ struct kvm_arch{ struct page *ept_identity_pagetable; bool ept_identity_pagetable_done; + + unsigned long irq_sources_bitmap; + unsigned long irq_states[KVM_IOAPIC_NUM_PINS]; }; struct kvm_vm_stat { diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index d7e5a58..e489ff9 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -6,11 +6,12 @@ extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinu CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE) -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_tsc.o = -pg CFLAGS_REMOVE_rtc.o = -pg CFLAGS_REMOVE_paravirt-spinlocks.o = -pg +CFLAGS_REMOVE_ftrace.o = -pg endif # diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index dd65143..28b597e 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S @@ -1149,7 +1149,7 @@ ENDPROC(xen_failsafe_callback) #endif /* CONFIG_XEN */ -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(mcount) @@ -1204,7 +1204,7 @@ trace: jmp ftrace_stub END(mcount) #endif /* CONFIG_DYNAMIC_FTRACE */ -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ .section .rodata,"a" #include "syscall_table_32.S" diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 09e7145..b86f332 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S @@ -61,7 +61,7 @@ .code64 -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(mcount) retq @@ -138,7 +138,7 @@ trace: jmp ftrace_stub END(mcount) #endif /* CONFIG_DYNAMIC_FTRACE */ -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ #ifndef CONFIG_PREEMPT #define retint_kernel retint_restore_args diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index d073d98..50ea0ac 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -21,8 +21,7 @@ #include <asm/nops.h> -/* Long is fine, even if it is only 4 bytes ;-) */ -static unsigned long *ftrace_nop; +static unsigned char ftrace_nop[MCOUNT_INSN_SIZE]; union ftrace_code_union { char code[MCOUNT_INSN_SIZE]; @@ -33,17 +32,17 @@ union ftrace_code_union { }; -static int notrace ftrace_calc_offset(long ip, long addr) +static int ftrace_calc_offset(long ip, long addr) { return (int)(addr - ip); } -notrace unsigned char *ftrace_nop_replace(void) +unsigned char *ftrace_nop_replace(void) { - return (char *)ftrace_nop; + return ftrace_nop; } -notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) +unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) { static union ftrace_code_union calc; @@ -57,7 +56,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr) return calc.code; } -notrace int +int ftrace_modify_code(unsigned long ip, unsigned char *old_code, unsigned char *new_code) { @@ -66,26 +65,31 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code, /* * Note: Due to modules and __init, code can * disappear and change, we need to protect against faulting - * as well as code changing. + * as well as code changing. We do this by using the + * probe_kernel_* functions. * * No real locking needed, this code is run through * kstop_machine, or before SMP starts. */ - if (__copy_from_user_inatomic(replaced, (char __user *)ip, MCOUNT_INSN_SIZE)) - return 1; + /* read the text we want to modify */ + if (probe_kernel_read(replaced, (void *)ip, MCOUNT_INSN_SIZE)) + return -EFAULT; + + /* Make sure it is what we expect it to be */ if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0) - return 2; + return -EINVAL; - WARN_ON_ONCE(__copy_to_user_inatomic((char __user *)ip, new_code, - MCOUNT_INSN_SIZE)); + /* replace the text with the new text */ + if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) + return -EPERM; sync_core(); return 0; } -notrace int ftrace_update_ftrace_func(ftrace_func_t func) +int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); unsigned char old[MCOUNT_INSN_SIZE], *new; @@ -98,13 +102,6 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func) return ret; } -notrace int ftrace_mcount_set(unsigned long *data) -{ - /* mcount is initialized as a nop */ - *data = 0; - return 0; -} - int __init ftrace_dyn_arch_init(void *data) { extern const unsigned char ftrace_test_p6nop[]; @@ -127,9 +124,6 @@ int __init ftrace_dyn_arch_init(void *data) * TODO: check the cpuid to determine the best nop. */ asm volatile ( - "jmp ftrace_test_jmp\n" - /* This code needs to stay around */ - ".section .text, \"ax\"\n" "ftrace_test_jmp:" "jmp ftrace_test_p6nop\n" "nop\n" @@ -140,8 +134,6 @@ int __init ftrace_dyn_arch_init(void *data) "jmp 1f\n" "ftrace_test_nop5:" ".byte 0x66,0x66,0x66,0x66,0x90\n" - "jmp 1f\n" - ".previous\n" "1:" ".section .fixup, \"ax\"\n" "2: movl $1, %0\n" @@ -156,15 +148,15 @@ int __init ftrace_dyn_arch_init(void *data) switch (faulted) { case 0: pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n"); - ftrace_nop = (unsigned long *)ftrace_test_p6nop; + memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE); break; case 1: pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n"); - ftrace_nop = (unsigned long *)ftrace_test_nop5; + memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE); break; case 2: pr_info("ftrace: converting mcount calls to jmp . + 5\n"); - ftrace_nop = (unsigned long *)ftrace_test_jmp; + memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE); break; } diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c index 680a065..2c7dbdb 100644 --- a/arch/x86/kernel/genx2apic_uv_x.c +++ b/arch/x86/kernel/genx2apic_uv_x.c @@ -15,7 +15,6 @@ #include <linux/ctype.h> #include <linux/init.h> #include <linux/sched.h> -#include <linux/bootmem.h> #include <linux/module.h> #include <linux/hardirq.h> #include <asm/smp.h> @@ -398,16 +397,16 @@ void __init uv_system_init(void) printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); - uv_blade_info = alloc_bootmem_pages(bytes); + uv_blade_info = kmalloc(bytes, GFP_KERNEL); get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size); bytes = sizeof(uv_node_to_blade[0]) * num_possible_nodes(); - uv_node_to_blade = alloc_bootmem_pages(bytes); + uv_node_to_blade = kmalloc(bytes, GFP_KERNEL); memset(uv_node_to_blade, 255, bytes); bytes = sizeof(uv_cpu_to_blade[0]) * num_possible_cpus(); - uv_cpu_to_blade = alloc_bootmem_pages(bytes); + uv_cpu_to_blade = kmalloc(bytes, GFP_KERNEL); memset(uv_cpu_to_blade, 255, bytes); blade = 0; diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index dd7ebee..43cec6b 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c @@ -5,7 +5,7 @@ #include <asm/desc.h> #include <asm/ftrace.h> -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER /* mcount is defined in assembly */ EXPORT_SYMBOL(mcount); #endif diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1972266..1926248 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -9,6 +9,8 @@ #include <asm/calgary.h> #include <asm/amd_iommu.h> +static int forbid_dac __read_mostly; + struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); @@ -291,3 +293,17 @@ void pci_iommu_shutdown(void) } /* Must execute after PCI subsystem */ fs_initcall(pci_iommu_init); + +#ifdef CONFIG_PCI +/* Many VIA bridges seem to corrupt data for DAC. Disable it here */ + +static __devinit void via_no_dac(struct pci_dev *dev) +{ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { + printk(KERN_INFO "PCI: VIA PCI bridge detected." + "Disabling DAC.\n"); + forbid_dac = 1; + } +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); +#endif diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index c4ce033..3c539d1 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -18,9 +18,21 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } +static void *x86_swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags) +{ + void *vaddr; + + vaddr = dma_generic_alloc_coherent(hwdev, size, dma_handle, flags); + if (vaddr) + return vaddr; + + return swiotlb_alloc_coherent(hwdev, size, dma_handle, flags); +} + struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, - .alloc_coherent = swiotlb_alloc_coherent, + .alloc_coherent = x86_swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, .map_single = swiotlb_map_single_phys, .unmap_single = swiotlb_unmap_single, diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index b545f37..695e426 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c @@ -12,7 +12,7 @@ #include <asm/desc.h> #include <asm/ftrace.h> -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER /* mcount is defined in assembly */ EXPORT_SYMBOL(mcount); #endif diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 11c6725..8772dc9 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -545,6 +545,12 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) if (!pit) return NULL; + mutex_lock(&kvm->lock); + pit->irq_source_id = kvm_request_irq_source_id(kvm); + mutex_unlock(&kvm->lock); + if (pit->irq_source_id < 0) + return NULL; + mutex_init(&pit->pit_state.lock); mutex_lock(&pit->pit_state.lock); spin_lock_init(&pit->pit_state.inject_lock); @@ -587,6 +593,7 @@ void kvm_free_pit(struct kvm *kvm) mutex_lock(&kvm->arch.vpit->pit_state.lock); timer = &kvm->arch.vpit->pit_state.pit_timer.timer; hrtimer_cancel(timer); + kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id); mutex_unlock(&kvm->arch.vpit->pit_state.lock); kfree(kvm->arch.vpit); } @@ -595,8 +602,8 @@ void kvm_free_pit(struct kvm *kvm) static void __inject_pit_timer_intr(struct kvm *kvm) { mutex_lock(&kvm->lock); - kvm_set_irq(kvm, 0, 1); - kvm_set_irq(kvm, 0, 0); + kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 1); + kvm_set_irq(kvm, kvm->arch.vpit->irq_source_id, 0, 0); mutex_unlock(&kvm->lock); } diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index e436d49..4178022 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -44,6 +44,7 @@ struct kvm_pit { struct kvm_io_device speaker_dev; struct kvm *kvm; struct kvm_kpit_state pit_state; + int irq_source_id; }; #define KVM_PIT_BASE_ADDRESS 0x40 diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 99c239c..2a5e648 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2634,6 +2634,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu, static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu) { kvm_x86_ops->tlb_flush(vcpu); + set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests); return 1; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4f0677d..f1f8ff2 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1742,7 +1742,8 @@ long kvm_arch_vm_ioctl(struct file *filp, goto out; if (irqchip_in_kernel(kvm)) { mutex_lock(&kvm->lock); - kvm_set_irq(kvm, irq_event.irq, irq_event.level); + kvm_set_irq(kvm, KVM_USERSPACE_IRQ_SOURCE_ID, + irq_event.irq, irq_event.level); mutex_unlock(&kvm->lock); r = 0; } @@ -4013,6 +4014,9 @@ struct kvm *kvm_arch_create_vm(void) INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); + /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ + set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); + return kvm; } diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index b8e461d..f79a02f 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -350,8 +350,10 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end, * pagetable pages as RO. So assume someone who pre-setup * these mappings are more intelligent. */ - if (pte_val(*pte)) + if (pte_val(*pte)) { + pages++; continue; + } if (0) printk(" pte=%p addr=%lx pte=%016lx\n", @@ -418,8 +420,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end, * not differ with respect to page frame and * attributes. */ - if (page_size_mask & (1 << PG_LEVEL_2M)) + if (page_size_mask & (1 << PG_LEVEL_2M)) { + pages++; continue; + } new_prot = pte_pgprot(pte_clrhuge(*(pte_t *)pmd)); } @@ -499,8 +503,10 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end, * not differ with respect to page frame and * attributes. */ - if (page_size_mask & (1 << PG_LEVEL_1G)) + if (page_size_mask & (1 << PG_LEVEL_1G)) { + pages++; continue; + } prot = pte_pgprot(pte_clrhuge(*(pte_t *)pud)); } @@ -831,7 +837,7 @@ int arch_add_memory(int nid, u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - last_mapped_pfn = init_memory_mapping(start, start + size-1); + last_mapped_pfn = init_memory_mapping(start, start + size); if (last_mapped_pfn > max_pfn_mapped) max_pfn_mapped = last_mapped_pfn; diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 3139479..6dcefba 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile @@ -1,4 +1,4 @@ -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_spinlock.o = -pg CFLAGS_REMOVE_time.o = -pg diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index d4d52f5..aba77b2 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c @@ -246,11 +246,21 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr) { unsigned long address = (unsigned long)vaddr; unsigned int level; - pte_t *pte = lookup_address(address, &level); - unsigned offset = address & ~PAGE_MASK; + pte_t *pte; + unsigned offset; - BUG_ON(pte == NULL); + /* + * if the PFN is in the linear mapped vaddr range, we can just use + * the (quick) virt_to_machine() p2m lookup + */ + if (virt_addr_valid(vaddr)) + return virt_to_machine(vaddr); + /* otherwise we have to do a (slower) full page-table walk */ + + pte = lookup_address(address, &level); + BUG_ON(pte == NULL); + offset = address & ~PAGE_MASK; return XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset); } @@ -410,7 +420,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, xen_mc_batch(); - u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; + u.ptr = arbitrary_virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; u.val = pte_val_ma(pte); xen_extend_mmu_update(&u); diff --git a/drivers/Kconfig b/drivers/Kconfig index d38f43f..2f557f5 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -68,6 +68,8 @@ source "drivers/ssb/Kconfig" source "drivers/mfd/Kconfig" +source "drivers/regulator/Kconfig" + source "drivers/media/Kconfig" source "drivers/video/Kconfig" diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index aeadd00..a67b8e7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -49,6 +49,17 @@ #define DRV_NAME "ahci" #define DRV_VERSION "3.0" +/* Enclosure Management Control */ +#define EM_CTRL_MSG_TYPE 0x000f0000 + +/* Enclosure Management LED Message Type */ +#define EM_MSG_LED_HBA_PORT 0x0000000f +#define EM_MSG_LED_PMP_SLOT 0x0000ff00 +#define EM_MSG_LED_VALUE 0xffff0000 +#define EM_MSG_LED_VALUE_ACTIVITY 0x00070000 +#define EM_MSG_LED_VALUE_OFF 0xfff80000 +#define EM_MSG_LED_VALUE_ON 0x00010000 + static int ahci_skip_host_reset; module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444); MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)"); @@ -588,6 +599,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ + /* Promise */ + { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ + /* Generic, PCI class code for AHCI */ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, @@ -1220,18 +1234,20 @@ static void ahci_sw_activity_blink(unsigned long arg) struct ahci_em_priv *emp = &pp->em_priv[link->pmp]; unsigned long led_message = emp->led_state; u32 activity_led_state; + unsigned long flags; - led_message &= 0xffff0000; + led_message &= EM_MSG_LED_VALUE; led_message |= ap->port_no | (link->pmp << 8); /* check to see if we've had activity. If so, * toggle state of LED and reset timer. If not, * turn LED to desired idle state. */ + spin_lock_irqsave(ap->lock, flags); if (emp->saved_activity != emp->activity) { emp->saved_activity = emp->activity; /* get the current LED state */ - activity_led_state = led_message & 0x00010000; + activity_led_state = led_message & EM_MSG_LED_VALUE_ON; if (activity_led_state) activity_led_state = 0; @@ -1239,17 +1255,18 @@ static void ahci_sw_activity_blink(unsigned long arg) activity_led_state = 1; /* clear old state */ - led_message &= 0xfff8ffff; + led_message &= ~EM_MSG_LED_VALUE_ACTIVITY; /* toggle state */ led_message |= (activity_led_state << 16); mod_timer(&emp->timer, jiffies + msecs_to_jiffies(100)); } else { /* switch to idle */ - led_message &= 0xfff8ffff; + led_message &= ~EM_MSG_LED_VALUE_ACTIVITY; if (emp->blink_policy == BLINK_OFF) led_message |= (1 << 16); } + spin_unlock_irqrestore(ap->lock, flags); ahci_transmit_led_message(ap, led_message, 4); } @@ -1294,7 +1311,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, struct ahci_em_priv *emp; /* get the slot number from the message */ - pmp = (state & 0x0000ff00) >> 8; + pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; if (pmp < MAX_SLOTS) emp = &pp->em_priv[pmp]; else @@ -1319,7 +1336,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, message[0] |= (4 << 8); /* ignore 0:4 of byte zero, fill in port info yourself */ - message[1] = ((state & 0xfffffff0) | ap->port_no); + message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no); /* write message to EM_LOC */ writel(message[0], mmio + hpriv->em_loc); @@ -1362,7 +1379,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, state = simple_strtoul(buf, NULL, 0); /* get the slot number from the message */ - pmp = (state & 0x0000ff00) >> 8; + pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; if (pmp < MAX_SLOTS) emp = &pp->em_priv[pmp]; else @@ -1373,7 +1390,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, * activity led through em_message */ if (emp->blink_policy) - state &= 0xfff8ffff; + state &= ~EM_MSG_LED_VALUE_ACTIVITY; return ahci_transmit_led_message(ap, state, size); } @@ -1392,16 +1409,16 @@ static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val) link->flags &= ~(ATA_LFLAG_SW_ACTIVITY); /* set the LED to OFF */ - port_led_state &= 0xfff80000; + port_led_state &= EM_MSG_LED_VALUE_OFF; port_led_state |= (ap->port_no | (link->pmp << 8)); ahci_transmit_led_message(ap, port_led_state, 4); } else { link->flags |= ATA_LFLAG_SW_ACTIVITY; if (val == BLINK_OFF) { /* set LED to ON for idle */ - port_led_state &= 0xfff80000; + port_led_state &= EM_MSG_LED_VALUE_OFF; port_led_state |= (ap->port_no | (link->pmp << 8)); - port_led_state |= 0x00010000; /* check this */ + port_led_state |= EM_MSG_LED_VALUE_ON; /* check this */ ahci_transmit_led_message(ap, port_led_state, 4); } } @@ -2612,7 +2629,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) u32 em_loc = readl(mmio + HOST_EM_LOC); u32 em_ctl = readl(mmio + HOST_EM_CTL); - messages = (em_ctl & 0x000f0000) >> 16; + messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16; /* we only support LED message type right now */ if ((messages & 0x01) && (ahci_em_messages == 1)) { diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 75a406f..5c33767 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -1,6 +1,6 @@ /* * ata_generic.c - Generic PATA/SATA controller driver. - * Copyright 2005 Red Hat Inc <alan@redhat.com>, all rights reserved. + * Copyright 2005 Red Hat Inc, all rights reserved. * * Elements from ide/pci/generic.c * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index e9e32ed..52dc2d8 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -14,7 +14,7 @@ * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> + * Copyright (C) 2003 Red Hat Inc * * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 8cb0b36..2ff633c 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4156,29 +4156,33 @@ static int cable_is_40wire(struct ata_port *ap) struct ata_link *link; struct ata_device *dev; - /* If the controller thinks we are 40 wire, we are */ + /* If the controller thinks we are 40 wire, we are. */ if (ap->cbl == ATA_CBL_PATA40) return 1; - /* If the controller thinks we are 80 wire, we are */ + + /* If the controller thinks we are 80 wire, we are. */ if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA) return 0; - /* If the system is known to be 40 wire short cable (eg laptop), - then we allow 80 wire modes even if the drive isn't sure */ + + /* If the system is known to be 40 wire short cable (eg + * laptop), then we allow 80 wire modes even if the drive + * isn't sure. + */ if (ap->cbl == ATA_CBL_PATA40_SHORT) return 0; - /* If the controller doesn't know we scan - - - Note: We look for all 40 wire detects at this point. - Any 80 wire detect is taken to be 80 wire cable - because - - In many setups only the one drive (slave if present) - will give a valid detect - - If you have a non detect capable drive you don't - want it to colour the choice - */ + + /* If the controller doesn't know, we scan. + * + * Note: We look for all 40 wire detects at this point. Any + * 80 wire detect is taken to be 80 wire cable because + * - in many setups only the one drive (slave if present) will + * give a valid detect + * - if you have a non detect capable drive you don't want it + * to colour the choice + */ ata_port_for_each_link(link, ap) { ata_link_for_each_dev(dev, link) { - if (!ata_is_40wire(dev)) + if (ata_dev_enabled(dev) && !ata_is_40wire(dev)) return 0; } } @@ -4553,6 +4557,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) /** * ata_qc_new_init - Request an available ATA command, and initialize it * @dev: Device from whom we request an available command structure + * @tag: command tag * * LOCKING: * None. diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5d687d7..8077bdf 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -603,6 +603,9 @@ void ata_scsi_error(struct Scsi_Host *host) ata_link_for_each_dev(dev, link) { int devno = dev->devno; + if (!ata_dev_enabled(dev)) + continue; + ehc->saved_xfer_mode[devno] = dev->xfer_mode; if (ata_ncq_enabled(dev)) ehc->saved_ncq_enabled |= 1 << devno; @@ -1161,6 +1164,7 @@ void ata_eh_detach_dev(struct ata_device *dev) { struct ata_link *link = dev->link; struct ata_port *ap = link->ap; + struct ata_eh_context *ehc = &link->eh_context; unsigned long flags; ata_dev_disable(dev); @@ -1174,9 +1178,11 @@ void ata_eh_detach_dev(struct ata_device *dev) ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; } - /* clear per-dev EH actions */ + /* clear per-dev EH info */ ata_eh_clear_action(link, dev, &link->eh_info, ATA_EH_PERDEV_MASK); ata_eh_clear_action(link, dev, &link->eh_context.i, ATA_EH_PERDEV_MASK); + ehc->saved_xfer_mode[dev->devno] = 0; + ehc->saved_ncq_enabled &= ~(1 << dev->devno); spin_unlock_irqrestore(ap->lock, flags); } @@ -2787,6 +2793,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) /* if data transfer is verified, clear DUBIOUS_XFER on ering top */ ata_link_for_each_dev(dev, link) { + if (!ata_dev_enabled(dev)) + continue; + if (!(dev->flags & ATA_DFLAG_DUBIOUS_XFER)) { struct ata_ering_entry *ent; @@ -2808,6 +2817,9 @@ int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) u8 saved_xfer_mode = ehc->saved_xfer_mode[dev->devno]; u8 saved_ncq = !!(ehc->saved_ncq_enabled & (1 << dev->devno)); + if (!ata_dev_enabled(dev)) + continue; + if (dev->xfer_mode != saved_xfer_mode || ata_ncq_enabled(dev) != saved_ncq) dev->flags |= ATA_DFLAG_DUBIOUS_XFER; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 4b95c43..bbb30d8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1107,6 +1107,15 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); depth = min(ATA_MAX_QUEUE - 1, depth); + + /* + * If this device is behind a port multiplier, we have + * to share the tag map between all devices on that PMP. + * Set up the shared tag map here and we get automatic. + */ + if (dev->link->ap->pmp_link) + scsi_init_shared_tag_map(sdev->host, ATA_MAX_QUEUE - 1); + scsi_set_tag_type(sdev, MSG_SIMPLE_TAG); scsi_activate_tcq(sdev, depth); } diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c index eb919c1..e2e332d 100644 --- a/drivers/ata/pata_acpi.c +++ b/drivers/ata/pata_acpi.c @@ -1,7 +1,7 @@ /* * ACPI PATA driver * - * (c) 2007 Red Hat <alan@redhat.com> + * (c) 2007 Red Hat */ #include <linux/kernel.h> diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 5ca70fa..73c466e 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -1,7 +1,6 @@ /* * pata_ali.c - ALI 15x3 PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * based in part upon * linux/drivers/ide/pci/alim15x3.c Version 0.17 2003/01/02 diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 57dd00f..0ec9c7d 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -1,7 +1,6 @@ /* * pata_amd.c - AMD PATA for new ATA layer * (C) 2005-2006 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Based on pata-sil680. Errata information is taken from data sheets * and the amd74xx.c driver by Vojtech Pavlik. Nvidia SATA devices are diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 0f513bc..6b3092c 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -1,7 +1,7 @@ /* * pata_artop.c - ARTOP ATA controller driver * - * (C) 2006 Red Hat <alan@redhat.com> + * (C) 2006 Red Hat * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on drivers/ide/pci/aec62xx.c diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index e8a0d99..0e2cde8 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -1,7 +1,6 @@ /* * pata_atiixp.c - ATI PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Based on * diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c index 2de30b9..34a3942 100644 --- a/drivers/ata/pata_cmd640.c +++ b/drivers/ata/pata_cmd640.c @@ -1,7 +1,6 @@ /* * pata_cmd640.c - CMD640 PCI PATA for new ATA layer * (C) 2007 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Based upon * linux/drivers/ide/pci/cmd640.c Version 1.02 Sep 01, 1996 diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index ddd09b7..3167d8f 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c @@ -1,7 +1,7 @@ /* * pata_cmd64x.c - CMD64x PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * * Based upon * linux/drivers/ide/pci/cmd64x.c Version 1.30 Sept 10, 2002 diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c index 0c4b271..bba4533 100644 --- a/drivers/ata/pata_cs5530.c +++ b/drivers/ata/pata_cs5530.c @@ -1,7 +1,6 @@ /* * pata-cs5530.c - CS5530 PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * based upon cs5530.c by Mark Lord. * diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index f1b6556..1b2d4a0 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -1,7 +1,7 @@ /* * pata-cs5535.c - CS5535 PATA for new ATA layer * (C) 2005-2006 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * * based upon cs5535.c from AMD <Jens.Altmann@amd.com> as cleaned up and * made readable and Linux style by Wolfgang Zuleger <wolfgang.zuleger@gmx.de diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c index 2ff6260..d546425 100644 --- a/drivers/ata/pata_cypress.c +++ b/drivers/ata/pata_cypress.c @@ -1,7 +1,7 @@ /* * pata_cypress.c - Cypress PATA for new ATA layer * (C) 2006 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox * * Based heavily on * linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002 diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c index 9fba829..ac6392e 100644 --- a/drivers/ata/pata_efar.c +++ b/drivers/ata/pata_efar.c @@ -1,7 +1,7 @@ /* * pata_efar.c - EFAR PIIX clone controller driver * - * (C) 2005 Red Hat <alan@redhat.com> + * (C) 2005 Red Hat * * Some parts based on ata_piix.c by Jeff Garzik and others. * diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 6a111ba..15cdb91 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -1,7 +1,7 @@ /* * pata-isapnp.c - ISA PnP PATA controller driver. - * Copyright 2005/2006 Red Hat Inc <alan@redhat.com>, all rights reserved. + * Copyright 2005/2006 Red Hat Inc, all rights reserved. * * Based in part on ide-pnp.c by Andrey Panin <pazke@donpac.ru> */ diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 0221c9a..860ede5 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -1,7 +1,7 @@ /* * pata_it821x.c - IT821x PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * (C) 2007 Bartlomiej Zolnierkiewicz * * based upon @@ -10,7 +10,7 @@ * * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 * - * Copyright (C) 2004 Red Hat <alan@redhat.com> + * Copyright (C) 2004 Red Hat * * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. @@ -557,9 +557,8 @@ static unsigned int it821x_read_id(struct ata_device *adev, if (strstr(model_num, "Integrated Technology Express")) { /* Set feature bits the firmware neglects */ id[49] |= 0x0300; /* LBA, DMA */ - id[82] |= 0x0400; /* LBA48 */ id[83] &= 0x7FFF; - id[83] |= 0x4000; /* Word 83 is valid */ + id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ id[86] |= 0x0400; /* LBA48 on */ id[ATA_ID_MAJOR_VER] |= 0x1F; } diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 73b7596..38cf1ab 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -4,7 +4,7 @@ * driven by AHCI in the usual configuration although * this driver can handle other setups if we need it. * - * (c) 2006 Red Hat <alan@redhat.com> + * (c) 2006 Red Hat */ #include <linux/kernel.h> diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index bc037ff..930c220 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c @@ -1,6 +1,6 @@ /* * pata-legacy.c - Legacy port PATA/SATA controller driver. - * Copyright 2005/2006 Red Hat <alan@redhat.com>, all rights reserved. + * Copyright 2005/2006 Red Hat, all rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 0d87eec..76e399b 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -5,7 +5,7 @@ * isn't making full use of the device functionality but it is * easy to get working. * - * (c) 2006 Red Hat <alan@redhat.com> + * (c) 2006 Red Hat */ #include <linux/kernel.h> diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c index 7d7e3fd..7c8faa4 100644 --- a/drivers/ata/pata_mpiix.c +++ b/drivers/ata/pata_mpiix.c @@ -1,7 +1,7 @@ /* * pata_mpiix.c - Intel MPIIX PATA for new ATA layer * (C) 2005-2006 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * * The MPIIX is different enough to the PIIX4 and friends that we give it * a separate driver. The old ide/pci code handles this by just not tuning diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c index d9719c8..9dc05e1 100644 --- a/drivers/ata/pata_netcell.c +++ b/drivers/ata/pata_netcell.c @@ -1,7 +1,7 @@ /* * pata_netcell.c - Netcell PATA driver * - * (c) 2006 Red Hat <alan@redhat.com> + * (c) 2006 Red Hat */ #include <linux/kernel.h> diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c index 565e67c..4e466ea 100644 --- a/drivers/ata/pata_ninja32.c +++ b/drivers/ata/pata_ninja32.c @@ -1,7 +1,6 @@ /* * pata_ninja32.c - Ninja32 PATA for new ATA layer * (C) 2007 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Note: The controller like many controllers has shared timings for * PIO and DMA. We thus flip to the DMA timings in dma_start and flip back @@ -45,7 +44,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_ninja32" -#define DRV_VERSION "0.0.1" +#define DRV_VERSION "0.1.1" /** @@ -89,6 +88,17 @@ static struct ata_port_operations ninja32_port_ops = { .set_piomode = ninja32_set_piomode, }; +static void ninja32_program(void __iomem *base) +{ + iowrite8(0x05, base + 0x01); /* Enable interrupt lines */ + iowrite8(0xBE, base + 0x02); /* Burst, ?? setup */ + iowrite8(0x01, base + 0x03); /* Unknown */ + iowrite8(0x20, base + 0x04); /* WAIT0 */ + iowrite8(0x8f, base + 0x05); /* Unknown */ + iowrite8(0xa4, base + 0x1c); /* Unknown */ + iowrite8(0x83, base + 0x1d); /* BMDMA control: WAIT0 */ +} + static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) { struct ata_host *host; @@ -134,18 +144,28 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id) ap->ioaddr.bmdma_addr = base; ata_sff_std_ports(&ap->ioaddr); - iowrite8(0x05, base + 0x01); /* Enable interrupt lines */ - iowrite8(0xBE, base + 0x02); /* Burst, ?? setup */ - iowrite8(0x01, base + 0x03); /* Unknown */ - iowrite8(0x20, base + 0x04); /* WAIT0 */ - iowrite8(0x8f, base + 0x05); /* Unknown */ - iowrite8(0xa4, base + 0x1c); /* Unknown */ - iowrite8(0x83, base + 0x1d); /* BMDMA control: WAIT0 */ + ninja32_program(base); /* FIXME: Should we disable them at remove ? */ return ata_host_activate(host, dev->irq, ata_sff_interrupt, IRQF_SHARED, &ninja32_sht); } +#ifdef CONFIG_PM + +static int ninja32_reinit_one(struct pci_dev *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + int rc; + + rc = ata_pci_device_do_resume(pdev); + if (rc) + return rc; + ninja32_program(host->iomap[0]); + ata_host_resume(host); + return 0; +} +#endif + static const struct pci_device_id ninja32[] = { { 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, @@ -156,7 +176,11 @@ static struct pci_driver ninja32_pci_driver = { .name = DRV_NAME, .id_table = ninja32, .probe = ninja32_init_one, - .remove = ata_pci_remove_one + .remove = ata_pci_remove_one, +#ifdef CONFIG_PM + .suspend = ata_pci_device_suspend, + .resume = ninja32_reinit_one, +#endif }; static int __init ninja32_init(void) diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c index be756b7..40d411c 100644 --- a/drivers/ata/pata_ns87410.c +++ b/drivers/ata/pata_ns87410.c @@ -1,7 +1,6 @@ /* * pata_ns87410.c - National Semiconductor 87410 PATA for new ATA layer * (C) 2006 Red Hat Inc - * Alan Cox <alan@redhat.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 diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index e0aa7ea..89bf5f8 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -1,7 +1,7 @@ /* * pata_ns87415.c - NS87415 (non PARISC) PATA * - * (C) 2005 Red Hat <alan@redhat.com> + * (C) 2005 Red Hat <alan@lxorguk.ukuu.org.uk> * * This is a fairly generic MWDMA controller. It has some limitations * as it requires timing reloads on PIO/DMA transitions but it is otherwise diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c index df64f24..c0dbc46 100644 --- a/drivers/ata/pata_oldpiix.c +++ b/drivers/ata/pata_oldpiix.c @@ -1,7 +1,7 @@ /* * pata_oldpiix.c - Intel PATA/SATA controllers * - * (C) 2005 Red Hat <alan@redhat.com> + * (C) 2005 Red Hat * * Some parts based on ata_piix.c by Jeff Garzik and others. * diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c index fb2cf66..e4fa4d5 100644 --- a/drivers/ata/pata_opti.c +++ b/drivers/ata/pata_opti.c @@ -1,7 +1,6 @@ /* * pata_opti.c - ATI PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Based on * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c index 4cd7444..93bb6e9 100644 --- a/drivers/ata/pata_optidma.c +++ b/drivers/ata/pata_optidma.c @@ -1,7 +1,6 @@ /* * pata_optidma.c - Opti DMA PATA for new ATA layer * (C) 2006 Red Hat Inc - * Alan Cox <alan@redhat.com> * * The Opti DMA controllers are related to the older PIO PCI controllers * and indeed the VLB ones. The main differences are that the timing diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 02b596b..271cb64 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -1,6 +1,6 @@ /* * pata_pcmcia.c - PCMCIA PATA controller driver. - * Copyright 2005-2006 Red Hat Inc <alan@redhat.com>, all rights reserved. + * Copyright 2005-2006 Red Hat Inc, all rights reserved. * PCMCIA ident update Copyright 2006 Marcin Juszkiewicz * <openembedded@hrw.one.pl> * diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index d267306..799a6a0 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -1,7 +1,7 @@ /* * pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 8f65ad6..77e4e3b 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -5,7 +5,7 @@ * * Based on pata_pcmcia: * - * Copyright 2005-2006 Red Hat Inc <alan@redhat.com>, all rights reserved. + * Copyright 2005-2006 Red Hat Inc, all rights reserved. * * 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 diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index 63b7a1c..3080f37 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c @@ -1,6 +1,6 @@ /* * pata_qdi.c - QDI VLB ATA controllers - * (C) 2006 Red Hat <alan@redhat.com> + * (C) 2006 Red Hat * * This driver mostly exists as a proof of concept for non PCI devices under * libata. While the QDI6580 was 'neat' in 1993 it is no longer terribly diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c index 1c0d9fa..0b0aa45 100644 --- a/drivers/ata/pata_radisys.c +++ b/drivers/ata/pata_radisys.c @@ -1,7 +1,7 @@ /* * pata_radisys.c - Intel PATA/SATA controllers * - * (C) 2006 Red Hat <alan@redhat.com> + * (C) 2006 Red Hat <alan@lxorguk.ukuu.org.uk> * * Some parts based on ata_piix.c by Jeff Garzik and others. * diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c index 0278fd2..9a4bdca 100644 --- a/drivers/ata/pata_sc1200.c +++ b/drivers/ata/pata_sc1200.c @@ -1,5 +1,5 @@ /* - * New ATA layer SC1200 driver Alan Cox <alan@redhat.com> + * New ATA layer SC1200 driver Alan Cox <alan@lxorguk.ukuu.org.uk> * * TODO: Mode selection filtering * TODO: Can't enable second channel until ATA core has serialize diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c index 16673d1..cf3707e 100644 --- a/drivers/ata/pata_scc.c +++ b/drivers/ata/pata_scc.c @@ -8,7 +8,7 @@ * Copyright 2003-2005 Jeff Garzik * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> - * Copyright (C) 2003 Red Hat Inc <alan@redhat.com> + * Copyright (C) 2003 Red Hat Inc * * and drivers/ata/ahci.c: * Copyright 2004-2005 Red Hat, Inc. diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c index ffd26d0..72e41c9 100644 --- a/drivers/ata/pata_serverworks.c +++ b/drivers/ata/pata_serverworks.c @@ -1,7 +1,6 @@ /* * pata_serverworks.c - Serverworks PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * based upon * diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c index a598bb3..83580a5 100644 --- a/drivers/ata/pata_sil680.c +++ b/drivers/ata/pata_sil680.c @@ -1,7 +1,6 @@ /* * pata_sil680.c - SIL680 PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * based upon * diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 26345d7..d342366 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -1,7 +1,7 @@ /* * pata_sis.c - SiS ATA driver * - * (C) 2005 Red Hat <alan@redhat.com> + * (C) 2005 Red Hat * (C) 2007 Bartlomiej Zolnierkiewicz * * Based upon linux/drivers/ide/pci/sis5513.c diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c index 69877bd..1b0e7b6 100644 --- a/drivers/ata/pata_sl82c105.c +++ b/drivers/ata/pata_sl82c105.c @@ -1,7 +1,6 @@ /* * pata_sl82c105.c - SL82C105 PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Based in part on linux/drivers/ide/pci/sl82c105.c * SL82C105/Winbond 553 IDE driver diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index b181261..ef95975 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -1,7 +1,7 @@ /* * pata_triflex.c - Compaq PATA for new ATA layer * (C) 2005 Red Hat Inc - * Alan Cox <alan@redhat.com> + * Alan Cox <alan@lxorguk.ukuu.org.uk> * * based upon * diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 8fdb2ce..681169c 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -1,7 +1,6 @@ /* * pata_via.c - VIA PATA for new ATA layer * (C) 2005-2006 Red Hat Inc - * Alan Cox <alan@redhat.com> * * Documentation * Most chipset documentation available under NDA only diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c index a7606b0..319e164 100644 --- a/drivers/ata/pata_winbond.c +++ b/drivers/ata/pata_winbond.c @@ -1,6 +1,6 @@ /* * pata_winbond.c - Winbond VLB ATA controllers - * (C) 2006 Red Hat <alan@redhat.com> + * (C) 2006 Red Hat * * Support for the Winbond 83759A when operating in advanced mode. * Multichip mode is not currently supported. diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index 4621807..ccee930 100644 --- a/drivers/ata/sata_sil24.c +++ b/drivers/ata/sata_sil24.c @@ -1329,6 +1329,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } } + /* Set max read request size to 4096. This slightly increases + * write throughput for pci-e variants. + */ + pcie_set_readrq(pdev, 4096); + sil24_init_controller(host); pci_set_master(pdev); diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 75dd6e2..c98c31e 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c @@ -355,7 +355,7 @@ static void __sysdev_resume(struct sys_device *dev) * sysdev_suspend - Suspend all system devices. * @state: Power state to enter. * - * We perform an almost identical operation as sys_device_shutdown() + * We perform an almost identical operation as sysdev_shutdown() * above, though calling ->suspend() instead. Interrupts are disabled * when this called. Devices are responsible for both saving state and * quiescing or powering down the device. @@ -437,7 +437,7 @@ aux_driver: /** * sysdev_resume - Bring system devices back to life. * - * Similar to sys_device_suspend(), but we iterate the list forwards + * Similar to sysdev_suspend(), but we iterate the list forwards * to guarantee that parent devices are resumed before their children. * * Note: Interrupts are disabled when called. @@ -488,7 +488,8 @@ ssize_t sysdev_store_ulong(struct sys_device *sysdev, if (end == buf) return -EINVAL; *(unsigned long *)(ea->var) = new; - return end - buf; + /* Always return full write size even if we didn't consume all */ + return size; } EXPORT_SYMBOL_GPL(sysdev_store_ulong); @@ -511,7 +512,8 @@ ssize_t sysdev_store_int(struct sys_device *sysdev, if (end == buf || new > INT_MAX || new < INT_MIN) return -EINVAL; *(int *)(ea->var) = new; - return end - buf; + /* Always return full write size even if we didn't consume all */ + return size; } EXPORT_SYMBOL_GPL(sysdev_store_int); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 3f09cd8..5c4ee70 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -40,8 +40,7 @@ * Heinz Mauelshagen <mge@sistina.com>, Feb 2002 * * Support for falling back on the write file operation when the address space - * operations prepare_write and/or commit_write are not available on the - * backing filesystem. + * operations write_begin is not available on the backing filesystem. * Anton Altaparmakov, 16 Feb 2005 * * Still To Fix: @@ -765,7 +764,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, */ if (!file->f_op->splice_read) goto out_putf; - if (aops->prepare_write || aops->write_begin) + if (aops->write_begin) lo_flags |= LO_FLAGS_USE_AOPS; if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) lo_flags |= LO_FLAGS_READ_ONLY; diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 58630cc..cda6c7c 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -152,7 +152,7 @@ static int btsdio_rx_packet(struct btsdio_data *data) err = sdio_readsb(data->func, skb->data, REG_RDAT, len - 4); if (err < 0) { - kfree(skb); + kfree_skb(skb); return err; } diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index c422e87..cd0ba51 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c @@ -11,7 +11,7 @@ * derived from * * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc <alan@redhat.com> + * (c) Copyright 2001 Red Hat Inc * * derived from * diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index fed4ef5..64d513f6 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c @@ -11,7 +11,7 @@ * derived from * * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc <alan@redhat.com> + * (c) Copyright 2001 Red Hat Inc * * derived from * diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 8a2fce0..5dcbe60 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -11,7 +11,7 @@ * derived from * * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc <alan@redhat.com> + * (c) Copyright 2001 Red Hat Inc * * derived from * diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 128202e..4e9573c 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -11,7 +11,7 @@ * derived from * * Hardware driver for the AMD 768 Random Number Generator (RNG) - * (c) Copyright 2001 Red Hat Inc <alan@redhat.com> + * (c) Copyright 2001 Red Hat Inc * * derived from * diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 835a33c..1d7b429 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -957,3 +957,4 @@ module_exit(cleanup_ipmi); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>"); MODULE_DESCRIPTION("Linux device interface for the IPMI message handler."); +MODULE_ALIAS("platform:ipmi_si"); diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 5a11e3c..e0dbd38 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -102,6 +102,13 @@ config EDAC_I3000 Support for error detection and correction on the Intel 3000 and 3010 server chipsets. +config EDAC_X38 + tristate "Intel X38" + depends on EDAC_MM_EDAC && PCI && X86 + help + Support for error detection and correction on the Intel + X38 server chipsets. + config EDAC_I82860 tristate "Intel 82860" depends on EDAC_MM_EDAC && PCI && X86_32 diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index e5e9104..62c2d9b 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_EDAC_I82443BXGX) += i82443bxgx_edac.o obj-$(CONFIG_EDAC_I82875P) += i82875p_edac.o obj-$(CONFIG_EDAC_I82975X) += i82975x_edac.o obj-$(CONFIG_EDAC_I3000) += i3000_edac.o +obj-$(CONFIG_EDAC_X38) += x38_edac.o obj-$(CONFIG_EDAC_I82860) += i82860_edac.o obj-$(CONFIG_EDAC_R82600) += r82600_edac.o obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index 887072f..cd2e3b8 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c @@ -9,6 +9,7 @@ */ #undef DEBUG +#include <linux/edac.h> #include <linux/module.h> #include <linux/init.h> #include <linux/platform_device.h> @@ -164,6 +165,8 @@ static int __devinit cell_edac_probe(struct platform_device *pdev) if (regs == NULL) return -ENODEV; + edac_op_state = EDAC_OPSTATE_POLL; + /* Get channel population */ reg = in_be64(®s->mic_mnt_cfg); dev_dbg(&pdev->dev, "MIC_MNT_CFG = 0x%016lx\n", reg); diff --git a/drivers/edac/x38_edac.c b/drivers/edac/x38_edac.c new file mode 100644 index 0000000..2406c2c --- /dev/null +++ b/drivers/edac/x38_edac.c @@ -0,0 +1,524 @@ +/* + * Intel X38 Memory Controller kernel module + * Copyright (C) 2008 Cluster Computing, Inc. + * + * This file may be distributed under the terms of the + * GNU General Public License. + * + * This file is based on i3200_edac.c + * + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/pci_ids.h> +#include <linux/slab.h> +#include <linux/edac.h> +#include "edac_core.h" + +#define X38_REVISION "1.1" + +#define EDAC_MOD_STR "x38_edac" + +#define PCI_DEVICE_ID_INTEL_X38_HB 0x29e0 + +#define X38_RANKS 8 +#define X38_RANKS_PER_CHANNEL 4 +#define X38_CHANNELS 2 + +/* Intel X38 register addresses - device 0 function 0 - DRAM Controller */ + +#define X38_MCHBAR_LOW 0x48 /* MCH Memory Mapped Register BAR */ +#define X38_MCHBAR_HIGH 0x4b +#define X38_MCHBAR_MASK 0xfffffc000ULL /* bits 35:14 */ +#define X38_MMR_WINDOW_SIZE 16384 + +#define X38_TOM 0xa0 /* Top of Memory (16b) + * + * 15:10 reserved + * 9:0 total populated physical memory + */ +#define X38_TOM_MASK 0x3ff /* bits 9:0 */ +#define X38_TOM_SHIFT 26 /* 64MiB grain */ + +#define X38_ERRSTS 0xc8 /* Error Status Register (16b) + * + * 15 reserved + * 14 Isochronous TBWRR Run Behind FIFO Full + * (ITCV) + * 13 Isochronous TBWRR Run Behind FIFO Put + * (ITSTV) + * 12 reserved + * 11 MCH Thermal Sensor Event + * for SMI/SCI/SERR (GTSE) + * 10 reserved + * 9 LOCK to non-DRAM Memory Flag (LCKF) + * 8 reserved + * 7 DRAM Throttle Flag (DTF) + * 6:2 reserved + * 1 Multi-bit DRAM ECC Error Flag (DMERR) + * 0 Single-bit DRAM ECC Error Flag (DSERR) + */ +#define X38_ERRSTS_UE 0x0002 +#define X38_ERRSTS_CE 0x0001 +#define X38_ERRSTS_BITS (X38_ERRSTS_UE | X38_ERRSTS_CE) + + +/* Intel MMIO register space - device 0 function 0 - MMR space */ + +#define X38_C0DRB 0x200 /* Channel 0 DRAM Rank Boundary (16b x 4) + * + * 15:10 reserved + * 9:0 Channel 0 DRAM Rank Boundary Address + */ +#define X38_C1DRB 0x600 /* Channel 1 DRAM Rank Boundary (16b x 4) */ +#define X38_DRB_MASK 0x3ff /* bits 9:0 */ +#define X38_DRB_SHIFT 26 /* 64MiB grain */ + +#define X38_C0ECCERRLOG 0x280 /* Channel 0 ECC Error Log (64b) + * + * 63:48 Error Column Address (ERRCOL) + * 47:32 Error Row Address (ERRROW) + * 31:29 Error Bank Address (ERRBANK) + * 28:27 Error Rank Address (ERRRANK) + * 26:24 reserved + * 23:16 Error Syndrome (ERRSYND) + * 15: 2 reserved + * 1 Multiple Bit Error Status (MERRSTS) + * 0 Correctable Error Status (CERRSTS) + */ +#define X38_C1ECCERRLOG 0x680 /* Channel 1 ECC Error Log (64b) */ +#define X38_ECCERRLOG_CE 0x1 +#define X38_ECCERRLOG_UE 0x2 +#define X38_ECCERRLOG_RANK_BITS 0x18000000 +#define X38_ECCERRLOG_SYNDROME_BITS 0xff0000 + +#define X38_CAPID0 0xe0 /* see P.94 of spec for details */ + +static int x38_channel_num; + +static int how_many_channel(struct pci_dev *pdev) +{ + unsigned char capid0_8b; /* 8th byte of CAPID0 */ + + pci_read_config_byte(pdev, X38_CAPID0 + 8, &capid0_8b); + if (capid0_8b & 0x20) { /* check DCD: Dual Channel Disable */ + debugf0("In single channel mode.\n"); + x38_channel_num = 1; + } else { + debugf0("In dual channel mode.\n"); + x38_channel_num = 2; + } + + return x38_channel_num; +} + +static unsigned long eccerrlog_syndrome(u64 log) +{ + return (log & X38_ECCERRLOG_SYNDROME_BITS) >> 16; +} + +static int eccerrlog_row(int channel, u64 log) +{ + return ((log & X38_ECCERRLOG_RANK_BITS) >> 27) | + (channel * X38_RANKS_PER_CHANNEL); +} + +enum x38_chips { + X38 = 0, +}; + +struct x38_dev_info { + const char *ctl_name; +}; + +struct x38_error_info { + u16 errsts; + u16 errsts2; + u64 eccerrlog[X38_CHANNELS]; +}; + +static const struct x38_dev_info x38_devs[] = { + [X38] = { + .ctl_name = "x38"}, +}; + +static struct pci_dev *mci_pdev; +static int x38_registered = 1; + + +static void x38_clear_error_info(struct mem_ctl_info *mci) +{ + struct pci_dev *pdev; + + pdev = to_pci_dev(mci->dev); + + /* + * Clear any error bits. + * (Yes, we really clear bits by writing 1 to them.) + */ + pci_write_bits16(pdev, X38_ERRSTS, X38_ERRSTS_BITS, + X38_ERRSTS_BITS); +} + +static u64 x38_readq(const void __iomem *addr) +{ + return readl(addr) | (((u64)readl(addr + 4)) << 32); +} + +static void x38_get_and_clear_error_info(struct mem_ctl_info *mci, + struct x38_error_info *info) +{ + struct pci_dev *pdev; + void __iomem *window = mci->pvt_info; + + pdev = to_pci_dev(mci->dev); + + /* + * This is a mess because there is no atomic way to read all the + * registers at once and the registers can transition from CE being + * overwritten by UE. + */ + pci_read_config_word(pdev, X38_ERRSTS, &info->errsts); + if (!(info->errsts & X38_ERRSTS_BITS)) + return; + + info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG); + if (x38_channel_num == 2) + info->eccerrlog[1] = x38_readq(window + X38_C1ECCERRLOG); + + pci_read_config_word(pdev, X38_ERRSTS, &info->errsts2); + + /* + * If the error is the same for both reads then the first set + * of reads is valid. If there is a change then there is a CE + * with no info and the second set of reads is valid and + * should be UE info. + */ + if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) { + info->eccerrlog[0] = x38_readq(window + X38_C0ECCERRLOG); + if (x38_channel_num == 2) + info->eccerrlog[1] = + x38_readq(window + X38_C1ECCERRLOG); + } + + x38_clear_error_info(mci); +} + +static void x38_process_error_info(struct mem_ctl_info *mci, + struct x38_error_info *info) +{ + int channel; + u64 log; + + if (!(info->errsts & X38_ERRSTS_BITS)) + return; + + if ((info->errsts ^ info->errsts2) & X38_ERRSTS_BITS) { + edac_mc_handle_ce_no_info(mci, "UE overwrote CE"); + info->errsts = info->errsts2; + } + + for (channel = 0; channel < x38_channel_num; channel++) { + log = info->eccerrlog[channel]; + if (log & X38_ECCERRLOG_UE) { + edac_mc_handle_ue(mci, 0, 0, + eccerrlog_row(channel, log), "x38 UE"); + } else if (log & X38_ECCERRLOG_CE) { + edac_mc_handle_ce(mci, 0, 0, + eccerrlog_syndrome(log), + eccerrlog_row(channel, log), 0, "x38 CE"); + } + } +} + +static void x38_check(struct mem_ctl_info *mci) +{ + struct x38_error_info info; + + debugf1("MC%d: %s()\n", mci->mc_idx, __func__); + x38_get_and_clear_error_info(mci, &info); + x38_process_error_info(mci, &info); +} + + +void __iomem *x38_map_mchbar(struct pci_dev *pdev) +{ + union { + u64 mchbar; + struct { + u32 mchbar_low; + u32 mchbar_high; + }; + } u; + void __iomem *window; + + pci_read_config_dword(pdev, X38_MCHBAR_LOW, &u.mchbar_low); + pci_write_config_dword(pdev, X38_MCHBAR_LOW, u.mchbar_low | 0x1); + pci_read_config_dword(pdev, X38_MCHBAR_HIGH, &u.mchbar_high); + u.mchbar &= X38_MCHBAR_MASK; + + if (u.mchbar != (resource_size_t)u.mchbar) { + printk(KERN_ERR + "x38: mmio space beyond accessible range (0x%llx)\n", + (unsigned long long)u.mchbar); + return NULL; + } + + window = ioremap_nocache(u.mchbar, X38_MMR_WINDOW_SIZE); + if (!window) + printk(KERN_ERR "x38: cannot map mmio space at 0x%llx\n", + (unsigned long long)u.mchbar); + + return window; +} + + +static void x38_get_drbs(void __iomem *window, + u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL]) +{ + int i; + + for (i = 0; i < X38_RANKS_PER_CHANNEL; i++) { + drbs[0][i] = readw(window + X38_C0DRB + 2*i) & X38_DRB_MASK; + drbs[1][i] = readw(window + X38_C1DRB + 2*i) & X38_DRB_MASK; + } +} + +static bool x38_is_stacked(struct pci_dev *pdev, + u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL]) +{ + u16 tom; + + pci_read_config_word(pdev, X38_TOM, &tom); + tom &= X38_TOM_MASK; + + return drbs[X38_CHANNELS - 1][X38_RANKS_PER_CHANNEL - 1] == tom; +} + +static unsigned long drb_to_nr_pages( + u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL], + bool stacked, int channel, int rank) +{ + int n; + + n = drbs[channel][rank]; + if (rank > 0) + n -= drbs[channel][rank - 1]; + if (stacked && (channel == 1) && drbs[channel][rank] == + drbs[channel][X38_RANKS_PER_CHANNEL - 1]) { + n -= drbs[0][X38_RANKS_PER_CHANNEL - 1]; + } + + n <<= (X38_DRB_SHIFT - PAGE_SHIFT); + return n; +} + +static int x38_probe1(struct pci_dev *pdev, int dev_idx) +{ + int rc; + int i; + struct mem_ctl_info *mci = NULL; + unsigned long last_page; + u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL]; + bool stacked; + void __iomem *window; + + debugf0("MC: %s()\n", __func__); + + window = x38_map_mchbar(pdev); + if (!window) + return -ENODEV; + + x38_get_drbs(window, drbs); + + how_many_channel(pdev); + + /* FIXME: unconventional pvt_info usage */ + mci = edac_mc_alloc(0, X38_RANKS, x38_channel_num, 0); + if (!mci) + return -ENOMEM; + + debugf3("MC: %s(): init mci\n", __func__); + + mci->dev = &pdev->dev; + mci->mtype_cap = MEM_FLAG_DDR2; + + mci->edac_ctl_cap = EDAC_FLAG_SECDED; + mci->edac_cap = EDAC_FLAG_SECDED; + + mci->mod_name = EDAC_MOD_STR; + mci->mod_ver = X38_REVISION; + mci->ctl_name = x38_devs[dev_idx].ctl_name; + mci->dev_name = pci_name(pdev); + mci->edac_check = x38_check; + mci->ctl_page_to_phys = NULL; + mci->pvt_info = window; + + stacked = x38_is_stacked(pdev, drbs); + + /* + * The dram rank boundary (DRB) reg values are boundary addresses + * for each DRAM rank with a granularity of 64MB. DRB regs are + * cumulative; the last one will contain the total memory + * contained in all ranks. + */ + last_page = -1UL; + for (i = 0; i < mci->nr_csrows; i++) { + unsigned long nr_pages; + struct csrow_info *csrow = &mci->csrows[i]; + + nr_pages = drb_to_nr_pages(drbs, stacked, + i / X38_RANKS_PER_CHANNEL, + i % X38_RANKS_PER_CHANNEL); + + if (nr_pages == 0) { + csrow->mtype = MEM_EMPTY; + continue; + } + + csrow->first_page = last_page + 1; + last_page += nr_pages; + csrow->last_page = last_page; + csrow->nr_pages = nr_pages; + + csrow->grain = nr_pages << PAGE_SHIFT; + csrow->mtype = MEM_DDR2; + csrow->dtype = DEV_UNKNOWN; + csrow->edac_mode = EDAC_UNKNOWN; + } + + x38_clear_error_info(mci); + + rc = -ENODEV; + if (edac_mc_add_mc(mci)) { + debugf3("MC: %s(): failed edac_mc_add_mc()\n", __func__); + goto fail; + } + + /* get this far and it's successful */ + debugf3("MC: %s(): success\n", __func__); + return 0; + +fail: + iounmap(window); + if (mci) + edac_mc_free(mci); + + return rc; +} + +static int __devinit x38_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int rc; + + debugf0("MC: %s()\n", __func__); + + if (pci_enable_device(pdev) < 0) + return -EIO; + + rc = x38_probe1(pdev, ent->driver_data); + if (!mci_pdev) + mci_pdev = pci_dev_get(pdev); + + return rc; +} + +static void __devexit x38_remove_one(struct pci_dev *pdev) +{ + struct mem_ctl_info *mci; + + debugf0("%s()\n", __func__); + + mci = edac_mc_del_mc(&pdev->dev); + if (!mci) + return; + + iounmap(mci->pvt_info); + + edac_mc_free(mci); +} + +static const struct pci_device_id x38_pci_tbl[] __devinitdata = { + { + PCI_VEND_DEV(INTEL, X38_HB), PCI_ANY_ID, PCI_ANY_ID, 0, 0, + X38}, + { + 0, + } /* 0 terminated list. */ +}; + +MODULE_DEVICE_TABLE(pci, x38_pci_tbl); + +static struct pci_driver x38_driver = { + .name = EDAC_MOD_STR, + .probe = x38_init_one, + .remove = __devexit_p(x38_remove_one), + .id_table = x38_pci_tbl, +}; + +static int __init x38_init(void) +{ + int pci_rc; + + debugf3("MC: %s()\n", __func__); + + /* Ensure that the OPSTATE is set correctly for POLL or NMI */ + opstate_init(); + + pci_rc = pci_register_driver(&x38_driver); + if (pci_rc < 0) + goto fail0; + + if (!mci_pdev) { + x38_registered = 0; + mci_pdev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_X38_HB, NULL); + if (!mci_pdev) { + debugf0("x38 pci_get_device fail\n"); + pci_rc = -ENODEV; + goto fail1; + } + + pci_rc = x38_init_one(mci_pdev, x38_pci_tbl); + if (pci_rc < 0) { + debugf0("x38 init fail\n"); + pci_rc = -ENODEV; + goto fail1; + } + } + + return 0; + +fail1: + pci_unregister_driver(&x38_driver); + +fail0: + if (mci_pdev) + pci_dev_put(mci_pdev); + + return pci_rc; +} + +static void __exit x38_exit(void) +{ + debugf3("MC: %s()\n", __func__); + + pci_unregister_driver(&x38_driver); + if (!x38_registered) { + x38_remove_one(mci_pdev); + pci_dev_put(mci_pdev); + } +} + +module_init(x38_init); +module_exit(x38_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Cluster Computing, Inc. Hitoshi Mitake"); +MODULE_DESCRIPTION("MC support for Intel X38 memory hub controllers"); + +module_param(edac_op_state, int, 0444); +MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI"); diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 251416f..8e16bfb 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -476,6 +476,7 @@ static int ar_context_add_page(struct ar_context *ctx) if (ab == NULL) return -ENOMEM; + ab->next = NULL; memset(&ab->descriptor, 0, sizeof(ab->descriptor)); ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | DESCRIPTOR_STATUS | @@ -496,6 +497,21 @@ static int ar_context_add_page(struct ar_context *ctx) return 0; } +static void ar_context_release(struct ar_context *ctx) +{ + struct ar_buffer *ab, *ab_next; + size_t offset; + dma_addr_t ab_bus; + + for (ab = ctx->current_buffer; ab; ab = ab_next) { + ab_next = ab->next; + offset = offsetof(struct ar_buffer, data); + ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE, + ab, ab_bus); + } +} + #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) #define cond_le32_to_cpu(v) \ (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) @@ -2349,8 +2365,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); if (ohci == NULL) { - fw_error("Could not malloc fw_ohci data.\n"); - return -ENOMEM; + err = -ENOMEM; + goto fail; } fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); @@ -2359,7 +2375,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) err = pci_enable_device(dev); if (err) { - fw_error("Failed to enable OHCI hardware.\n"); + fw_error("Failed to enable OHCI hardware\n"); goto fail_free; } @@ -2427,9 +2443,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) ohci->ir_context_list = kzalloc(size, GFP_KERNEL); if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { - fw_error("Out of memory for it/ir contexts.\n"); err = -ENOMEM; - goto fail_registers; + goto fail_contexts; } /* self-id dma buffer allocation */ @@ -2438,9 +2453,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) &ohci->self_id_bus, GFP_KERNEL); if (ohci->self_id_cpu == NULL) { - fw_error("Out of memory for self ID buffer.\n"); err = -ENOMEM; - goto fail_registers; + goto fail_contexts; } bus_options = reg_read(ohci, OHCI1394_BusOptions); @@ -2460,9 +2474,13 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) fail_self_id: dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, ohci->self_id_cpu, ohci->self_id_bus); - fail_registers: - kfree(ohci->it_context_list); + fail_contexts: kfree(ohci->ir_context_list); + kfree(ohci->it_context_list); + context_release(&ohci->at_response_ctx); + context_release(&ohci->at_request_ctx); + ar_context_release(&ohci->ar_response_ctx); + ar_context_release(&ohci->ar_request_ctx); pci_iounmap(dev, ohci->registers); fail_iomem: pci_release_region(dev, 0); @@ -2471,6 +2489,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) fail_free: kfree(&ohci->card); ohci_pmac_off(dev); + fail: + if (err == -ENOMEM) + fw_error("Out of memory\n"); return err; } @@ -2491,8 +2512,19 @@ static void pci_remove(struct pci_dev *dev) software_reset(ohci); free_irq(dev->irq, ohci); + + if (ohci->next_config_rom && ohci->next_config_rom != ohci->config_rom) + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, + ohci->next_config_rom, ohci->next_config_rom_bus); + if (ohci->config_rom) + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, + ohci->config_rom, ohci->config_rom_bus); dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, ohci->self_id_cpu, ohci->self_id_bus); + ar_context_release(&ohci->ar_request_ctx); + ar_context_release(&ohci->ar_response_ctx); + context_release(&ohci->at_request_ctx); + context_release(&ohci->at_response_ctx); kfree(ohci->it_context_list); kfree(ohci->ir_context_list); pci_iounmap(dev, ohci->registers); diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index ef0b9b4..d334cac 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -173,6 +173,9 @@ struct sbp2_target { int blocked; /* ditto */ }; +/* Impossible login_id, to detect logout attempt before successful login */ +#define INVALID_LOGIN_ID 0x10000 + /* * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be * provided in the config rom. Most devices do provide a value, which @@ -788,9 +791,20 @@ static void sbp2_release_target(struct kref *kref) scsi_remove_device(sdev); scsi_device_put(sdev); } - sbp2_send_management_orb(lu, tgt->node_id, lu->generation, - SBP2_LOGOUT_REQUEST, lu->login_id, NULL); - + if (lu->login_id != INVALID_LOGIN_ID) { + int generation, node_id; + /* + * tgt->node_id may be obsolete here if we failed + * during initial login or after a bus reset where + * the topology changed. + */ + generation = device->generation; + smp_rmb(); /* node_id vs. generation */ + node_id = device->node_id; + sbp2_send_management_orb(lu, node_id, generation, + SBP2_LOGOUT_REQUEST, + lu->login_id, NULL); + } fw_core_remove_address_handler(&lu->address_handler); list_del(&lu->link); kfree(lu); @@ -805,19 +819,20 @@ static void sbp2_release_target(struct kref *kref) static struct workqueue_struct *sbp2_wq; +static void sbp2_target_put(struct sbp2_target *tgt) +{ + kref_put(&tgt->kref, sbp2_release_target); +} + /* * Always get the target's kref when scheduling work on one its units. * Each workqueue job is responsible to call sbp2_target_put() upon return. */ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) { - if (queue_delayed_work(sbp2_wq, &lu->work, delay)) - kref_get(&lu->tgt->kref); -} - -static void sbp2_target_put(struct sbp2_target *tgt) -{ - kref_put(&tgt->kref, sbp2_release_target); + kref_get(&lu->tgt->kref); + if (!queue_delayed_work(sbp2_wq, &lu->work, delay)) + sbp2_target_put(lu->tgt); } /* @@ -978,6 +993,7 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) lu->tgt = tgt; lu->lun = lun_entry & 0xffff; + lu->login_id = INVALID_LOGIN_ID; lu->retries = 0; lu->has_sdev = false; lu->blocked = false; @@ -1147,7 +1163,7 @@ static int sbp2_probe(struct device *dev) /* Do the login in a workqueue so we can easily reschedule retries. */ list_for_each_entry(lu, &tgt->lu_list, link) - sbp2_queue_work(lu, 0); + sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); return 0; fail_tgt_put: diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index c1b8107..5e204713 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c @@ -413,7 +413,7 @@ static void update_tree(struct fw_card *card, struct fw_node *root) { struct list_head list0, list1; - struct fw_node *node0, *node1; + struct fw_node *node0, *node1, *next1; int i, event; INIT_LIST_HEAD(&list0); @@ -485,7 +485,9 @@ update_tree(struct fw_card *card, struct fw_node *root) } node0 = fw_node(node0->link.next); - node1 = fw_node(node1->link.next); + next1 = fw_node(node1->link.next); + fw_node_put(node1); + node1 = next1; } } diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 027f58ce..aed7dbb 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -248,7 +248,7 @@ struct fw_card { struct fw_node *local_node; struct fw_node *root_node; struct fw_node *irm_node; - int color; + u8 color; /* must be u8 to match the definition in struct fw_node */ int gap_count; bool beta_repeaters_present; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 743e6f8..1903e75 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1263,6 +1263,7 @@ static const struct hid_device_id hid_blacklist[] = { { 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_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, diff --git a/drivers/hid/hid-dell.c b/drivers/hid/hid-dell.c index 1a0d0df..f5474300 100644 --- a/drivers/hid/hid-dell.c +++ b/drivers/hid/hid-dell.c @@ -48,6 +48,7 @@ err_free: 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) }, + { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) }, { } }; MODULE_DEVICE_TABLE(hid, dell_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index a0d6a6c..5cc4042 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -163,6 +163,9 @@ #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc +#define USB_VENDOR_ID_GENERIC_13BA 0x13ba +#define USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE 0x0017 + #define USB_VENDOR_ID_GLAB 0x06c2 #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 #define USB_DEVICE_ID_1_PHIDGETSERVO_30 0x0039 diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 42bdd83..18e5ddd 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include <linux/list.h> #include <linux/mm.h> +#include <linux/mutex.h> #include <linux/smp_lock.h> #include <linux/spinlock.h> #include <asm/unaligned.h> @@ -776,21 +777,10 @@ 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; + struct usbhid_device *usbhid = hid->driver_data; 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; - } - - hid->driver_data = usbhid; - usbhid->hid = hid; - usbhid->bufsize = HID_MIN_BUFFER_SIZE; hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); @@ -804,6 +794,7 @@ static int usbhid_start(struct hid_device *hid) if (insize > HID_MAX_BUFFER_SIZE) insize = HID_MAX_BUFFER_SIZE; + mutex_lock(&usbhid->setup); if (hid_alloc_buffers(dev, hid)) { ret = -ENOMEM; goto fail; @@ -888,6 +879,9 @@ static int usbhid_start(struct hid_device *hid) usbhid_init_reports(hid); hid_dump_device(hid); + set_bit(HID_STARTED, &usbhid->iofl); + mutex_unlock(&usbhid->setup); + return 0; fail: @@ -895,8 +889,7 @@ fail: usb_free_urb(usbhid->urbout); usb_free_urb(usbhid->urbctrl); hid_free_buffers(dev, hid); - kfree(usbhid); -err: + mutex_unlock(&usbhid->setup); return ret; } @@ -907,6 +900,8 @@ static void usbhid_stop(struct hid_device *hid) if (WARN_ON(!usbhid)) return; + mutex_lock(&usbhid->setup); + clear_bit(HID_STARTED, &usbhid->iofl); spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ set_bit(HID_DISCONNECTED, &usbhid->iofl); spin_unlock_irq(&usbhid->inlock); @@ -931,8 +926,7 @@ static void usbhid_stop(struct hid_device *hid) usb_free_urb(usbhid->urbout); hid_free_buffers(hid_to_usb_dev(hid), hid); - kfree(usbhid); - hid->driver_data = NULL; + mutex_unlock(&usbhid->setup); } static struct hid_ll_driver usb_hid_driver = { @@ -947,6 +941,7 @@ static struct hid_ll_driver usb_hid_driver = { static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); + struct usbhid_device *usbhid; struct hid_device *hid; size_t len; int ret; @@ -1000,14 +995,26 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; + usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL); + if (usbhid == NULL) { + ret = -ENOMEM; + goto err; + } + + hid->driver_data = usbhid; + usbhid->hid = hid; + mutex_init(&usbhid->setup); /* needed on suspend/resume */ + ret = hid_add_device(hid); if (ret) { if (ret != -ENODEV) dev_err(&intf->dev, "can't add hid device: %d\n", ret); - goto err; + goto err_free; } return 0; +err_free: + kfree(usbhid); err: hid_destroy_device(hid); return ret; @@ -1016,11 +1023,14 @@ err: static void hid_disconnect(struct usb_interface *intf) { struct hid_device *hid = usb_get_intfdata(intf); + struct usbhid_device *usbhid; if (WARN_ON(!hid)) return; + usbhid = hid->driver_data; hid_destroy_device(hid); + kfree(usbhid); } static int hid_suspend(struct usb_interface *intf, pm_message_t message) @@ -1028,11 +1038,18 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) struct hid_device *hid = usb_get_intfdata (intf); struct usbhid_device *usbhid = hid->driver_data; + mutex_lock(&usbhid->setup); + if (!test_bit(HID_STARTED, &usbhid->iofl)) { + mutex_unlock(&usbhid->setup); + return 0; + } + spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ set_bit(HID_SUSPENDED, &usbhid->iofl); spin_unlock_irq(&usbhid->inlock); - del_timer(&usbhid->io_retry); + del_timer_sync(&usbhid->io_retry); usb_kill_urb(usbhid->urbin); + mutex_unlock(&usbhid->setup); dev_dbg(&intf->dev, "suspend\n"); return 0; } @@ -1043,9 +1060,16 @@ static int hid_resume(struct usb_interface *intf) struct usbhid_device *usbhid = hid->driver_data; int status; + mutex_lock(&usbhid->setup); + if (!test_bit(HID_STARTED, &usbhid->iofl)) { + mutex_unlock(&usbhid->setup); + return 0; + } + clear_bit(HID_SUSPENDED, &usbhid->iofl); usbhid->retry_delay = 0; status = hid_start_in(hid); + mutex_unlock(&usbhid->setup); dev_dbg(&intf->dev, "resume status %d\n", status); return status; } diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index abedb13..55973ff 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -27,6 +27,7 @@ #include <linux/types.h> #include <linux/slab.h> #include <linux/list.h> +#include <linux/mutex.h> #include <linux/timer.h> #include <linux/wait.h> #include <linux/workqueue.h> @@ -73,6 +74,7 @@ struct usbhid_device { dma_addr_t outbuf_dma; /* Output buffer dma */ spinlock_t outlock; /* Output fifo spinlock */ + struct mutex setup; unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ struct timer_list io_retry; /* Retry timer */ unsigned long stop_retry; /* Time to give up, in jiffies */ diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index c772e02..1fac4e2 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -507,7 +507,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int unsigned long timeout; int ret; - if (!readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN) + if (!(readl(i2c->regs + S3C2410_IICCON) & S3C2410_IICCON_IRQEN)) return -EIO; ret = s3c24xx_i2c_set_master(i2c); diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index c3022a0..e4c9853 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c @@ -81,6 +81,7 @@ static struct i2c_algo_bit_data scx200_i2c_data = { static struct i2c_adapter scx200_i2c_ops = { .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, .id = I2C_HW_B_SCX200, .algo_data = &scx200_i2c_data, .name = "NatSemi SCx200 I2C", diff --git a/drivers/input/misc/sgi_btns.c b/drivers/input/misc/sgi_btns.c index ce238f5..be3a15f 100644 --- a/drivers/input/misc/sgi_btns.c +++ b/drivers/input/misc/sgi_btns.c @@ -174,5 +174,6 @@ static void __exit sgi_buttons_exit(void) platform_driver_unregister(&sgi_buttons_driver); } +MODULE_LICENSE("GPL"); module_init(sgi_buttons_init); module_exit(sgi_buttons_exit); diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c index f1fddb1..2768c69 100644 --- a/drivers/leds/leds-da903x.c +++ b/drivers/leds/leds-da903x.c @@ -17,6 +17,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/leds.h> +#include <linux/workqueue.h> #include <linux/mfd/da903x.h> #define DA9030_LED1_CONTROL 0x20 diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 92dcc06..9d7b53e 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -656,9 +656,10 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures) return; if (!ms->log_failure) { - while ((bio = bio_list_pop(failures))) + while ((bio = bio_list_pop(failures))) { ms->in_sync = 0; dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); + } return; } diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index b2d9d1a..6c96db2 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -229,19 +229,21 @@ static void __insert_origin(struct origin *o) */ static int register_snapshot(struct dm_snapshot *snap) { - struct origin *o; + struct origin *o, *new_o; struct block_device *bdev = snap->origin->bdev; + new_o = kmalloc(sizeof(*new_o), GFP_KERNEL); + if (!new_o) + return -ENOMEM; + down_write(&_origins_lock); o = __lookup_origin(bdev); - if (!o) { + if (o) + kfree(new_o); + else { /* New origin */ - o = kmalloc(sizeof(*o), GFP_KERNEL); - if (!o) { - up_write(&_origins_lock); - return -ENOMEM; - } + o = new_o; /* Initialise the struct */ INIT_LIST_HEAD(&o->snapshots); @@ -368,6 +370,7 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps struct dm_snap_pending_exception *pe = mempool_alloc(s->pending_pool, GFP_NOIO); + atomic_inc(&s->pending_exceptions_count); pe->snap = s; return pe; @@ -375,7 +378,11 @@ static struct dm_snap_pending_exception *alloc_pending_exception(struct dm_snaps static void free_pending_exception(struct dm_snap_pending_exception *pe) { - mempool_free(pe, pe->snap->pending_pool); + struct dm_snapshot *s = pe->snap; + + mempool_free(pe, s->pending_pool); + smp_mb__before_atomic_dec(); + atomic_dec(&s->pending_exceptions_count); } static void insert_completed_exception(struct dm_snapshot *s, @@ -600,6 +607,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->valid = 1; s->active = 0; + atomic_set(&s->pending_exceptions_count, 0); init_rwsem(&s->lock); spin_lock_init(&s->pe_lock); s->ti = ti; @@ -726,6 +734,14 @@ static void snapshot_dtr(struct dm_target *ti) /* After this returns there can be no new kcopyd jobs. */ unregister_snapshot(s); + while (atomic_read(&s->pending_exceptions_count)) + yield(); + /* + * Ensure instructions in mempool_destroy aren't reordered + * before atomic_read. + */ + smp_mb(); + #ifdef CONFIG_DM_DEBUG for (i = 0; i < DM_TRACKED_CHUNK_HASH_SIZE; i++) BUG_ON(!hlist_empty(&s->tracked_chunk_hash[i])); diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index f07315f..99c0106 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h @@ -160,6 +160,8 @@ struct dm_snapshot { mempool_t *pending_pool; + atomic_t pending_exceptions_count; + struct exception_table pending; struct exception_table complete; diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 11a617a..84bdc2e 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -567,8 +567,8 @@ static void i2o_block_biosparam(unsigned long capacity, unsigned short *cyls, /** * i2o_block_open - Open the block device - * @inode: inode for block device being opened - * @file: file to open + * @bdev: block device being opened + * @mode: file open mode * * Power up the device, mount and lock the media. This function is called, * if the block device is opened for access. @@ -596,8 +596,8 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) /** * i2o_block_release - Release the I2O block device - * @inode: inode for block device being released - * @file: file to close + * @disk: gendisk device being released + * @mode: file open mode * * Unlock and unmount the media, and power down the device. Gets called if * the block device is closed. @@ -643,8 +643,8 @@ static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) /** * i2o_block_ioctl - Issue device specific ioctl calls. - * @inode: inode for block device ioctl - * @file: file for ioctl + * @bdev: block device being opened + * @mode: file open mode * @cmd: ioctl command * @arg: arg * diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 08e26be..ce39fa5 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -113,7 +113,6 @@ static int hdpu_nexus_probe(struct platform_device *pdev) if (!hdpu_chassis_id) printk(KERN_WARNING "sky_nexus: " "Unable to create proc dir entry: sky_chassis_id\n"); - } return 0; } diff --git a/drivers/misc/sgi-xp/Makefile b/drivers/misc/sgi-xp/Makefile index 35ce285..4fc40d8e 100644 --- a/drivers/misc/sgi-xp/Makefile +++ b/drivers/misc/sgi-xp/Makefile @@ -5,14 +5,14 @@ obj-$(CONFIG_SGI_XP) += xp.o xp-y := xp_main.o xp-$(CONFIG_IA64_SGI_SN2) += xp_sn2.o xp_nofault.o -xp-$(CONFIG_IA64_GENERIC) += xp_sn2.o xp_nofault.o xp_uv.o +xp-$(CONFIG_IA64_GENERIC) += xp_sn2.o xp_nofault.o xp-$(CONFIG_IA64_SGI_UV) += xp_uv.o xp-$(CONFIG_X86_64) += xp_uv.o obj-$(CONFIG_SGI_XP) += xpc.o xpc-y := xpc_main.o xpc_channel.o xpc_partition.o xpc-$(CONFIG_IA64_SGI_SN2) += xpc_sn2.o -xpc-$(CONFIG_IA64_GENERIC) += xpc_sn2.o xpc_uv.o +xpc-$(CONFIG_IA64_GENERIC) += xpc_sn2.o xpc-$(CONFIG_IA64_SGI_UV) += xpc_uv.o xpc-$(CONFIG_X86_64) += xpc_uv.o diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h index 859a528..ed1722e 100644 --- a/drivers/misc/sgi-xp/xp.h +++ b/drivers/misc/sgi-xp/xp.h @@ -19,7 +19,11 @@ #include <asm/system.h> #include <asm/sn/arch.h> /* defines is_shub1() and is_shub2() */ #define is_shub() ia64_platform_is("sn2") +#ifdef CONFIG_IA64_SGI_UV #define is_uv() ia64_platform_is("uv") +#else +#define is_uv() 0 +#endif #endif #ifdef CONFIG_X86_64 #include <asm/genapic.h> diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 46325fc..e8d5cfb 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -1104,7 +1104,7 @@ xpc_do_exit(enum xp_retval reason) if (is_shub()) xpc_exit_sn2(); - else + else if (is_uv()) xpc_exit_uv(); } @@ -1363,7 +1363,7 @@ out_2: out_1: if (is_shub()) xpc_exit_sn2(); - else + else if (is_uv()) xpc_exit_uv(); return ret; } diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 5a97d3a..f483c42 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -2315,8 +2315,10 @@ end: */ static int sony_pic_disable(struct acpi_device *device) { - if (ACPI_FAILURE(acpi_evaluate_object(device->handle, - "_DIS", NULL, NULL))) + acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL, + NULL); + + if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND) return -ENXIO; dprintk("Device disabled\n"); diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index c54967f..ba1be0b 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -833,12 +833,14 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget) } while(intr0 & RINT0); - /* Receive descriptor is empty now */ - spin_lock_irqsave(&lp->lock, flags); - __netif_rx_complete(dev, napi); - writel(VAL0|RINTEN0, mmio + INTEN0); - writel(VAL2 | RDMD0, mmio + CMD0); - spin_unlock_irqrestore(&lp->lock, flags); + if (rx_pkt_limit > 0) { + /* Receive descriptor is empty now */ + spin_lock_irqsave(&lp->lock, flags); + __netif_rx_complete(dev, napi); + writel(VAL0|RINTEN0, mmio + INTEN0); + writel(VAL2 | RDMD0, mmio + CMD0); + spin_unlock_irqrestore(&lp->lock, flags); + } rx_not_empty: return num_rx_pkt; diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 82dd1a8..002d918 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0094" +#define DRV_VERSION "EHEA_0095" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 9b61dc9..9d00687 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -632,10 +632,13 @@ static void ehea_rebuild_busmap(void) } } -static int ehea_update_busmap(unsigned long pfn, unsigned long pgnum, int add) +static int ehea_update_busmap(unsigned long pfn, unsigned long nr_pages, int add) { unsigned long i, start_section, end_section; + if (!nr_pages) + return 0; + if (!ehea_bmap) { ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); if (!ehea_bmap) @@ -643,7 +646,7 @@ static int ehea_update_busmap(unsigned long pfn, unsigned long pgnum, int add) } start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE; - end_section = start_section + ((pgnum * PAGE_SIZE) / EHEA_SECTSIZE); + end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE); /* Mark entries as valid or invalid only; address is assigned later */ for (i = start_section; i < end_section; i++) { u64 flag; @@ -692,10 +695,54 @@ int ehea_rem_sect_bmap(unsigned long pfn, unsigned long nr_pages) return ret; } -static int ehea_create_busmap_callback(unsigned long pfn, - unsigned long nr_pages, void *arg) +static int ehea_is_hugepage(unsigned long pfn) +{ + int page_order; + + if (pfn & EHEA_HUGEPAGE_PFN_MASK) + return 0; + + page_order = compound_order(pfn_to_page(pfn)); + if (page_order + PAGE_SHIFT != EHEA_HUGEPAGESHIFT) + return 0; + + return 1; +} + +static int ehea_create_busmap_callback(unsigned long initial_pfn, + unsigned long total_nr_pages, void *arg) { - return ehea_update_busmap(pfn, nr_pages, EHEA_BUSMAP_ADD_SECT); + int ret; + unsigned long pfn, start_pfn, end_pfn, nr_pages; + + if ((total_nr_pages * PAGE_SIZE) < EHEA_HUGEPAGE_SIZE) + return ehea_update_busmap(initial_pfn, total_nr_pages, + EHEA_BUSMAP_ADD_SECT); + + /* Given chunk is >= 16GB -> check for hugepages */ + start_pfn = initial_pfn; + end_pfn = initial_pfn + total_nr_pages; + pfn = start_pfn; + + while (pfn < end_pfn) { + if (ehea_is_hugepage(pfn)) { + /* Add mem found in front of the hugepage */ + nr_pages = pfn - start_pfn; + ret = ehea_update_busmap(start_pfn, nr_pages, + EHEA_BUSMAP_ADD_SECT); + if (ret) + return ret; + + /* Skip the hugepage */ + pfn += (EHEA_HUGEPAGE_SIZE / PAGE_SIZE); + start_pfn = pfn; + } else + pfn += (EHEA_SECTSIZE / PAGE_SIZE); + } + + /* Add mem found behind the hugepage(s) */ + nr_pages = pfn - start_pfn; + return ehea_update_busmap(start_pfn, nr_pages, EHEA_BUSMAP_ADD_SECT); } int ehea_create_busmap(void) diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h index 1e58dc0..0817c1e 100644 --- a/drivers/net/ehea/ehea_qmr.h +++ b/drivers/net/ehea/ehea_qmr.h @@ -40,6 +40,9 @@ #define EHEA_PAGESIZE (1UL << EHEA_PAGESHIFT) #define EHEA_SECTSIZE (1UL << 24) #define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> EHEA_PAGESHIFT) +#define EHEA_HUGEPAGESHIFT 34 +#define EHEA_HUGEPAGE_SIZE (1UL << EHEA_HUGEPAGESHIFT) +#define EHEA_HUGEPAGE_PFN_MASK ((EHEA_HUGEPAGE_SIZE - 1) >> PAGE_SHIFT) #if ((1UL << SECTION_SIZE_BITS) < EHEA_SECTSIZE) #error eHEA module cannot work if kernel sectionsize < ehea sectionsize diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 2ee262225..901212a 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2605,7 +2605,7 @@ static int __devinit emac_init_config(struct emac_instance *dev) 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")) { -#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CONTROL +#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x; #else printk(KERN_ERR "%s: Flow control not disabled!\n", diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 1b0eebf..4b9794e 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -35,7 +35,6 @@ #include <linux/module.h> #include <linux/delay.h> #include <linux/netdevice.h> -#include <linux/cpumask.h> #include <linux/mlx4/driver.h> #include <linux/mlx4/device.h> diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index be09fdb..cee199c 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -360,9 +360,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_PORT_ETH_MTU_OFFSET 0x02 #define QUERY_PORT_WIDTH_OFFSET 0x06 #define QUERY_PORT_MAX_GID_PKEY_OFFSET 0x07 -#define QUERY_PORT_MAC_OFFSET 0x08 #define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a #define QUERY_PORT_MAX_VL_OFFSET 0x0b +#define QUERY_PORT_MAC_OFFSET 0x10 for (i = 1; i <= dev_cap->num_ports; ++i) { err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT, diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 8e46a51..c91852f4 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -420,9 +420,13 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, /* Allocate Tx/Rx descriptor memory */ db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr); + if (!db->desc_pool_ptr) + goto err_out_res; db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr); + if (!db->buf_pool_ptr) + goto err_out_free_desc; db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr; db->first_tx_desc_dma = db->desc_pool_dma_ptr; @@ -469,7 +473,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, err = register_netdev (dev); if (err) - goto err_out_res; + goto err_out_free_buf; printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, " "%s, irq %d.\n", @@ -483,6 +487,12 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, return 0; +err_out_free_buf: + pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, + db->buf_pool_ptr, db->buf_pool_dma_ptr); +err_out_free_desc: + pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, + db->desc_pool_ptr, db->desc_pool_dma_ptr); err_out_res: pci_release_regions(pdev); err_out_disable: diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 78df2be..db3377da 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -396,6 +396,20 @@ static void dm9601_set_multicast(struct net_device *net) dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl); } +static int dm9601_set_mac_address(struct net_device *net, void *p) +{ + struct sockaddr *addr = p; + struct usbnet *dev = netdev_priv(net); + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + memcpy(net->dev_addr, addr->sa_data, net->addr_len); + dm_write_async(dev, DM_PHY_ADDR, net->addr_len, net->dev_addr); + + return 0; +} + static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) { int ret; @@ -406,6 +420,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->do_ioctl = dm9601_ioctl; dev->net->set_multicast_list = dm9601_set_multicast; + dev->net->set_mac_address = dm9601_set_mac_address; dev->net->ethtool_ops = &dm9601_ethtool_ops; dev->net->hard_header_len += DM_TX_OVERHEAD; dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 2dced38..3590ea5 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -521,7 +521,7 @@ static void __devexit velocity_remove1(struct pci_dev *pdev) * we don't duplicate code for each option. */ -static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, char *devname) +static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, const char *devname) { if (val == -1) *opt = def; @@ -550,7 +550,7 @@ static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, * we don't duplicate code for each option. */ -static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, char *devname) +static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, const char *devname) { (*opt) &= (~flag); if (val == -1) @@ -576,7 +576,7 @@ static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 fla * for the current device */ -static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname) +static void __devinit velocity_get_options(struct velocity_opt *opts, int index, const char *devname) { velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname); @@ -863,6 +863,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi static int first = 1; struct net_device *dev; int i; + const char *drv_string; const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data]; struct velocity_info *vptr; struct mac_regs __iomem * regs; @@ -935,7 +936,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi dev->dev_addr[i] = readb(®s->PAR[i]); - velocity_get_options(&vptr->options, velocity_nics, dev->name); + drv_string = dev_driver_string(&pdev->dev); + + velocity_get_options(&vptr->options, velocity_nics, drv_string); /* * Mask out the options cannot be set to the chip diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index 327d585..6e92f7b 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c @@ -756,10 +756,11 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) case CISCO_ADDR_REQ: /* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */ { - struct in_device *in_dev; - struct in_ifaddr *ifa; __be32 addr = 0, mask = htonl(~0U); /* FIXME: is the mask correct? */ #ifdef CONFIG_INET + struct in_device *in_dev; + struct in_ifaddr *ifa; + rcu_read_lock(); if ((in_dev = __in_dev_get_rcu(dev)) != NULL) { diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 0f1d6bd..cfd4d05 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -661,8 +661,7 @@ ath5k_pci_resume(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - int i, err; + int err; pci_restore_state(pdev); @@ -688,16 +687,6 @@ ath5k_pci_resume(struct pci_dev *pdev) goto err_irq; ath5k_led_enable(sc); - /* - * Reset the key cache since some parts do not - * reset the contents on initial power up or resume. - * - * FIXME: This may need to be revisited when mac80211 becomes - * aware of suspend/resume. - */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); - return 0; err_irq: free_irq(pdev->irq, sc); @@ -718,7 +707,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; u8 mac[ETH_ALEN]; - unsigned int i; int ret; ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); @@ -737,13 +725,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) __set_bit(ATH_STAT_MRRETRY, sc->status); /* - * Reset the key cache since some parts do not - * reset the contents on initial power up. - */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); - - /* * Collect the channel list. The 802.11 layer * is resposible for filtering this list based * on settings like the phy mode and regulatory @@ -2202,7 +2183,8 @@ ath5k_beacon_config(struct ath5k_softc *sc) static int ath5k_init(struct ath5k_softc *sc, bool is_resume) { - int ret; + struct ath5k_hw *ah = sc->ah; + int ret, i; mutex_lock(&sc->lock); @@ -2235,10 +2217,17 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume) if (ret) goto done; + /* + * Reset the key cache since some parts do not reset the + * contents on initial power up or resume from suspend. + */ + for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) + ath5k_hw_reset_key(ah, i); + __set_bit(ATH_STAT_STARTED, sc->status); /* Set ack to be sent at low bit-rates */ - ath5k_hw_set_ack_bitrate_high(sc->ah, false); + ath5k_hw_set_ack_bitrate_high(ah, false); mod_timer(&sc->calib_tim, round_jiffies(jiffies + msecs_to_jiffies(ath5k_calinterval * 1000))); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 5749f22..079e6aa 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -328,7 +328,7 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, lbs_deb_rx("rx err: frame received with bad length\n"); priv->stats.rx_length_errors++; ret = -EINVAL; - kfree(skb); + kfree_skb(skb); goto done; } diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 2d022f8..827ca03 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -319,7 +319,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) void *tmp; int err; u8 *end = (u8 *)eeprom + len; - u16 synth; + u16 synth = 0; DECLARE_MAC_BUF(mac); wrap = (struct eeprom_pda_wrap *) eeprom; @@ -422,7 +422,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) entry = (void *)entry + (entry_len + 1)*2; } - if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) { + if (!synth || !priv->iq_autocal || !priv->output_limit || + !priv->curve_data) { printk(KERN_ERR "p54: not all required entries found in eeprom!\n"); err = -EINVAL; goto err; diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 1c2a02a..88b3cad 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -346,68 +346,6 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy)); } -static int p54p_open(struct ieee80211_hw *dev) -{ - struct p54p_priv *priv = dev->priv; - int err; - - init_completion(&priv->boot_comp); - err = request_irq(priv->pdev->irq, &p54p_interrupt, - IRQF_SHARED, "p54pci", dev); - if (err) { - printk(KERN_ERR "%s: failed to register IRQ handler\n", - wiphy_name(dev->wiphy)); - return err; - } - - memset(priv->ring_control, 0, sizeof(*priv->ring_control)); - err = p54p_upload_firmware(dev); - if (err) { - free_irq(priv->pdev->irq, dev); - return err; - } - priv->rx_idx_data = priv->tx_idx_data = 0; - priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; - - p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data, - ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data); - - p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, - ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); - - P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); - P54P_READ(ring_control_base); - wmb(); - udelay(10); - - P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT)); - P54P_READ(int_enable); - wmb(); - udelay(10); - - P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); - P54P_READ(dev_int); - - if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { - printk(KERN_ERR "%s: Cannot boot firmware!\n", - wiphy_name(dev->wiphy)); - free_irq(priv->pdev->irq, dev); - return -ETIMEDOUT; - } - - P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)); - P54P_READ(int_enable); - wmb(); - udelay(10); - - P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); - P54P_READ(dev_int); - wmb(); - udelay(10); - - return 0; -} - static void p54p_stop(struct ieee80211_hw *dev) { struct p54p_priv *priv = dev->priv; @@ -474,6 +412,68 @@ static void p54p_stop(struct ieee80211_hw *dev) memset(ring_control, 0, sizeof(*ring_control)); } +static int p54p_open(struct ieee80211_hw *dev) +{ + struct p54p_priv *priv = dev->priv; + int err; + + init_completion(&priv->boot_comp); + err = request_irq(priv->pdev->irq, &p54p_interrupt, + IRQF_SHARED, "p54pci", dev); + if (err) { + printk(KERN_ERR "%s: failed to register IRQ handler\n", + wiphy_name(dev->wiphy)); + return err; + } + + memset(priv->ring_control, 0, sizeof(*priv->ring_control)); + err = p54p_upload_firmware(dev); + if (err) { + free_irq(priv->pdev->irq, dev); + return err; + } + priv->rx_idx_data = priv->tx_idx_data = 0; + priv->rx_idx_mgmt = priv->tx_idx_mgmt = 0; + + p54p_refill_rx_ring(dev, 0, priv->ring_control->rx_data, + ARRAY_SIZE(priv->ring_control->rx_data), priv->rx_buf_data); + + p54p_refill_rx_ring(dev, 2, priv->ring_control->rx_mgmt, + ARRAY_SIZE(priv->ring_control->rx_mgmt), priv->rx_buf_mgmt); + + P54P_WRITE(ring_control_base, cpu_to_le32(priv->ring_control_dma)); + P54P_READ(ring_control_base); + wmb(); + udelay(10); + + P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_INIT)); + P54P_READ(int_enable); + wmb(); + udelay(10); + + P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); + P54P_READ(dev_int); + + if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { + printk(KERN_ERR "%s: Cannot boot firmware!\n", + wiphy_name(dev->wiphy)); + p54p_stop(dev); + return -ETIMEDOUT; + } + + P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)); + P54P_READ(int_enable); + wmb(); + udelay(10); + + P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_UPDATE)); + P54P_READ(dev_int); + wmb(); + udelay(10); + + return 0; +} + static int __devinit p54p_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -556,11 +556,13 @@ static int __devinit p54p_probe(struct pci_dev *pdev, spin_lock_init(&priv->lock); tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); - p54p_open(dev); + err = p54p_open(dev); + if (err) + goto err_free_common; err = p54_read_eeprom(dev); p54p_stop(dev); if (err) - goto err_free_desc; + goto err_free_common; err = ieee80211_register_hw(dev); if (err) { @@ -573,8 +575,6 @@ static int __devinit p54p_probe(struct pci_dev *pdev, err_free_common: p54_free_common(dev); - - err_free_desc: pci_free_consistent(pdev, sizeof(*priv->ring_control), priv->ring_control, priv->ring_control_dma); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 96cf8ec..bbf66ea 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -43,20 +43,6 @@ static void __devinit quirk_mellanox_tavor(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR,quirk_mellanox_tavor); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE,quirk_mellanox_tavor); -/* Many VIA bridges seem to corrupt data for DAC. Disable it here */ -int forbid_dac __read_mostly; -EXPORT_SYMBOL(forbid_dac); - -static __devinit void via_no_dac(struct pci_dev *dev) -{ - if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { - dev_info(&dev->dev, - "VIA PCI bridge detected. Disabling DAC.\n"); - forbid_dac = 1; - } -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); - /* Deal with broken BIOS'es that neglect to enable passive release, which can cause problems in combination with the 82441FX/PPro MTRRs */ static void quirk_passive_release(struct pci_dev *dev) diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index 3688e33..773b29c 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c @@ -79,6 +79,11 @@ struct da903x_regulator_info { int enable_bit; }; +static inline struct device *to_da903x_dev(struct regulator_dev *rdev) +{ + return rdev_get_dev(rdev)->parent->parent; +} + static inline int check_range(struct da903x_regulator_info *info, int min_uV, int max_uV) { @@ -93,7 +98,7 @@ 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; if (check_range(info, min_uV, max_uV)) { @@ -111,7 +116,7 @@ static int da903x_set_ldo_voltage(struct regulator_dev *rdev, 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; @@ -128,7 +133,7 @@ static int da903x_get_voltage(struct regulator_dev *rdev) 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; + struct device *da9034_dev = to_da903x_dev(rdev); return da903x_set_bits(da9034_dev, info->enable_reg, 1 << info->enable_bit); @@ -137,7 +142,7 @@ static int da903x_enable(struct regulator_dev *rdev) 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; + struct device *da9034_dev = to_da903x_dev(rdev); return da903x_clr_bits(da9034_dev, info->enable_reg, 1 << info->enable_bit); @@ -146,7 +151,7 @@ static int da903x_disable(struct regulator_dev *rdev) 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t reg_val; int ret; @@ -162,7 +167,7 @@ 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; + struct device *da903x_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; @@ -189,7 +194,7 @@ 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; + struct device *da903x_dev = to_da903x_dev(rdev); uint8_t val, mask; int thresh; @@ -215,7 +220,7 @@ static int da9030_set_ldo14_voltage(struct regulator_dev *rdev, 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; + struct device *da903x_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; @@ -238,7 +243,7 @@ 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; @@ -264,7 +269,7 @@ 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; if (check_range(info, min_uV, max_uV)) { @@ -283,7 +288,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, 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; + struct device *da9034_dev = to_da903x_dev(rdev); uint8_t val, mask; int ret; @@ -466,7 +471,7 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) 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); + rdev = regulator_register(&ri->desc, &pdev->dev, ri); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c index 37d131d..45e5b10 100644 --- a/drivers/rtc/rtc-ds3234.c +++ b/drivers/rtc/rtc-ds3234.c @@ -189,7 +189,7 @@ static const struct rtc_class_ops ds3234_rtc_ops = { .set_time = ds3234_set_time, }; -static int ds3234_probe(struct spi_device *spi) +static int __devinit ds3234_probe(struct spi_device *spi) { struct rtc_device *rtc; unsigned char tmp; @@ -249,7 +249,7 @@ static int ds3234_probe(struct spi_device *spi) return 0; } -static int __exit ds3234_remove(struct spi_device *spi) +static int __devexit ds3234_remove(struct spi_device *spi) { struct ds3234 *chip = platform_get_drvdata(spi); struct rtc_device *rtc = chip->rtc; diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 910bc70..f59277b 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -455,6 +455,8 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev) s3c_rtc_setfreq(&pdev->dev, 1); + device_init_wakeup(&pdev->dev, 1); + /* register RTC and exit */ rtc = rtc_device_register("s3c", &pdev->dev, &s3c_rtcops, @@ -507,7 +509,7 @@ static int s3c_rtc_resume(struct platform_device *pdev) #define s3c_rtc_resume NULL #endif -static struct platform_driver s3c2410_rtcdrv = { +static struct platform_driver s3c2410_rtc_driver = { .probe = s3c_rtc_probe, .remove = __devexit_p(s3c_rtc_remove), .suspend = s3c_rtc_suspend, @@ -523,12 +525,12 @@ static char __initdata banner[] = "S3C24XX RTC, (c) 2004,2006 Simtec Electronics static int __init s3c_rtc_init(void) { printk(banner); - return platform_driver_register(&s3c2410_rtcdrv); + return platform_driver_register(&s3c2410_rtc_driver); } static void __exit s3c_rtc_exit(void) { - platform_driver_unregister(&s3c2410_rtcdrv); + platform_driver_unregister(&s3c2410_rtc_driver); } module_init(s3c_rtc_init); diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 023803d..ae18baf 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -76,7 +76,7 @@ tapeblock_trigger_requeue(struct tape_device *device) static void tapeblock_end_request(struct request *req, int error) { - if (__blk_end_request(req, error, blk_rq_bytes(req))) + if (blk_end_request(req, error, blk_rq_bytes(req))) BUG(); } @@ -166,7 +166,7 @@ tapeblock_requeue(struct work_struct *work) { nr_queued++; spin_unlock(get_ccwdev_lock(device->cdev)); - spin_lock(&device->blk_data.request_queue_lock); + spin_lock_irq(&device->blk_data.request_queue_lock); while ( !blk_queue_plugged(queue) && elv_next_request(queue) && @@ -176,7 +176,9 @@ tapeblock_requeue(struct work_struct *work) { if (rq_data_dir(req) == WRITE) { DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); blkdev_dequeue_request(req); + spin_unlock_irq(&device->blk_data.request_queue_lock); tapeblock_end_request(req, -EIO); + spin_lock_irq(&device->blk_data.request_queue_lock); continue; } blkdev_dequeue_request(req); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index d7073db..f9bb51f 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -1200,7 +1200,7 @@ tape_open(struct tape_device *device) { int rc; - spin_lock(get_ccwdev_lock(device->cdev)); + spin_lock_irq(get_ccwdev_lock(device->cdev)); if (device->tape_state == TS_NOT_OPER) { DBF_EVENT(6, "TAPE:nodev\n"); rc = -ENODEV; @@ -1218,7 +1218,7 @@ tape_open(struct tape_device *device) tape_state_set(device, TS_IN_USE); rc = 0; } - spin_unlock(get_ccwdev_lock(device->cdev)); + spin_unlock_irq(get_ccwdev_lock(device->cdev)); return rc; } @@ -1228,11 +1228,11 @@ tape_open(struct tape_device *device) int tape_release(struct tape_device *device) { - spin_lock(get_ccwdev_lock(device->cdev)); + spin_lock_irq(get_ccwdev_lock(device->cdev)); if (device->tape_state == TS_IN_USE) tape_state_set(device, TS_UNUSED); module_put(device->discipline->owner); - spin_unlock(get_ccwdev_lock(device->cdev)); + spin_unlock_irq(get_ccwdev_lock(device->cdev)); return 0; } diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index b539082..f055903 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -20,6 +20,7 @@ static struct dentry *debugfs_root; #define MAX_DEBUGFS_QUEUES 32 static struct dentry *debugfs_queues[MAX_DEBUGFS_QUEUES] = { NULL }; static DEFINE_MUTEX(debugfs_mutex); +#define QDIO_DEBUGFS_NAME_LEN 40 void qdio_allocate_do_dbf(struct qdio_initialize *init_data) { @@ -152,17 +153,6 @@ static int qstat_seq_open(struct inode *inode, struct file *filp) filp->f_path.dentry->d_inode->i_private); } -static void get_queue_name(struct qdio_q *q, struct ccw_device *cdev, char *name) -{ - memset(name, 0, sizeof(name)); - sprintf(name, "%s", dev_name(&cdev->dev)); - if (q->is_input_q) - sprintf(name + strlen(name), "_input"); - else - sprintf(name + strlen(name), "_output"); - sprintf(name + strlen(name), "_%d", q->nr); -} - static void remove_debugfs_entry(struct qdio_q *q) { int i; @@ -189,14 +179,17 @@ static struct file_operations debugfs_fops = { static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) { int i = 0; - char name[40]; + char name[QDIO_DEBUGFS_NAME_LEN]; while (debugfs_queues[i] != NULL) { i++; if (i >= MAX_DEBUGFS_QUEUES) return; } - get_queue_name(q, cdev, name); + snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%s_%d", + dev_name(&cdev->dev), + q->is_input_q ? "input" : "output", + q->nr); debugfs_queues[i] = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR, debugfs_root, q, &debugfs_fops); } diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index a50682d..7c86591 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -1083,7 +1083,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, case -EIO: sprintf(dbf_text, "ierr%4x", irq_ptr->schid.sch_no); QDIO_DBF_TEXT2(1, setup, dbf_text); - qdio_int_error(cdev); return; case -ETIMEDOUT: sprintf(dbf_text, "qtoh%4x", irq_ptr->schid.sch_no); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 7de410d..52d2659 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3025,7 +3025,7 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill, int offset) { - int length = skb->len - offset; + int length = skb->len; int length_here; int element; char *data; @@ -3037,6 +3037,7 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb, if (offset >= 0) { data = skb->data + offset; + length -= offset; first_lap = 0; } diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 955ba7a..1b1e803 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -373,8 +373,6 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, 0, 1); - if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) - return -ERESTARTSYS; if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && (card->state == CARD_STATE_UP)) { @@ -451,12 +449,15 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card, netif_rx(skb); break; case QETH_HEADER_TYPE_OSN: - skb_push(skb, sizeof(struct qeth_hdr)); - skb_copy_to_linear_data(skb, hdr, + if (card->info.type == QETH_CARD_TYPE_OSN) { + skb_push(skb, sizeof(struct qeth_hdr)); + skb_copy_to_linear_data(skb, hdr, sizeof(struct qeth_hdr)); - len = skb->len; - card->osn_info.data_cb(skb); - break; + len = skb->len; + card->osn_info.data_cb(skb); + break; + } + /* else unknown */ default: dev_kfree_skb_any(skb); QETH_DBF_TEXT(TRACE, 3, "inbunkno"); @@ -975,12 +976,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1); - if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) { - PRINT_WARN("set_online of card %s interrupted by user!\n", - CARD_BUS_ID(card)); - return -ERESTARTSYS; - } - recover_flag = card->state; rc = ccw_device_set_online(CARD_RDEV(card)); if (rc) { @@ -1091,11 +1086,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, if (card->dev && netif_carrier_ok(card->dev)) netif_carrier_off(card->dev); recover_flag = card->state; - if (qeth_l2_stop_card(card, recovery_mode) == -ERESTARTSYS) { - PRINT_WARN("Stopping card %s interrupted by user!\n", - CARD_BUS_ID(card)); - return -ERESTARTSYS; - } + qeth_l2_stop_card(card, recovery_mode); rc = ccw_device_set_offline(CARD_DDEV(card)); rc2 = ccw_device_set_offline(CARD_WDEV(card)); rc3 = ccw_device_set_offline(CARD_RDEV(card)); diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 99547de..ed59fed 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2064,8 +2064,6 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, 0, 1); - if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) - return -ERESTARTSYS; if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && (card->state == CARD_STATE_UP)) { @@ -3049,11 +3047,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1); - if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) { - PRINT_WARN("set_online of card %s interrupted by user!\n", - CARD_BUS_ID(card)); - return -ERESTARTSYS; - } recover_flag = card->state; rc = ccw_device_set_online(CARD_RDEV(card)); @@ -3170,11 +3163,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, if (card->dev && netif_carrier_ok(card->dev)) netif_carrier_off(card->dev); recover_flag = card->state; - if (qeth_l3_stop_card(card, recovery_mode) == -ERESTARTSYS) { - PRINT_WARN("Stopping card %s interrupted by user!\n", - CARD_BUS_ID(card)); - return -ERESTARTSYS; - } + qeth_l3_stop_card(card, recovery_mode); rc = ccw_device_set_offline(CARD_DDEV(card)); rc2 = ccw_device_set_offline(CARD_WDEV(card)); rc3 = ccw_device_set_offline(CARD_RDEV(card)); diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 210ddb6..c144b99 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -121,9 +121,6 @@ static ssize_t qeth_l3_dev_route6_show(struct device *dev, if (!card) return -EINVAL; - if (!qeth_is_supported(card, IPA_IPV6)) - return sprintf(buf, "%s\n", "n/a"); - return qeth_l3_dev_route_show(card, &card->options.route6, buf); } @@ -135,10 +132,6 @@ static ssize_t qeth_l3_dev_route6_store(struct device *dev, if (!card) return -EINVAL; - if (!qeth_is_supported(card, IPA_IPV6)) { - return -EOPNOTSUPP; - } - return qeth_l3_dev_route_store(card, &card->options.route6, QETH_PROT_IPV6, buf, count); } diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 543811f..8e74657 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -133,7 +133,7 @@ static int usbtmc_release(struct inode *inode, struct file *file) static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data) { - char *buffer; + u8 *buffer; struct device *dev; int rv; int n; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index fc9018e..e1b4262 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -106,6 +106,9 @@ static DEFINE_SPINLOCK(hcd_root_hub_lock); /* used when updating an endpoint's URB list */ static DEFINE_SPINLOCK(hcd_urb_list_lock); +/* used to protect against unlinking URBs after the device is gone */ +static DEFINE_SPINLOCK(hcd_urb_unlink_lock); + /* wait queue for synchronous unlinks */ DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); @@ -1376,10 +1379,25 @@ static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) int usb_hcd_unlink_urb (struct urb *urb, int status) { struct usb_hcd *hcd; - int retval; + int retval = -EIDRM; + unsigned long flags; - hcd = bus_to_hcd(urb->dev->bus); - retval = unlink1(hcd, urb, status); + /* Prevent the device and bus from going away while + * the unlink is carried out. If they are already gone + * then urb->use_count must be 0, since disconnected + * devices can't have any active URBs. + */ + spin_lock_irqsave(&hcd_urb_unlink_lock, flags); + if (atomic_read(&urb->use_count) > 0) { + retval = 0; + usb_get_dev(urb->dev); + } + spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags); + if (retval == 0) { + hcd = bus_to_hcd(urb->dev->bus); + retval = unlink1(hcd, urb, status); + usb_put_dev(urb->dev); + } if (retval == 0) retval = -EINPROGRESS; @@ -1528,6 +1546,17 @@ void usb_hcd_disable_endpoint(struct usb_device *udev, hcd->driver->endpoint_disable(hcd, ep); } +/* Protect against drivers that try to unlink URBs after the device + * is gone, by waiting until all unlinks for @udev are finished. + * Since we don't currently track URBs by device, simply wait until + * nothing is running in the locked region of usb_hcd_unlink_urb(). + */ +void usb_hcd_synchronize_unlinks(struct usb_device *udev) +{ + spin_lock_irq(&hcd_urb_unlink_lock); + spin_unlock_irq(&hcd_urb_unlink_lock); +} + /*-------------------------------------------------------------------------*/ /* called in any context */ diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 2dcde61..9465e70 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -232,6 +232,7 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep); extern void usb_hcd_disable_endpoint(struct usb_device *udev, struct usb_host_endpoint *ep); +extern void usb_hcd_synchronize_unlinks(struct usb_device *udev); extern int usb_hcd_get_frame_number(struct usb_device *udev); extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 9b3f16b..b19cbfc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -659,6 +659,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2); schedule_delayed_work(&hub->init_work, msecs_to_jiffies(delay)); + + /* Suppress autosuspend until init is done */ + to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; return; /* Continues at init2: below */ } else { hub_power_on(hub, true); @@ -1429,6 +1432,7 @@ void usb_disconnect(struct usb_device **pdev) */ dev_dbg (&udev->dev, "unregistering device\n"); usb_disable_device(udev, 0); + usb_hcd_synchronize_unlinks(udev); usb_unlock_device(udev); diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index f263800..4342bd9 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -474,6 +474,12 @@ EXPORT_SYMBOL_GPL(usb_submit_urb); * indicating that the request has been canceled (rather than any other * code). * + * Drivers should not call this routine or related routines, such as + * usb_kill_urb() or usb_unlink_anchored_urbs(), after their disconnect + * method has returned. The disconnect function should synchronize with + * a driver's I/O routines to insure that all URB-related activity has + * completed before it returns. + * * This request is always asynchronous. Success is indicated by * returning -EINPROGRESS, at which time the URB will probably not yet * have been given back to the device driver. When it is eventually @@ -550,6 +556,9 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb); * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_kill_urb(struct urb *urb) { @@ -588,6 +597,9 @@ EXPORT_SYMBOL_GPL(usb_kill_urb); * This routine may not be used in an interrupt context (such as a bottom * half or a completion handler), or when holding a spinlock, or in other * situations where the caller can't schedule(). + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_poison_urb(struct urb *urb) { @@ -622,6 +634,9 @@ EXPORT_SYMBOL_GPL(usb_unpoison_urb); * * this allows all outstanding URBs to be killed starting * from the back of the queue + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_kill_anchored_urbs(struct usb_anchor *anchor) { @@ -651,6 +666,9 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs); * this allows all outstanding URBs to be poisoned starting * from the back of the queue. Newly added URBs will also be * poisoned + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_poison_anchored_urbs(struct usb_anchor *anchor) { @@ -672,6 +690,7 @@ void usb_poison_anchored_urbs(struct usb_anchor *anchor) spin_unlock_irq(&anchor->lock); } EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); + /** * usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse * @anchor: anchor the requests are bound to @@ -680,6 +699,9 @@ EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); * from the back of the queue. This function is asynchronous. * The unlinking is just tiggered. It may happen after this * function has returned. + * + * This routine should not be called by a driver after its disconnect + * method has returned. */ void usb_unlink_anchored_urbs(struct usb_anchor *anchor) { diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 8be3f39..794b5ff 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -281,6 +281,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp) if (tty->driver_data) tty->driver_data = NULL; tty_port_tty_set(&port->port, NULL); + tty_kref_put(tty); } } diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index a2b9ebbe..fb9e20e 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -333,6 +333,13 @@ UNUSUAL_DEV( 0x0482, 0x0103, 0x0100, 0x0100, "Finecam S5", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), +/* Patch submitted by Jens Taprogge <jens.taprogge@taprogge.org> */ +UNUSUAL_DEV( 0x0482, 0x0107, 0x0100, 0x0100, + "Kyocera", + "CONTAX SL300R T*", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE), + /* Reported by Paul Stewart <stewart@wetlogic.net> * This entry is needed because the device reports Sub=ff */ UNUSUAL_DEV( 0x04a4, 0x0004, 0x0001, 0x0001, diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 64b3d30..b92947d 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -2118,7 +2118,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s height, width); } -static __inline__ void updatescrollmode(struct display *p, +static void updatescrollmode(struct display *p, struct fb_info *info, struct vc_data *vc) { diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index cd5f20d..6048b55 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1262,8 +1262,8 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case FBIOPUT_CON2FBMAP: arg = (unsigned long) compat_ptr(arg); case FBIOBLANK: - ret = fb_ioctl(file, cmd, arg); - break; + mutex_unlock(&info->lock); + return fb_ioctl(file, cmd, arg); case FBIOGET_FSCREENINFO: ret = fb_get_fscreeninfo(inode, file, cmd, arg); diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 8e5263c..7543d5f 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -38,7 +38,6 @@ #include "iface.h" #include "viafbdev.h" #include "chip.h" -#include "debug.h" #include "accel.h" #include "share.h" #include "dvi.h" @@ -48,12 +47,10 @@ #include "lcd.h" #include "ioctl.h" -#include "viamode.h" #include "via_utility.h" #include "vt1636.h" #include "tblDPASetting.h" #include "tbl1636.h" -#include "viafbdev.h" /* External struct*/ diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 9ce1ab6..1e3b934 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -774,7 +774,7 @@ void xen_poll_irq(int irq) poll.nr_ports = 1; poll.timeout = 0; - poll.ports = &evtchn; + set_xen_guest_handle(poll.ports, &evtchn); if (HYPERVISOR_sched_op(SCHEDOP_poll, &poll) != 0) BUG(); diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index d0e87cb..9b91617 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -39,8 +39,6 @@ static int xen_suspend(void *data) BUG_ON(!irqs_disabled()); - load_cr3(swapper_pg_dir); - err = device_power_down(PMSG_SUSPEND); if (err) { printk(KERN_ERR "xen_suspend: device_power_down failed: %d\n", diff --git a/drivers/xen/xencomm.c b/drivers/xen/xencomm.c index 797cb4e..a240b2c 100644 --- a/drivers/xen/xencomm.c +++ b/drivers/xen/xencomm.c @@ -23,13 +23,7 @@ #include <asm/page.h> #include <xen/xencomm.h> #include <xen/interface/xen.h> -#ifdef __ia64__ -#include <asm/xen/xencomm.h> /* for is_kern_addr() */ -#endif - -#ifdef HAVE_XEN_PLATFORM_COMPAT_H -#include <xen/platform-compat.h> -#endif +#include <asm/xen/xencomm.h> /* for xencomm_is_phys_contiguous() */ static int xencomm_init(struct xencomm_desc *desc, void *buffer, unsigned long bytes) @@ -157,20 +151,11 @@ static int xencomm_create(void *buffer, unsigned long bytes, return 0; } -/* check if memory address is within VMALLOC region */ -static int is_phys_contiguous(unsigned long addr) -{ - if (!is_kernel_addr(addr)) - return 0; - - return (addr < VMALLOC_START) || (addr >= VMALLOC_END); -} - static struct xencomm_handle *xencomm_create_inline(void *ptr) { unsigned long paddr; - BUG_ON(!is_phys_contiguous((unsigned long)ptr)); + BUG_ON(!xencomm_is_phys_contiguous((unsigned long)ptr)); paddr = (unsigned long)xencomm_pa(ptr); BUG_ON(paddr & XENCOMM_INLINE_FLAG); @@ -202,7 +187,7 @@ struct xencomm_handle *xencomm_map(void *ptr, unsigned long bytes) int rc; struct xencomm_desc *desc; - if (is_phys_contiguous((unsigned long)ptr)) + if (xencomm_is_phys_contiguous((unsigned long)ptr)) return xencomm_create_inline(ptr); rc = xencomm_create(ptr, bytes, &desc, GFP_KERNEL); @@ -219,7 +204,7 @@ struct xencomm_handle *__xencomm_map_no_alloc(void *ptr, unsigned long bytes, int rc; struct xencomm_desc *desc = NULL; - if (is_phys_contiguous((unsigned long)ptr)) + if (xencomm_is_phys_contiguous((unsigned long)ptr)) return xencomm_create_inline(ptr); rc = xencomm_create_mini(ptr, bytes, xc_desc, diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index cfd29da..0376ac6 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -2,7 +2,7 @@ * An implementation of a loadable kernel mode driver providing * multiple kernel/user space bidirectional communications links. * - * Author: Alan Cox <alan@redhat.com> + * Author: Alan Cox <alan@lxorguk.ukuu.org.uk> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 06db79d..6046239 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1251,6 +1251,7 @@ struct kmem_cache *ecryptfs_header_cache_2; /** * ecryptfs_write_headers_virt * @page_virt: The virtual address to write the headers to + * @max: The size of memory allocated at page_virt * @size: Set to the number of bytes written by this function * @crypt_stat: The cryptographic context * @ecryptfs_dentry: The eCryptfs dentry @@ -1278,7 +1279,8 @@ struct kmem_cache *ecryptfs_header_cache_2; * * Returns zero on success */ -static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, +static int ecryptfs_write_headers_virt(char *page_virt, size_t max, + size_t *size, struct ecryptfs_crypt_stat *crypt_stat, struct dentry *ecryptfs_dentry) { @@ -1296,7 +1298,7 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, offset += written; rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat, ecryptfs_dentry, &written, - PAGE_CACHE_SIZE - offset); + max - offset); if (rc) ecryptfs_printk(KERN_WARNING, "Error generating key packet " "set; rc = [%d]\n", rc); @@ -1368,14 +1370,14 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) goto out; } /* Released in this function */ - virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL); + virt = (char *)get_zeroed_page(GFP_KERNEL); if (!virt) { printk(KERN_ERR "%s: Out of memory\n", __func__); rc = -ENOMEM; goto out; } - rc = ecryptfs_write_headers_virt(virt, &size, crypt_stat, - ecryptfs_dentry); + rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size, + crypt_stat, ecryptfs_dentry); if (unlikely(rc)) { printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", __func__, rc); @@ -1393,8 +1395,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) goto out_free; } out_free: - memset(virt, 0, crypt_stat->num_header_bytes_at_front); - kfree(virt); + free_page((unsigned long)virt); out: return rc; } diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 19eafbe..2b2eec1 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -175,7 +175,7 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb, if (rw == WRITE) { /* - * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(), + * FIXME: blockdev_direct_IO() doesn't use ->write_begin(), * so we need to update the ->mmu_private to block boundary. * * But we must fill the remaining area or hole by nul for diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index d15cd6e..60d4c32 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -860,7 +860,6 @@ out: * int journal_get_undo_access() - Notify intent to modify metadata with non-rewindable consequences * @handle: transaction * @bh: buffer to undo - * @credits: store the number of taken credits here (if not NULL) * * Sometimes there is a need to distinguish between metadata which has * been committed to disk and that which has not. The ext3fs code uses @@ -814,7 +814,7 @@ EXPORT_SYMBOL(simple_getattr); EXPORT_SYMBOL(simple_link); EXPORT_SYMBOL(simple_lookup); EXPORT_SYMBOL(simple_pin_fs); -EXPORT_SYMBOL(simple_prepare_write); +EXPORT_UNUSED_SYMBOL(simple_prepare_write); EXPORT_SYMBOL(simple_readpage); EXPORT_SYMBOL(simple_release_fs); EXPORT_SYMBOL(simple_rename); diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index b9195c0..dc52793 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -5,7 +5,7 @@ * * nfs inode and superblock handling functions * - * Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some + * Modularised by Alan Cox <alan@lxorguk.ukuu.org.uk>, while hacking some * experimental NFS changes. Modularisation taken straight from SYS5 fs. * * Change to nfs_read_super() to permit NFS mounts to multi-homed hosts. diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a3b0061..f48db67 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -5,7 +5,7 @@ * * nfs superblock handling functions * - * Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some + * Modularised by Alan Cox <alan@lxorguk.ukuu.org.uk>, while hacking some * experimental NFS changes. Modularisation taken straight from SYS5 fs. * * Change to nfs_read_super() to permit NFS mounts to multi-homed hosts. diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 8d3225a..7efe937 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -679,8 +679,7 @@ leave: /* Some parts of this taken from generic_cont_expand, which turned out * to be too fragile to do exactly what we need without us having to - * worry about recursive locking in ->prepare_write() and - * ->commit_write(). */ + * worry about recursive locking in ->write_begin() and ->write_end(). */ static int ocfs2_write_zero_page(struct inode *inode, u64 size) { diff --git a/fs/proc/array.c b/fs/proc/array.c index bb9f4b0..6af7fba 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -40,7 +40,7 @@ * * * Alan Cox : security fixes. - * <Alan.Cox@linux.org> + * <alan@lxorguk.ukuu.org.uk> * * Al Viro : safe handling of mm_struct * diff --git a/fs/splice.c b/fs/splice.c index a1e701c..1abab5c 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -731,8 +731,8 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, }; /* - * The actor worker might be calling ->prepare_write and - * ->commit_write. Most of the time, these expect i_mutex to + * The actor worker might be calling ->write_begin and + * ->write_end. Most of the time, these expect i_mutex to * be held. Since this may result in an ABBA deadlock with * pipe->inode, we have to order lock acquiry here. */ diff --git a/include/asm-generic/kdebug.h b/include/asm-generic/kdebug.h index 2b799c9..11e57b6 100644 --- a/include/asm-generic/kdebug.h +++ b/include/asm-generic/kdebug.h @@ -3,6 +3,7 @@ enum die_val { DIE_UNUSED, + DIE_OOPS=1 }; #endif /* _ASM_GENERIC_KDEBUG_H */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 8b00f66..1164963 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -25,7 +25,6 @@ struct cgroup; extern int cgroup_init_early(void); extern int cgroup_init(void); -extern void cgroup_init_smp(void); extern void cgroup_lock(void); extern bool cgroup_lock_live_group(struct cgroup *cgrp); extern void cgroup_unlock(void); @@ -348,8 +347,6 @@ struct cgroup_subsys { struct cgroupfs_root *root; struct list_head sibling; - - void *private; }; #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; @@ -410,7 +407,6 @@ void cgroup_mm_owner_callbacks(struct task_struct *old, static inline int cgroup_init_early(void) { return 0; } static inline int cgroup_init(void) { return 0; } -static inline void cgroup_init_smp(void) {} static inline void cgroup_fork(struct task_struct *p) {} static inline void cgroup_fork_callbacks(struct task_struct *p) {} static inline void cgroup_post_fork(struct task_struct *p) {} diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 8f22533..5a361f8 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -44,11 +44,6 @@ static inline bool should_send_signal(struct task_struct *p) return !(p->flags & PF_FREEZER_NOSIG); } -/* - * Wake up a frozen process - */ -extern int __thaw_process(struct task_struct *p); - /* Takes and releases task alloc lock using task_lock() */ extern int thaw_process(struct task_struct *p); diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b248d6..0dcdd94 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -489,13 +489,6 @@ struct address_space_operations { int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages); - /* - * ext3 requires that a successful prepare_write() call be followed - * by a commit_write() call - they must be balanced - */ - int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); - int (*commit_write)(struct file *, struct page *, unsigned, unsigned); - int (*write_begin)(struct file *, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 9623b7b..899ec4b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -8,7 +8,7 @@ #include <linux/types.h> #include <linux/kallsyms.h> -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER extern int ftrace_enabled; extern int @@ -36,16 +36,14 @@ void clear_ftrace_function(void); extern void ftrace_stub(unsigned long a0, unsigned long a1); -#else /* !CONFIG_FTRACE */ +#else /* !CONFIG_FUNCTION_TRACER */ # define register_ftrace_function(ops) do { } while (0) # define unregister_ftrace_function(ops) do { } while (0) # define clear_ftrace_function(ops) do { } while (0) -static inline void ftrace_kill_atomic(void) { } -#endif /* CONFIG_FTRACE */ +static inline void ftrace_kill(void) { } +#endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_DYNAMIC_FTRACE -# define FTRACE_HASHBITS 10 -# define FTRACE_HASHSIZE (1<<FTRACE_HASHBITS) enum { FTRACE_FL_FREE = (1 << 0), @@ -58,9 +56,9 @@ enum { }; struct dyn_ftrace { - struct hlist_node node; - unsigned long ip; /* address of mcount call-site */ - unsigned long flags; + struct list_head list; + unsigned long ip; /* address of mcount call-site */ + unsigned long flags; }; int ftrace_force_update(void); @@ -71,14 +69,33 @@ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); extern int ftrace_dyn_arch_init(void *data); -extern int ftrace_mcount_set(unsigned long *data); -extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, - unsigned char *new_code); extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); +/** + * ftrace_modify_code - modify code segment + * @ip: the address of the code segment + * @old_code: the contents of what is expected to be there + * @new_code: the code to patch in + * + * This is a very sensitive operation and great care needs + * to be taken by the arch. The operation should carefully + * read the location, check to see if what is read is indeed + * what we expect it to be, and then on success of the compare, + * it should write to the location. + * + * Return must be: + * 0 on success + * -EFAULT on error reading the location + * -EINVAL on a failed compare of the contents + * -EPERM on error writing to the location + * Any other value will be considered a failure. + */ +extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code); + extern int skip_trace(unsigned long ip); extern void ftrace_release(void *start, unsigned long size); @@ -97,11 +114,10 @@ static inline void ftrace_release(void *start, unsigned long size) { } /* totally disable ftrace - can not re-enable after this */ void ftrace_kill(void); -void ftrace_kill_atomic(void); static inline void tracer_disable(void) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER ftrace_enabled = 0; #endif } @@ -113,7 +129,7 @@ static inline void tracer_disable(void) */ static inline int __ftrace_enabled_save(void) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER int saved_ftrace_enabled = ftrace_enabled; ftrace_enabled = 0; return saved_ftrace_enabled; @@ -124,7 +140,7 @@ static inline int __ftrace_enabled_save(void) static inline void __ftrace_enabled_restore(int enabled) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER ftrace_enabled = enabled; #endif } diff --git a/include/linux/hid.h b/include/linux/hid.h index 5355ca4..e5780f8 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -410,6 +410,7 @@ struct hid_output_fifo { #define HID_SUSPENDED 5 #define HID_CLEAR_HALT 6 #define HID_DISCONNECTED 7 +#define HID_STARTED 8 struct hid_input { struct list_head list; diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 396a350..fba141d 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -116,6 +116,8 @@ extern int _cond_resched(void); # define might_resched() do { } while (0) #endif +#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP + void __might_sleep(char *file, int line); /** * might_sleep - annotation for functions that can sleep * @@ -126,8 +128,6 @@ extern int _cond_resched(void); * be bitten later when the calling function happens to sleep when it is not * supposed to. */ -#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP - void __might_sleep(char *file, int line); # define might_sleep() \ do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) #else diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 797fcd7..f18b86f 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -489,6 +489,9 @@ struct kvm_assigned_pci_dev { __u32 busnr; __u32 devfn; __u32 flags; + union { + __u32 reserved[12]; + }; }; struct kvm_assigned_irq { @@ -496,6 +499,9 @@ struct kvm_assigned_irq { __u32 host_irq; __u32 guest_irq; __u32 flags; + union { + __u32 reserved[12]; + }; }; #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3833c48..bb92be2 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -37,6 +37,8 @@ #define KVM_REQ_UNHALT 6 #define KVM_REQ_MMU_SYNC 7 +#define KVM_USERSPACE_IRQ_SOURCE_ID 0 + struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; @@ -306,15 +308,18 @@ struct kvm_assigned_dev_kernel { int host_irq; int guest_irq; int irq_requested; + int irq_source_id; struct pci_dev *dev; struct kvm *kvm; }; -void kvm_set_irq(struct kvm *kvm, int irq, int level); +void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi); void kvm_register_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); void kvm_unregister_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); +int kvm_request_irq_source_id(struct kvm *kvm); +void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_DMAR int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index eb71b45..97b91d1 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -135,6 +135,7 @@ struct usb_device_id { struct hid_device_id { __u16 bus; + __u16 pad1; __u32 vendor; __u32 product; kernel_ulong_t driver_data diff --git a/include/linux/phonet.h b/include/linux/phonet.h index c9609f9..4157faa 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -72,6 +72,7 @@ struct phonetmsg { } pn_msg_u; }; #define PN_COMMON_MESSAGE 0xF0 +#define PN_COMMGR 0x10 #define PN_PREFIX 0xE0 /* resource for extended messages */ #define pn_submsg_id pn_msg_u.base.pn_submsg_id #define pn_e_submsg_id pn_msg_u.ext.pn_e_submsg_id diff --git a/include/linux/resource.h b/include/linux/resource.h index aaa423a..40fc7e6 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -59,10 +59,10 @@ struct rlimit { #define _STK_LIM (8*1024*1024) /* - * GPG wants 32kB of mlocked memory, to make sure pass phrases + * GPG2 wants 64kB of mlocked memory, to make sure pass phrases * and other sensitive information are never written to disk. */ -#define MLOCK_LIMIT (8 * PAGE_SIZE) +#define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024) /* * Due to binary compatibility, the actual resource numbers diff --git a/include/linux/sched.h b/include/linux/sched.h index 8478f33..b483f39 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -936,7 +936,6 @@ struct sched_class { void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); void (*yield_task) (struct rq *rq); - int (*select_task_rq)(struct task_struct *p, int sync); void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync); @@ -944,6 +943,8 @@ struct sched_class { void (*put_prev_task) (struct rq *rq, struct task_struct *p); #ifdef CONFIG_SMP + int (*select_task_rq)(struct task_struct *p, int sync); + unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, struct rq *busiest, unsigned long max_load_move, struct sched_domain *sd, enum cpu_idle_type idle, @@ -955,16 +956,17 @@ struct sched_class { void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); -#endif - void (*set_curr_task) (struct rq *rq); - void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); - void (*task_new) (struct rq *rq, struct task_struct *p); void (*set_cpus_allowed)(struct task_struct *p, const cpumask_t *newmask); void (*rq_online)(struct rq *rq); void (*rq_offline)(struct rq *rq); +#endif + + void (*set_curr_task) (struct rq *rq); + void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); + void (*task_new) (struct rq *rq, struct task_struct *p); void (*switched_from) (struct rq *this_rq, struct task_struct *task, int running); diff --git a/include/linux/security.h b/include/linux/security.h index f5c4a51..c13f1ce 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1585,6 +1585,7 @@ int security_syslog(int type); int security_settime(struct timespec *ts, struct timezone *tz); int security_vm_enough_memory(long pages); int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); +int security_vm_enough_memory_kern(long pages); int security_bprm_alloc(struct linux_binprm *bprm); void security_bprm_free(struct linux_binprm *bprm); void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); @@ -1820,6 +1821,11 @@ static inline int security_vm_enough_memory(long pages) return cap_vm_enough_memory(current->mm, pages); } +static inline int security_vm_enough_memory_kern(long pages) +{ + return cap_vm_enough_memory(current->mm, pages); +} + static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) { return cap_vm_enough_memory(mm, pages); diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index b8db32c..bf8de28 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -18,6 +18,9 @@ * duplex (MicroWire) controllers. Provide chipslect() and txrx_bufs(), * and custom setup()/cleanup() methods. */ + +#include <linux/workqueue.h> + struct spi_bitbang { struct workqueue_struct *workqueue; struct work_struct work; diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d861197..8856e2d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1474,7 +1474,6 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, * ieee80211_beacon_get - beacon generation function * @hw: pointer obtained from ieee80211_alloc_hw(). * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. - * @control: will be filled with information needed to send this beacon. * * If the beacon frames are generated by the host system (i.e., not in * hardware/firmware), the low-level driver uses this function to receive @@ -1575,7 +1574,6 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw, * ieee80211_get_buffered_bc - accessing buffered broadcast and multicast frames * @hw: pointer as obtained from ieee80211_alloc_hw(). * @vif: &struct ieee80211_vif pointer from &struct ieee80211_if_init_conf. - * @control: will be filled with information needed to send returned frame. * * Function for accessing buffered broadcast and multicast frames. If * hardware/firmware does not implement buffering of broadcast/multicast @@ -1623,9 +1621,8 @@ unsigned int ieee80211_hdrlen(__le16 fc); * * @keyconf: the parameter passed with the set key * @skb: the skb for which the key is needed - * @rc4key: a buffer to which the key will be written * @type: TBD - * @key: TBD + * @key: a buffer to which the key will be written */ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, struct sk_buff *skb, @@ -1726,7 +1723,8 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw, * @hw: pointer as obtained from ieee80211_alloc_hw(). * @ra: receiver address of the BA session recipient * @tid: the TID to BA on. - * @return: success if addBA request was sent, failure otherwise + * + * Return: success if addBA request was sent, failure otherwise * * Although mac80211/low level driver/user space application can estimate * the need to start aggregation on a certain RA/TID, the session level @@ -1764,7 +1762,8 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, const u8 *ra, * @ra: receiver address of the BA session recipient * @tid: the TID to stop BA. * @initiator: if indicates initiator DELBA frame will be sent. - * @return: error if no sta with matching da found, success otherwise + * + * Return: error if no sta with matching da found, success otherwise * * Although mac80211/low level driver/user space application can estimate * the need to stop aggregation on a certain RA/TID, the session level diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index d4e7250..c6a2451 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -27,7 +27,7 @@ * The lower layers may not require more space, ever. Make sure it's * enough. */ -#define MAX_PHONET_HEADER 8 +#define MAX_PHONET_HEADER (8 + MAX_HEADER) /* * Every Phonet* socket has this structure first in its diff --git a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h index cf4c219..1723138 100644 --- a/include/scsi/scsi_tcq.h +++ b/include/scsi/scsi_tcq.h @@ -140,8 +140,18 @@ static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) */ static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) { - shost->bqt = blk_init_tags(depth); - return shost->bqt ? 0 : -ENOMEM; + /* + * If the shared tag map isn't already initialized, do it now. + * This saves callers from having to check ->bqt when setting up + * devices on the shared host (for libata) + */ + if (!shost->bqt) { + shost->bqt = blk_init_tags(depth); + if (!shost->bqt) + return -ENOMEM; + } + + return 0; } /** diff --git a/include/sound/soc.h b/include/sound/soc.h index a1e0357..5e01898 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -28,7 +28,8 @@ */ #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .shift = xshift, .max = xmax, .invert = xinvert}) + {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ + .invert = xinvert}) #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ ((unsigned long)&(struct soc_mixer_control) \ {.reg = xreg, .max = xmax, .invert = xinvert}) diff --git a/init/Kconfig b/init/Kconfig index 44e9208..86b00c5 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -401,16 +401,20 @@ config CGROUP_MEM_RES_CTLR depends on CGROUPS && RESOURCE_COUNTERS select MM_OWNER help - Provides a memory resource controller that manages both page cache and - RSS memory. + Provides a memory resource controller that manages both anonymous + memory and page cache. (See Documentation/controllers/memory.txt) Note that setting this option increases fixed memory overhead - associated with each page of memory in the system by 4/8 bytes - and also increases cache misses because struct page on many 64bit - systems will not fit into a single cache line anymore. + associated with each page of memory in the system. By this, + 20(40)bytes/PAGE_SIZE on 32(64)bit system will be occupied by memory + usage tracking struct at boot. Total amount of this is printed out + at boot. Only enable when you're ok with these trade offs and really - sure you need the memory resource controller. + sure you need the memory resource controller. Even when you enable + this, you can set "cgroup_disable=memory" at your boot option to + disable memory resource controller and you can avoid overheads. + (and lose benefits of memory resource contoller) This config option also selects MM_OWNER config option, which could in turn add some fork/exit overhead. diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c index 4c87ee1..4d42f45 100644 --- a/init/do_mounts_md.c +++ b/init/do_mounts_md.c @@ -1,4 +1,4 @@ - +#include <linux/delay.h> #include <linux/raid/md.h> #include <linux/delay.h> diff --git a/kernel/Makefile b/kernel/Makefile index 305f11d..9a3ec66 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,7 +13,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ CFLAGS_REMOVE_sched.o = -mno-spe -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER # Do not trace debug files and internal ftrace files CFLAGS_REMOVE_lockdep.o = -pg CFLAGS_REMOVE_lockdep_proc.o = -pg @@ -88,7 +88,7 @@ obj-$(CONFIG_MARKERS) += marker.o obj-$(CONFIG_TRACEPOINTS) += tracepoint.o obj-$(CONFIG_LATENCYTOP) += latencytop.o obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o -obj-$(CONFIG_FTRACE) += trace/ +obj-$(CONFIG_FUNCTION_TRACER) += trace/ obj-$(CONFIG_TRACING) += trace/ obj-$(CONFIG_SMP) += sched_cpupri.o diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index e950569..7fa476f 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c @@ -162,9 +162,13 @@ static int freezer_can_attach(struct cgroup_subsys *ss, struct task_struct *task) { struct freezer *freezer; - int retval; - /* Anything frozen can't move or be moved to/from */ + /* + * Anything frozen can't move or be moved to/from. + * + * Since orig_freezer->state == FROZEN means that @task has been + * frozen, so it's sufficient to check the latter condition. + */ if (is_task_frozen_enough(task)) return -EBUSY; @@ -173,13 +177,7 @@ static int freezer_can_attach(struct cgroup_subsys *ss, if (freezer->state == CGROUP_FROZEN) return -EBUSY; - retval = 0; - task_lock(task); - freezer = task_freezer(task); - if (freezer->state == CGROUP_FROZEN) - retval = -EBUSY; - task_unlock(task); - return retval; + return 0; } static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) @@ -190,8 +188,9 @@ static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task) freezer = task_freezer(task); task_unlock(task); - BUG_ON(freezer->state == CGROUP_FROZEN); spin_lock_irq(&freezer->lock); + BUG_ON(freezer->state == CGROUP_FROZEN); + /* Locking avoids race with FREEZING -> THAWED transitions. */ if (freezer->state == CGROUP_FREEZING) freeze_task(task, true); @@ -276,25 +275,18 @@ static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) return num_cant_freeze_now ? -EBUSY : 0; } -static int unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) +static void unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer) { struct cgroup_iter it; struct task_struct *task; cgroup_iter_start(cgroup, &it); while ((task = cgroup_iter_next(cgroup, &it))) { - int do_wake; - - task_lock(task); - do_wake = __thaw_process(task); - task_unlock(task); - if (do_wake) - wake_up_process(task); + thaw_process(task); } cgroup_iter_end(cgroup, &it); - freezer->state = CGROUP_THAWED; - return 0; + freezer->state = CGROUP_THAWED; } static int freezer_change_state(struct cgroup *cgroup, @@ -304,27 +296,22 @@ static int freezer_change_state(struct cgroup *cgroup, int retval = 0; freezer = cgroup_freezer(cgroup); + spin_lock_irq(&freezer->lock); + update_freezer_state(cgroup, freezer); if (goal_state == freezer->state) goto out; - switch (freezer->state) { + + switch (goal_state) { case CGROUP_THAWED: - retval = try_to_freeze_cgroup(cgroup, freezer); + unfreeze_cgroup(cgroup, freezer); break; - case CGROUP_FREEZING: - if (goal_state == CGROUP_FROZEN) { - /* Userspace is retrying after - * "/bin/echo FROZEN > freezer.state" returned -EBUSY */ - retval = try_to_freeze_cgroup(cgroup, freezer); - break; - } - /* state == FREEZING and goal_state == THAWED, so unfreeze */ case CGROUP_FROZEN: - retval = unfreeze_cgroup(cgroup, freezer); + retval = try_to_freeze_cgroup(cgroup, freezer); break; default: - break; + BUG(); } out: spin_unlock_irq(&freezer->lock); diff --git a/kernel/freezer.c b/kernel/freezer.c index ba6248b..2f4936c 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -121,16 +121,7 @@ void cancel_freezing(struct task_struct *p) } } -/* - * Wake up a frozen process - * - * task_lock() is needed to prevent the race with refrigerator() which may - * occur if the freezing of tasks fails. Namely, without the lock, if the - * freezing of tasks failed, thaw_tasks() might have run before a task in - * refrigerator() could call frozen_process(), in which case the task would be - * frozen and no one would thaw it. - */ -int __thaw_process(struct task_struct *p) +static int __thaw_process(struct task_struct *p) { if (frozen(p)) { p->flags &= ~PF_FROZEN; @@ -140,6 +131,15 @@ int __thaw_process(struct task_struct *p) return 0; } +/* + * Wake up a frozen process + * + * task_lock() is needed to prevent the race with refrigerator() which may + * occur if the freezing of tasks fails. Namely, without the lock, if the + * freezing of tasks failed, thaw_tasks() might have run before a task in + * refrigerator() could call frozen_process(), in which case the task would be + * frozen and no one would thaw it. + */ int thaw_process(struct task_struct *p) { task_lock(p); diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index fac014a..4d161c70 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -220,7 +220,7 @@ void unregister_handler_proc(unsigned int irq, struct irqaction *action) } } -void register_default_affinity_proc(void) +static void register_default_affinity_proc(void) { #ifdef CONFIG_SMP proc_create("irq/default_smp_affinity", 0600, NULL, diff --git a/kernel/lockdep.c b/kernel/lockdep.c index dbda475..06e1571 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -2169,12 +2169,11 @@ void early_boot_irqs_on(void) /* * Hardirqs will be enabled: */ -void trace_hardirqs_on_caller(unsigned long a0) +void trace_hardirqs_on_caller(unsigned long ip) { struct task_struct *curr = current; - unsigned long ip; - time_hardirqs_on(CALLER_ADDR0, a0); + time_hardirqs_on(CALLER_ADDR0, ip); if (unlikely(!debug_locks || current->lockdep_recursion)) return; @@ -2188,7 +2187,6 @@ void trace_hardirqs_on_caller(unsigned long a0) } /* we'll do an OFF -> ON transition: */ curr->hardirqs_enabled = 1; - ip = (unsigned long) __builtin_return_address(0); if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) return; @@ -2224,11 +2222,11 @@ EXPORT_SYMBOL(trace_hardirqs_on); /* * Hardirqs were disabled: */ -void trace_hardirqs_off_caller(unsigned long a0) +void trace_hardirqs_off_caller(unsigned long ip) { struct task_struct *curr = current; - time_hardirqs_off(CALLER_ADDR0, a0); + time_hardirqs_off(CALLER_ADDR0, ip); if (unlikely(!debug_locks || current->lockdep_recursion)) return; @@ -2241,7 +2239,7 @@ void trace_hardirqs_off_caller(unsigned long a0) * We have done an ON -> OFF transition: */ curr->hardirqs_enabled = 0; - curr->hardirq_disable_ip = _RET_IP_; + curr->hardirq_disable_ip = ip; curr->hardirq_disable_event = ++curr->irq_events; debug_atomic_inc(&hardirqs_off_events); } else @@ -3417,9 +3415,10 @@ retry: } printk(" ignoring it.\n"); unlock = 0; + } else { + if (count != 10) + printk(KERN_CONT " locked it.\n"); } - if (count != 10) - printk(" locked it.\n"); do_each_thread(g, p) { /* diff --git a/kernel/printk.c b/kernel/printk.c index 6341af7..f492f15 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -233,45 +233,6 @@ static inline void boot_delay_msec(void) #endif /* - * Return the number of unread characters in the log buffer. - */ -static int log_buf_get_len(void) -{ - return logged_chars; -} - -/* - * Copy a range of characters from the log buffer. - */ -int log_buf_copy(char *dest, int idx, int len) -{ - int ret, max; - bool took_lock = false; - - if (!oops_in_progress) { - spin_lock_irq(&logbuf_lock); - took_lock = true; - } - - max = log_buf_get_len(); - if (idx < 0 || idx >= max) { - ret = -1; - } else { - if (len > max) - len = max; - ret = len; - idx += (log_end - max); - while (len-- > 0) - dest[len] = LOG_BUF(idx + len); - } - - if (took_lock) - spin_unlock_irq(&logbuf_lock); - - return ret; -} - -/* * Commands to do_syslog: * * 0 -- Close the log. Currently a NOP. diff --git a/kernel/profile.c b/kernel/profile.c index a9e422d..9830a03 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -102,7 +102,7 @@ int profile_setup(char *str) __setup("profile=", profile_setup); -int profile_init(void) +int __ref profile_init(void) { int buffer_bytes; if (!prof_on) diff --git a/kernel/resource.c b/kernel/resource.c index 4089d12..7fec0e4 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -571,7 +571,7 @@ static void __init __reserve_region_with_split(struct resource *root, } -void reserve_region_with_split(struct resource *root, +void __init reserve_region_with_split(struct resource *root, resource_size_t start, resource_size_t end, const char *name) { diff --git a/kernel/sched.c b/kernel/sched.c index 6625c3c..e8819bc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -386,7 +386,6 @@ struct cfs_rq { u64 exec_clock; u64 min_vruntime; - u64 pair_start; struct rb_root tasks_timeline; struct rb_node *rb_leftmost; @@ -3344,7 +3343,7 @@ small_imbalance: } else this_load_per_task = cpu_avg_load_per_task(this_cpu); - if (max_load - this_load + 2*busiest_load_per_task >= + if (max_load - this_load + busiest_load_per_task >= busiest_load_per_task * imbn) { *imbalance = busiest_load_per_task; return busiest; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 9573c33..ce514af 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -143,6 +143,49 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se) return se->parent; } +/* return depth at which a sched entity is present in the hierarchy */ +static inline int depth_se(struct sched_entity *se) +{ + int depth = 0; + + for_each_sched_entity(se) + depth++; + + return depth; +} + +static void +find_matching_se(struct sched_entity **se, struct sched_entity **pse) +{ + int se_depth, pse_depth; + + /* + * preemption test can be made between sibling entities who are in the + * same cfs_rq i.e who have a common parent. Walk up the hierarchy of + * both tasks until we find their ancestors who are siblings of common + * parent. + */ + + /* First walk up until both entities are at same depth */ + se_depth = depth_se(*se); + pse_depth = depth_se(*pse); + + while (se_depth > pse_depth) { + se_depth--; + *se = parent_entity(*se); + } + + while (pse_depth > se_depth) { + pse_depth--; + *pse = parent_entity(*pse); + } + + while (!is_same_group(*se, *pse)) { + *se = parent_entity(*se); + *pse = parent_entity(*pse); + } +} + #else /* CONFIG_FAIR_GROUP_SCHED */ static inline struct rq *rq_of(struct cfs_rq *cfs_rq) @@ -193,6 +236,11 @@ static inline struct sched_entity *parent_entity(struct sched_entity *se) return NULL; } +static inline void +find_matching_se(struct sched_entity **se, struct sched_entity **pse) +{ +} + #endif /* CONFIG_FAIR_GROUP_SCHED */ @@ -223,6 +271,27 @@ static inline s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se) return se->vruntime - cfs_rq->min_vruntime; } +static void update_min_vruntime(struct cfs_rq *cfs_rq) +{ + u64 vruntime = cfs_rq->min_vruntime; + + if (cfs_rq->curr) + vruntime = cfs_rq->curr->vruntime; + + if (cfs_rq->rb_leftmost) { + struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost, + struct sched_entity, + run_node); + + if (vruntime == cfs_rq->min_vruntime) + vruntime = se->vruntime; + else + vruntime = min_vruntime(vruntime, se->vruntime); + } + + cfs_rq->min_vruntime = max_vruntime(cfs_rq->min_vruntime, vruntime); +} + /* * Enqueue an entity into the rb-tree: */ @@ -256,15 +325,8 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) * Maintain a cache of leftmost tree entries (it is frequently * used): */ - if (leftmost) { + if (leftmost) cfs_rq->rb_leftmost = &se->run_node; - /* - * maintain cfs_rq->min_vruntime to be a monotonic increasing - * value tracking the leftmost vruntime in the tree. - */ - cfs_rq->min_vruntime = - max_vruntime(cfs_rq->min_vruntime, se->vruntime); - } rb_link_node(&se->run_node, parent, link); rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline); @@ -274,18 +336,9 @@ static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) { if (cfs_rq->rb_leftmost == &se->run_node) { struct rb_node *next_node; - struct sched_entity *next; next_node = rb_next(&se->run_node); cfs_rq->rb_leftmost = next_node; - - if (next_node) { - next = rb_entry(next_node, - struct sched_entity, run_node); - cfs_rq->min_vruntime = - max_vruntime(cfs_rq->min_vruntime, - next->vruntime); - } } if (cfs_rq->next == se) @@ -424,6 +477,7 @@ __update_curr(struct cfs_rq *cfs_rq, struct sched_entity *curr, schedstat_add(cfs_rq, exec_clock, delta_exec); delta_exec_weighted = calc_delta_fair(delta_exec, curr); curr->vruntime += delta_exec_weighted; + update_min_vruntime(cfs_rq); } static void update_curr(struct cfs_rq *cfs_rq) @@ -613,13 +667,7 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { - u64 vruntime; - - if (first_fair(cfs_rq)) { - vruntime = min_vruntime(cfs_rq->min_vruntime, - __pick_next_entity(cfs_rq)->vruntime); - } else - vruntime = cfs_rq->min_vruntime; + u64 vruntime = cfs_rq->min_vruntime; /* * The 'current' period is already promised to the current tasks, @@ -696,6 +744,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int sleep) if (se != cfs_rq->curr) __dequeue_entity(cfs_rq, se); account_entity_dequeue(cfs_rq, se); + update_min_vruntime(cfs_rq); } /* @@ -742,16 +791,14 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) se->prev_sum_exec_runtime = se->sum_exec_runtime; } +static int +wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se); + static struct sched_entity * pick_next(struct cfs_rq *cfs_rq, struct sched_entity *se) { - struct rq *rq = rq_of(cfs_rq); - u64 pair_slice = rq->clock - cfs_rq->pair_start; - - if (!cfs_rq->next || pair_slice > sysctl_sched_min_granularity) { - cfs_rq->pair_start = rq->clock; + if (!cfs_rq->next || wakeup_preempt_entity(cfs_rq->next, se) == 1) return se; - } return cfs_rq->next; } @@ -1122,10 +1169,9 @@ wake_affine(struct sched_domain *this_sd, struct rq *this_rq, if (!(this_sd->flags & SD_WAKE_AFFINE) || !sched_feat(AFFINE_WAKEUPS)) return 0; - if (!sync && sched_feat(SYNC_WAKEUPS) && - curr->se.avg_overlap < sysctl_sched_migration_cost && - p->se.avg_overlap < sysctl_sched_migration_cost) - sync = 1; + if (sync && (curr->se.avg_overlap > sysctl_sched_migration_cost || + p->se.avg_overlap > sysctl_sched_migration_cost)) + sync = 0; /* * If sync wakeup then subtract the (maximum possible) @@ -1244,13 +1290,42 @@ static unsigned long wakeup_gran(struct sched_entity *se) * More easily preempt - nice tasks, while not making it harder for * + nice tasks. */ - if (sched_feat(ASYM_GRAN)) - gran = calc_delta_mine(gran, NICE_0_LOAD, &se->load); + if (!sched_feat(ASYM_GRAN) || se->load.weight > NICE_0_LOAD) + gran = calc_delta_fair(sysctl_sched_wakeup_granularity, se); return gran; } /* + * Should 'se' preempt 'curr'. + * + * |s1 + * |s2 + * |s3 + * g + * |<--->|c + * + * w(c, s1) = -1 + * w(c, s2) = 0 + * w(c, s3) = 1 + * + */ +static int +wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se) +{ + s64 gran, vdiff = curr->vruntime - se->vruntime; + + if (vdiff <= 0) + return -1; + + gran = wakeup_gran(curr); + if (vdiff > gran) + return 1; + + return 0; +} + +/* * Preempt the current task with a newly woken task if needed: */ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) @@ -1258,7 +1333,6 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) struct task_struct *curr = rq->curr; struct cfs_rq *cfs_rq = task_cfs_rq(curr); struct sched_entity *se = &curr->se, *pse = &p->se; - s64 delta_exec; if (unlikely(rt_prio(p->prio))) { update_rq_clock(rq); @@ -1296,9 +1370,19 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int sync) return; } - delta_exec = se->sum_exec_runtime - se->prev_sum_exec_runtime; - if (delta_exec > wakeup_gran(pse)) - resched_task(curr); + find_matching_se(&se, &pse); + + while (se) { + BUG_ON(!pse); + + if (wakeup_preempt_entity(se, pse) == 1) { + resched_task(curr); + break; + } + + se = parent_entity(se); + pse = parent_entity(pse); + } } static struct task_struct *pick_next_task_fair(struct rq *rq) @@ -1594,9 +1678,6 @@ static const struct sched_class fair_sched_class = { .enqueue_task = enqueue_task_fair, .dequeue_task = dequeue_task_fair, .yield_task = yield_task_fair, -#ifdef CONFIG_SMP - .select_task_rq = select_task_rq_fair, -#endif /* CONFIG_SMP */ .check_preempt_curr = check_preempt_wakeup, @@ -1604,6 +1685,8 @@ static const struct sched_class fair_sched_class = { .put_prev_task = put_prev_task_fair, #ifdef CONFIG_SMP + .select_task_rq = select_task_rq_fair, + .load_balance = load_balance_fair, .move_one_task = move_one_task_fair, #endif diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index dec4cca..8a21a2e 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c @@ -105,9 +105,6 @@ static const struct sched_class idle_sched_class = { /* dequeue is not valid, we print a debug message there: */ .dequeue_task = dequeue_task_idle, -#ifdef CONFIG_SMP - .select_task_rq = select_task_rq_idle, -#endif /* CONFIG_SMP */ .check_preempt_curr = check_preempt_curr_idle, @@ -115,6 +112,8 @@ static const struct sched_class idle_sched_class = { .put_prev_task = put_prev_task_idle, #ifdef CONFIG_SMP + .select_task_rq = select_task_rq_idle, + .load_balance = load_balance_idle, .move_one_task = move_one_task_idle, #endif diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index b446dc8..d9ba9d5 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -1504,9 +1504,6 @@ static const struct sched_class rt_sched_class = { .enqueue_task = enqueue_task_rt, .dequeue_task = dequeue_task_rt, .yield_task = yield_task_rt, -#ifdef CONFIG_SMP - .select_task_rq = select_task_rq_rt, -#endif /* CONFIG_SMP */ .check_preempt_curr = check_preempt_curr_rt, @@ -1514,6 +1511,8 @@ static const struct sched_class rt_sched_class = { .put_prev_task = put_prev_task_rt, #ifdef CONFIG_SMP + .select_task_rq = select_task_rq_rt, + .load_balance = load_balance_rt, .move_one_task = move_one_task_rt, .set_cpus_allowed = set_cpus_allowed_rt, diff --git a/kernel/signal.c b/kernel/signal.c index 105217d..4530fc6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1144,7 +1144,8 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid) struct task_struct * p; for_each_process(p) { - if (p->pid > 1 && !same_thread_group(p, current)) { + if (task_pid_vnr(p) > 1 && + !same_thread_group(p, current)) { int err = group_send_sig_info(sig, info, p); ++count; if (err != -EPERM) diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 84754f5..6b6b727 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -474,7 +474,7 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = &proc_dointvec, }, -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER { .ctl_name = CTL_UNNUMBERED, .procname = "ftrace_enabled", diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 1cb3e1f..b58f43b 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -1,13 +1,13 @@ # -# Architectures that offer an FTRACE implementation should select HAVE_FTRACE: +# Architectures that offer an FUNCTION_TRACER implementation should +# select HAVE_FUNCTION_TRACER: # config NOP_TRACER bool -config HAVE_FTRACE +config HAVE_FUNCTION_TRACER bool - select NOP_TRACER config HAVE_DYNAMIC_FTRACE bool @@ -27,10 +27,13 @@ config TRACING select RING_BUFFER select STACKTRACE select TRACEPOINTS + select NOP_TRACER + +menu "Tracers" -config FTRACE +config FUNCTION_TRACER bool "Kernel Function Tracer" - depends on HAVE_FTRACE + depends on HAVE_FUNCTION_TRACER depends on DEBUG_KERNEL select FRAME_POINTER select TRACING @@ -49,7 +52,6 @@ config IRQSOFF_TRACER default n depends on TRACE_IRQFLAGS_SUPPORT depends on GENERIC_TIME - depends on HAVE_FTRACE depends on DEBUG_KERNEL select TRACE_IRQFLAGS select TRACING @@ -73,7 +75,6 @@ config PREEMPT_TRACER default n depends on GENERIC_TIME depends on PREEMPT - depends on HAVE_FTRACE depends on DEBUG_KERNEL select TRACING select TRACER_MAX_TRACE @@ -101,7 +102,6 @@ config SYSPROF_TRACER config SCHED_TRACER bool "Scheduling Latency Tracer" - depends on HAVE_FTRACE depends on DEBUG_KERNEL select TRACING select CONTEXT_SWITCH_TRACER @@ -112,7 +112,6 @@ config SCHED_TRACER config CONTEXT_SWITCH_TRACER bool "Trace process context switches" - depends on HAVE_FTRACE depends on DEBUG_KERNEL select TRACING select MARKERS @@ -122,9 +121,9 @@ config CONTEXT_SWITCH_TRACER config BOOT_TRACER bool "Trace boot initcalls" - depends on HAVE_FTRACE depends on DEBUG_KERNEL select TRACING + select CONTEXT_SWITCH_TRACER help This tracer helps developers to optimize boot times: it records the timings of the initcalls and traces key events and the identity @@ -141,9 +140,9 @@ config BOOT_TRACER config STACK_TRACER bool "Trace max stack" - depends on HAVE_FTRACE + depends on HAVE_FUNCTION_TRACER depends on DEBUG_KERNEL - select FTRACE + select FUNCTION_TRACER select STACKTRACE help This special tracer records the maximum stack footprint of the @@ -160,7 +159,7 @@ config STACK_TRACER config DYNAMIC_FTRACE bool "enable/disable ftrace tracepoints dynamically" - depends on FTRACE + depends on FUNCTION_TRACER depends on HAVE_DYNAMIC_FTRACE depends on DEBUG_KERNEL default y @@ -170,7 +169,7 @@ config DYNAMIC_FTRACE with a No-Op instruction) as they are called. A table is created to dynamically enable them again. - This way a CONFIG_FTRACE kernel is slightly larger, but otherwise + This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but otherwise has native performance as long as no tracing is active. The changes to the code are done by a kernel thread that @@ -195,3 +194,5 @@ config FTRACE_STARTUP_TEST a series of tests are made to verify that the tracer is functioning properly. It will do tests on all the configured tracers of ftrace. + +endmenu diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index a85dfba..c8228b1 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -1,7 +1,7 @@ # Do not instrument the tracer itself: -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) @@ -10,13 +10,13 @@ CFLAGS_trace_selftest_dynamic.o = -pg obj-y += trace_selftest_dynamic.o endif -obj-$(CONFIG_FTRACE) += libftrace.o +obj-$(CONFIG_FUNCTION_TRACER) += libftrace.o obj-$(CONFIG_RING_BUFFER) += ring_buffer.o obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o -obj-$(CONFIG_FTRACE) += trace_functions.o +obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 4dda4f6..4a39d24 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -25,13 +25,24 @@ #include <linux/ftrace.h> #include <linux/sysctl.h> #include <linux/ctype.h> -#include <linux/hash.h> #include <linux/list.h> #include <asm/ftrace.h> #include "trace.h" +#define FTRACE_WARN_ON(cond) \ + do { \ + if (WARN_ON(cond)) \ + ftrace_kill(); \ + } while (0) + +#define FTRACE_WARN_ON_ONCE(cond) \ + do { \ + if (WARN_ON_ONCE(cond)) \ + ftrace_kill(); \ + } while (0) + /* ftrace_enabled is a method to turn ftrace on or off */ int ftrace_enabled __read_mostly; static int last_ftrace_enabled; @@ -153,21 +164,8 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) } #ifdef CONFIG_DYNAMIC_FTRACE - #ifndef CONFIG_FTRACE_MCOUNT_RECORD -/* - * The hash lock is only needed when the recording of the mcount - * callers are dynamic. That is, by the caller themselves and - * not recorded via the compilation. - */ -static DEFINE_SPINLOCK(ftrace_hash_lock); -#define ftrace_hash_lock(flags) spin_lock_irqsave(&ftrace_hash_lock, flags) -#define ftrace_hash_unlock(flags) \ - spin_unlock_irqrestore(&ftrace_hash_lock, flags) -#else -/* This is protected via the ftrace_lock with MCOUNT_RECORD. */ -#define ftrace_hash_lock(flags) do { (void)(flags); } while (0) -#define ftrace_hash_unlock(flags) do { } while(0) +# error Dynamic ftrace depends on MCOUNT_RECORD #endif /* @@ -178,8 +176,6 @@ static DEFINE_SPINLOCK(ftrace_hash_lock); */ static unsigned long mcount_addr = MCOUNT_ADDR; -static struct task_struct *ftraced_task; - enum { FTRACE_ENABLE_CALLS = (1 << 0), FTRACE_DISABLE_CALLS = (1 << 1), @@ -190,13 +186,9 @@ enum { static int ftrace_filtered; static int tracing_on; -static int frozen_record_count; - -static struct hlist_head ftrace_hash[FTRACE_HASHSIZE]; -static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu); +static LIST_HEAD(ftrace_new_addrs); -static DEFINE_MUTEX(ftraced_lock); static DEFINE_MUTEX(ftrace_regex_lock); struct ftrace_page { @@ -214,16 +206,13 @@ struct ftrace_page { static struct ftrace_page *ftrace_pages_start; static struct ftrace_page *ftrace_pages; -static int ftraced_trigger; -static int ftraced_suspend; -static int ftraced_stop; - -static int ftrace_record_suspend; - static struct dyn_ftrace *ftrace_free_records; #ifdef CONFIG_KPROBES + +static int frozen_record_count; + static inline void freeze_record(struct dyn_ftrace *rec) { if (!(rec->flags & FTRACE_FL_FROZEN)) { @@ -250,72 +239,6 @@ static inline int record_frozen(struct dyn_ftrace *rec) # define record_frozen(rec) ({ 0; }) #endif /* CONFIG_KPROBES */ -int skip_trace(unsigned long ip) -{ - unsigned long fl; - struct dyn_ftrace *rec; - struct hlist_node *t; - struct hlist_head *head; - - if (frozen_record_count == 0) - return 0; - - head = &ftrace_hash[hash_long(ip, FTRACE_HASHBITS)]; - hlist_for_each_entry_rcu(rec, t, head, node) { - if (rec->ip == ip) { - if (record_frozen(rec)) { - if (rec->flags & FTRACE_FL_FAILED) - return 1; - - if (!(rec->flags & FTRACE_FL_CONVERTED)) - return 1; - - if (!tracing_on || !ftrace_enabled) - return 1; - - if (ftrace_filtered) { - fl = rec->flags & (FTRACE_FL_FILTER | - FTRACE_FL_NOTRACE); - if (!fl || (fl & FTRACE_FL_NOTRACE)) - return 1; - } - } - break; - } - } - - return 0; -} - -static inline int -ftrace_ip_in_hash(unsigned long ip, unsigned long key) -{ - struct dyn_ftrace *p; - struct hlist_node *t; - int found = 0; - - hlist_for_each_entry_rcu(p, t, &ftrace_hash[key], node) { - if (p->ip == ip) { - found = 1; - break; - } - } - - return found; -} - -static inline void -ftrace_add_hash(struct dyn_ftrace *node, unsigned long key) -{ - hlist_add_head_rcu(&node->node, &ftrace_hash[key]); -} - -/* called from kstop_machine */ -static inline void ftrace_del_hash(struct dyn_ftrace *node) -{ - hlist_del(&node->node); -} - static void ftrace_free_rec(struct dyn_ftrace *rec) { rec->ip = (unsigned long)ftrace_free_records; @@ -346,7 +269,6 @@ void ftrace_release(void *start, unsigned long size) } } spin_unlock(&ftrace_lock); - } static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) @@ -358,10 +280,8 @@ static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) rec = ftrace_free_records; if (unlikely(!(rec->flags & FTRACE_FL_FREE))) { - WARN_ON_ONCE(1); + FTRACE_WARN_ON_ONCE(1); ftrace_free_records = NULL; - ftrace_disabled = 1; - ftrace_enabled = 0; return NULL; } @@ -371,76 +291,36 @@ static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) } if (ftrace_pages->index == ENTRIES_PER_PAGE) { - if (!ftrace_pages->next) - return NULL; + if (!ftrace_pages->next) { + /* allocate another page */ + ftrace_pages->next = + (void *)get_zeroed_page(GFP_KERNEL); + if (!ftrace_pages->next) + return NULL; + } ftrace_pages = ftrace_pages->next; } return &ftrace_pages->records[ftrace_pages->index++]; } -static void +static struct dyn_ftrace * ftrace_record_ip(unsigned long ip) { - struct dyn_ftrace *node; - unsigned long flags; - unsigned long key; - int resched; - int cpu; + struct dyn_ftrace *rec; if (!ftrace_enabled || ftrace_disabled) - return; - - resched = need_resched(); - preempt_disable_notrace(); + return NULL; - /* - * We simply need to protect against recursion. - * Use the the raw version of smp_processor_id and not - * __get_cpu_var which can call debug hooks that can - * cause a recursive crash here. - */ - cpu = raw_smp_processor_id(); - per_cpu(ftrace_shutdown_disable_cpu, cpu)++; - if (per_cpu(ftrace_shutdown_disable_cpu, cpu) != 1) - goto out; - - if (unlikely(ftrace_record_suspend)) - goto out; - - key = hash_long(ip, FTRACE_HASHBITS); - - WARN_ON_ONCE(key >= FTRACE_HASHSIZE); - - if (ftrace_ip_in_hash(ip, key)) - goto out; - - ftrace_hash_lock(flags); - - /* This ip may have hit the hash before the lock */ - if (ftrace_ip_in_hash(ip, key)) - goto out_unlock; - - node = ftrace_alloc_dyn_node(ip); - if (!node) - goto out_unlock; - - node->ip = ip; - - ftrace_add_hash(node, key); + rec = ftrace_alloc_dyn_node(ip); + if (!rec) + return NULL; - ftraced_trigger = 1; + rec->ip = ip; - out_unlock: - ftrace_hash_unlock(flags); - out: - per_cpu(ftrace_shutdown_disable_cpu, cpu)--; + list_add(&rec->list, &ftrace_new_addrs); - /* prevent recursion with scheduler */ - if (resched) - preempt_enable_no_resched_notrace(); - else - preempt_enable_notrace(); + return rec; } #define FTRACE_ADDR ((long)(ftrace_caller)) @@ -559,7 +439,6 @@ static void ftrace_replace_code(int enable) rec->flags |= FTRACE_FL_FAILED; if ((system_state == SYSTEM_BOOTING) || !core_kernel_text(rec->ip)) { - ftrace_del_hash(rec); ftrace_free_rec(rec); } } @@ -567,15 +446,6 @@ static void ftrace_replace_code(int enable) } } -static void ftrace_shutdown_replenish(void) -{ - if (ftrace_pages->next) - return; - - /* allocate another page */ - ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL); -} - static void print_ip_ins(const char *fmt, unsigned char *p) { int i; @@ -591,23 +461,23 @@ ftrace_code_disable(struct dyn_ftrace *rec) { unsigned long ip; unsigned char *nop, *call; - int failed; + int ret; ip = rec->ip; nop = ftrace_nop_replace(); call = ftrace_call_replace(ip, mcount_addr); - failed = ftrace_modify_code(ip, call, nop); - if (failed) { - switch (failed) { - case 1: - WARN_ON_ONCE(1); + ret = ftrace_modify_code(ip, call, nop); + if (ret) { + switch (ret) { + case -EFAULT: + FTRACE_WARN_ON_ONCE(1); pr_info("ftrace faulted on modifying "); print_ip_sym(ip); break; - case 2: - WARN_ON_ONCE(1); + case -EINVAL: + FTRACE_WARN_ON_ONCE(1); pr_info("ftrace failed to modify "); print_ip_sym(ip); print_ip_ins(" expected: ", call); @@ -615,6 +485,15 @@ ftrace_code_disable(struct dyn_ftrace *rec) print_ip_ins(" replace: ", nop); printk(KERN_CONT "\n"); break; + case -EPERM: + FTRACE_WARN_ON_ONCE(1); + pr_info("ftrace faulted on writing "); + print_ip_sym(ip); + break; + default: + FTRACE_WARN_ON_ONCE(1); + pr_info("ftrace faulted on unknown error "); + print_ip_sym(ip); } rec->flags |= FTRACE_FL_FAILED; @@ -623,19 +502,11 @@ ftrace_code_disable(struct dyn_ftrace *rec) return 1; } -static int __ftrace_update_code(void *ignore); - static int __ftrace_modify_code(void *data) { - unsigned long addr; int *command = data; if (*command & FTRACE_ENABLE_CALLS) { - /* - * Update any recorded ips now that we have the - * machine stopped - */ - __ftrace_update_code(NULL); ftrace_replace_code(1); tracing_on = 1; } else if (*command & FTRACE_DISABLE_CALLS) { @@ -646,14 +517,6 @@ static int __ftrace_modify_code(void *data) if (*command & FTRACE_UPDATE_TRACE_FUNC) ftrace_update_ftrace_func(ftrace_trace_function); - if (*command & FTRACE_ENABLE_MCOUNT) { - addr = (unsigned long)ftrace_record_ip; - ftrace_mcount_set(&addr); - } else if (*command & FTRACE_DISABLE_MCOUNT) { - addr = (unsigned long)ftrace_stub; - ftrace_mcount_set(&addr); - } - return 0; } @@ -662,26 +525,9 @@ static void ftrace_run_update_code(int command) stop_machine(__ftrace_modify_code, &command, NULL); } -void ftrace_disable_daemon(void) -{ - /* Stop the daemon from calling kstop_machine */ - mutex_lock(&ftraced_lock); - ftraced_stop = 1; - mutex_unlock(&ftraced_lock); - - ftrace_force_update(); -} - -void ftrace_enable_daemon(void) -{ - mutex_lock(&ftraced_lock); - ftraced_stop = 0; - mutex_unlock(&ftraced_lock); - - ftrace_force_update(); -} - static ftrace_func_t saved_ftrace_func; +static int ftrace_start; +static DEFINE_MUTEX(ftrace_start_lock); static void ftrace_startup(void) { @@ -690,9 +536,9 @@ static void ftrace_startup(void) if (unlikely(ftrace_disabled)) return; - mutex_lock(&ftraced_lock); - ftraced_suspend++; - if (ftraced_suspend == 1) + mutex_lock(&ftrace_start_lock); + ftrace_start++; + if (ftrace_start == 1) command |= FTRACE_ENABLE_CALLS; if (saved_ftrace_func != ftrace_trace_function) { @@ -705,7 +551,7 @@ static void ftrace_startup(void) ftrace_run_update_code(command); out: - mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_start_lock); } static void ftrace_shutdown(void) @@ -715,9 +561,9 @@ static void ftrace_shutdown(void) if (unlikely(ftrace_disabled)) return; - mutex_lock(&ftraced_lock); - ftraced_suspend--; - if (!ftraced_suspend) + mutex_lock(&ftrace_start_lock); + ftrace_start--; + if (!ftrace_start) command |= FTRACE_DISABLE_CALLS; if (saved_ftrace_func != ftrace_trace_function) { @@ -730,7 +576,7 @@ static void ftrace_shutdown(void) ftrace_run_update_code(command); out: - mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_start_lock); } static void ftrace_startup_sysctl(void) @@ -740,15 +586,15 @@ static void ftrace_startup_sysctl(void) if (unlikely(ftrace_disabled)) return; - mutex_lock(&ftraced_lock); + mutex_lock(&ftrace_start_lock); /* Force update next time */ saved_ftrace_func = NULL; - /* ftraced_suspend is true if we want ftrace running */ - if (ftraced_suspend) + /* ftrace_start is true if we want ftrace running */ + if (ftrace_start) command |= FTRACE_ENABLE_CALLS; ftrace_run_update_code(command); - mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_start_lock); } static void ftrace_shutdown_sysctl(void) @@ -758,112 +604,50 @@ static void ftrace_shutdown_sysctl(void) if (unlikely(ftrace_disabled)) return; - mutex_lock(&ftraced_lock); - /* ftraced_suspend is true if ftrace is running */ - if (ftraced_suspend) + mutex_lock(&ftrace_start_lock); + /* ftrace_start is true if ftrace is running */ + if (ftrace_start) command |= FTRACE_DISABLE_CALLS; ftrace_run_update_code(command); - mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_start_lock); } static cycle_t ftrace_update_time; static unsigned long ftrace_update_cnt; unsigned long ftrace_update_tot_cnt; -static int __ftrace_update_code(void *ignore) +static int ftrace_update_code(void) { - int i, save_ftrace_enabled; + struct dyn_ftrace *p, *t; cycle_t start, stop; - struct dyn_ftrace *p; - struct hlist_node *t, *n; - struct hlist_head *head, temp_list; - - /* Don't be recording funcs now */ - ftrace_record_suspend++; - save_ftrace_enabled = ftrace_enabled; - ftrace_enabled = 0; start = ftrace_now(raw_smp_processor_id()); ftrace_update_cnt = 0; - /* No locks needed, the machine is stopped! */ - for (i = 0; i < FTRACE_HASHSIZE; i++) { - INIT_HLIST_HEAD(&temp_list); - head = &ftrace_hash[i]; + list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) { - /* all CPUS are stopped, we are safe to modify code */ - hlist_for_each_entry_safe(p, t, n, head, node) { - /* Skip over failed records which have not been - * freed. */ - if (p->flags & FTRACE_FL_FAILED) - continue; + /* If something went wrong, bail without enabling anything */ + if (unlikely(ftrace_disabled)) + return -1; - /* Unconverted records are always at the head of the - * hash bucket. Once we encounter a converted record, - * simply skip over to the next bucket. Saves ftraced - * some processor cycles (ftrace does its bid for - * global warming :-p ). */ - if (p->flags & (FTRACE_FL_CONVERTED)) - break; + list_del_init(&p->list); - /* Ignore updates to this record's mcount site. - * Reintroduce this record at the head of this - * bucket to attempt to "convert" it again if - * the kprobe on it is unregistered before the - * next run. */ - if (get_kprobe((void *)p->ip)) { - ftrace_del_hash(p); - INIT_HLIST_NODE(&p->node); - hlist_add_head(&p->node, &temp_list); - freeze_record(p); - continue; - } else { - unfreeze_record(p); - } - - /* convert record (i.e, patch mcount-call with NOP) */ - if (ftrace_code_disable(p)) { - p->flags |= FTRACE_FL_CONVERTED; - ftrace_update_cnt++; - } else { - if ((system_state == SYSTEM_BOOTING) || - !core_kernel_text(p->ip)) { - ftrace_del_hash(p); - ftrace_free_rec(p); - } - } - } - - hlist_for_each_entry_safe(p, t, n, &temp_list, node) { - hlist_del(&p->node); - INIT_HLIST_NODE(&p->node); - hlist_add_head(&p->node, head); - } + /* convert record (i.e, patch mcount-call with NOP) */ + if (ftrace_code_disable(p)) { + p->flags |= FTRACE_FL_CONVERTED; + ftrace_update_cnt++; + } else + ftrace_free_rec(p); } stop = ftrace_now(raw_smp_processor_id()); ftrace_update_time = stop - start; ftrace_update_tot_cnt += ftrace_update_cnt; - ftraced_trigger = 0; - - ftrace_enabled = save_ftrace_enabled; - ftrace_record_suspend--; return 0; } -static int ftrace_update_code(void) -{ - if (unlikely(ftrace_disabled) || - !ftrace_enabled || !ftraced_trigger) - return 0; - - stop_machine(__ftrace_update_code, NULL, NULL); - - return 1; -} - static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) { struct ftrace_page *pg; @@ -892,7 +676,7 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) pg = ftrace_pages = ftrace_pages_start; cnt = num_to_init / ENTRIES_PER_PAGE; - pr_info("ftrace: allocating %ld hash entries in %d pages\n", + pr_info("ftrace: allocating %ld entries in %d pages\n", num_to_init, cnt); for (i = 0; i < cnt; i++) { @@ -1401,10 +1185,10 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable) } mutex_lock(&ftrace_sysctl_lock); - mutex_lock(&ftraced_lock); - if (iter->filtered && ftraced_suspend && ftrace_enabled) + mutex_lock(&ftrace_start_lock); + if (iter->filtered && ftrace_start && ftrace_enabled) ftrace_run_update_code(FTRACE_ENABLE_CALLS); - mutex_unlock(&ftraced_lock); + mutex_unlock(&ftrace_start_lock); mutex_unlock(&ftrace_sysctl_lock); kfree(iter); @@ -1424,55 +1208,6 @@ ftrace_notrace_release(struct inode *inode, struct file *file) return ftrace_regex_release(inode, file, 0); } -static ssize_t -ftraced_read(struct file *filp, char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - /* don't worry about races */ - char *buf = ftraced_stop ? "disabled\n" : "enabled\n"; - int r = strlen(buf); - - return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); -} - -static ssize_t -ftraced_write(struct file *filp, const char __user *ubuf, - size_t cnt, loff_t *ppos) -{ - char buf[64]; - long val; - int ret; - - if (cnt >= sizeof(buf)) - return -EINVAL; - - if (copy_from_user(&buf, ubuf, cnt)) - return -EFAULT; - - if (strncmp(buf, "enable", 6) == 0) - val = 1; - else if (strncmp(buf, "disable", 7) == 0) - val = 0; - else { - buf[cnt] = 0; - - ret = strict_strtoul(buf, 10, &val); - if (ret < 0) - return ret; - - val = !!val; - } - - if (val) - ftrace_enable_daemon(); - else - ftrace_disable_daemon(); - - filp->f_pos += cnt; - - return cnt; -} - static struct file_operations ftrace_avail_fops = { .open = ftrace_avail_open, .read = seq_read, @@ -1503,54 +1238,6 @@ static struct file_operations ftrace_notrace_fops = { .release = ftrace_notrace_release, }; -static struct file_operations ftraced_fops = { - .open = tracing_open_generic, - .read = ftraced_read, - .write = ftraced_write, -}; - -/** - * ftrace_force_update - force an update to all recording ftrace functions - */ -int ftrace_force_update(void) -{ - int ret = 0; - - if (unlikely(ftrace_disabled)) - return -ENODEV; - - mutex_lock(&ftrace_sysctl_lock); - mutex_lock(&ftraced_lock); - - /* - * If ftraced_trigger is not set, then there is nothing - * to update. - */ - if (ftraced_trigger && !ftrace_update_code()) - ret = -EBUSY; - - mutex_unlock(&ftraced_lock); - mutex_unlock(&ftrace_sysctl_lock); - - return ret; -} - -static void ftrace_force_shutdown(void) -{ - struct task_struct *task; - int command = FTRACE_DISABLE_CALLS | FTRACE_UPDATE_TRACE_FUNC; - - mutex_lock(&ftraced_lock); - task = ftraced_task; - ftraced_task = NULL; - ftraced_suspend = -1; - ftrace_run_update_code(command); - mutex_unlock(&ftraced_lock); - - if (task) - kthread_stop(task); -} - static __init int ftrace_init_debugfs(void) { struct dentry *d_tracer; @@ -1581,17 +1268,11 @@ static __init int ftrace_init_debugfs(void) pr_warning("Could not create debugfs " "'set_ftrace_notrace' entry\n"); - entry = debugfs_create_file("ftraced_enabled", 0644, d_tracer, - NULL, &ftraced_fops); - if (!entry) - pr_warning("Could not create debugfs " - "'ftraced_enabled' entry\n"); return 0; } fs_initcall(ftrace_init_debugfs); -#ifdef CONFIG_FTRACE_MCOUNT_RECORD static int ftrace_convert_nops(unsigned long *start, unsigned long *end) { @@ -1599,20 +1280,18 @@ static int ftrace_convert_nops(unsigned long *start, unsigned long addr; unsigned long flags; + mutex_lock(&ftrace_start_lock); p = start; while (p < end) { addr = ftrace_call_adjust(*p++); - /* should not be called from interrupt context */ - spin_lock(&ftrace_lock); ftrace_record_ip(addr); - spin_unlock(&ftrace_lock); - ftrace_shutdown_replenish(); } - /* p is ignored */ + /* disable interrupts to prevent kstop machine */ local_irq_save(flags); - __ftrace_update_code(p); + ftrace_update_code(); local_irq_restore(flags); + mutex_unlock(&ftrace_start_lock); return 0; } @@ -1658,130 +1337,34 @@ void __init ftrace_init(void) failed: ftrace_disabled = 1; } -#else /* CONFIG_FTRACE_MCOUNT_RECORD */ -static int ftraced(void *ignore) -{ - unsigned long usecs; - - while (!kthread_should_stop()) { - - set_current_state(TASK_INTERRUPTIBLE); - - /* check once a second */ - schedule_timeout(HZ); - if (unlikely(ftrace_disabled)) - continue; - - mutex_lock(&ftrace_sysctl_lock); - mutex_lock(&ftraced_lock); - if (!ftraced_suspend && !ftraced_stop && - ftrace_update_code()) { - usecs = nsecs_to_usecs(ftrace_update_time); - if (ftrace_update_tot_cnt > 100000) { - ftrace_update_tot_cnt = 0; - pr_info("hm, dftrace overflow: %lu change%s" - " (%lu total) in %lu usec%s\n", - ftrace_update_cnt, - ftrace_update_cnt != 1 ? "s" : "", - ftrace_update_tot_cnt, - usecs, usecs != 1 ? "s" : ""); - ftrace_disabled = 1; - WARN_ON_ONCE(1); - } - } - mutex_unlock(&ftraced_lock); - mutex_unlock(&ftrace_sysctl_lock); - - ftrace_shutdown_replenish(); - } - __set_current_state(TASK_RUNNING); - return 0; -} +#else -static int __init ftrace_dynamic_init(void) +static int __init ftrace_nodyn_init(void) { - struct task_struct *p; - unsigned long addr; - int ret; - - addr = (unsigned long)ftrace_record_ip; - - stop_machine(ftrace_dyn_arch_init, &addr, NULL); - - /* ftrace_dyn_arch_init places the return code in addr */ - if (addr) { - ret = (int)addr; - goto failed; - } - - ret = ftrace_dyn_table_alloc(NR_TO_INIT); - if (ret) - goto failed; - - p = kthread_run(ftraced, NULL, "ftraced"); - if (IS_ERR(p)) { - ret = -1; - goto failed; - } - - last_ftrace_enabled = ftrace_enabled = 1; - ftraced_task = p; - + ftrace_enabled = 1; return 0; - - failed: - ftrace_disabled = 1; - return ret; } +device_initcall(ftrace_nodyn_init); -core_initcall(ftrace_dynamic_init); -#endif /* CONFIG_FTRACE_MCOUNT_RECORD */ - -#else # define ftrace_startup() do { } while (0) # define ftrace_shutdown() do { } while (0) # define ftrace_startup_sysctl() do { } while (0) # define ftrace_shutdown_sysctl() do { } while (0) -# define ftrace_force_shutdown() do { } while (0) #endif /* CONFIG_DYNAMIC_FTRACE */ /** - * ftrace_kill_atomic - kill ftrace from critical sections + * ftrace_kill - kill ftrace * * This function should be used by panic code. It stops ftrace * but in a not so nice way. If you need to simply kill ftrace * from a non-atomic section, use ftrace_kill. */ -void ftrace_kill_atomic(void) -{ - ftrace_disabled = 1; - ftrace_enabled = 0; -#ifdef CONFIG_DYNAMIC_FTRACE - ftraced_suspend = -1; -#endif - clear_ftrace_function(); -} - -/** - * ftrace_kill - totally shutdown ftrace - * - * This is a safety measure. If something was detected that seems - * wrong, calling this function will keep ftrace from doing - * any more modifications, and updates. - * used when something went wrong. - */ void ftrace_kill(void) { - mutex_lock(&ftrace_sysctl_lock); ftrace_disabled = 1; ftrace_enabled = 0; - clear_ftrace_function(); - mutex_unlock(&ftrace_sysctl_lock); - - /* Try to totally disable ftrace */ - ftrace_force_shutdown(); } /** @@ -1870,3 +1453,4 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, mutex_unlock(&ftrace_sysctl_lock); return ret; } + diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 94af1fe..cedf4e2 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -130,7 +130,7 @@ struct buffer_page { static inline void free_buffer_page(struct buffer_page *bpage) { if (bpage->page) - __free_page(bpage->page); + free_page((unsigned long)bpage->page); kfree(bpage); } @@ -966,7 +966,9 @@ rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer, if (unlikely(*delta > (1ULL << 59) && !once++)) { printk(KERN_WARNING "Delta way too big! %llu" " ts=%llu write stamp = %llu\n", - *delta, *ts, cpu_buffer->write_stamp); + (unsigned long long)*delta, + (unsigned long long)*ts, + (unsigned long long)cpu_buffer->write_stamp); WARN_ON(1); } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 47f46cb..8741e5c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -34,6 +34,7 @@ #include <linux/stacktrace.h> #include <linux/ring_buffer.h> +#include <linux/irqflags.h> #include "trace.h" @@ -873,7 +874,7 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) preempt_enable_notrace(); } -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER static void function_trace_call(unsigned long ip, unsigned long parent_ip) { @@ -887,9 +888,6 @@ function_trace_call(unsigned long ip, unsigned long parent_ip) if (unlikely(!ftrace_function_enabled)) return; - if (skip_trace(ip)) - return; - pc = preempt_count(); resched = need_resched(); preempt_disable_notrace(); @@ -2401,9 +2399,10 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf, int i; size_t ret; + ret = cnt; + if (cnt > max_tracer_type_len) cnt = max_tracer_type_len; - ret = cnt; if (copy_from_user(&buf, ubuf, cnt)) return -EFAULT; @@ -2436,8 +2435,8 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf, out: mutex_unlock(&trace_types_lock); - if (ret == cnt) - filp->f_pos += cnt; + if (ret > 0) + filp->f_pos += ret; return ret; } @@ -3120,7 +3119,7 @@ void ftrace_dump(void) dump_ran = 1; /* No turning back! */ - ftrace_kill_atomic(); + ftrace_kill(); for_each_tracing_cpu(cpu) { atomic_inc(&global_trace.data[cpu]->disabled); diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f1f9957..6889ca4 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -335,7 +335,7 @@ void update_max_tr_single(struct trace_array *tr, extern cycle_t ftrace_now(int cpu); -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER void tracing_start_function_trace(void); void tracing_stop_function_trace(void); #else diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index e90eb0c..0f85a64 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -64,7 +64,7 @@ static void function_trace_ctrl_update(struct trace_array *tr) static struct tracer function_trace __read_mostly = { - .name = "ftrace", + .name = "function", .init = function_trace_init, .reset = function_trace_reset, .ctrl_update = function_trace_ctrl_update, diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index a7db7f0..9c74071 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -63,7 +63,7 @@ irq_trace(void) */ static __cacheline_aligned_in_smp unsigned long max_sequence; -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER /* * irqsoff uses its own tracer function to keep the overhead down: */ @@ -104,7 +104,7 @@ static struct ftrace_ops trace_ops __read_mostly = { .func = irqsoff_tracer_call, }; -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ /* * Should this new latency be reported/recorded? diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index fe4a252..3ae93f1 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c @@ -31,7 +31,7 @@ static raw_spinlock_t wakeup_lock = static void __wakeup_reset(struct trace_array *tr); -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER /* * irqsoff uses its own tracer function to keep the overhead down: */ @@ -96,7 +96,7 @@ static struct ftrace_ops trace_ops __read_mostly = { .func = wakeup_tracer_call, }; -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ /* * Should this new latency be reported/recorded? diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index 09cf230..90bc752 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -70,7 +70,7 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count) return ret; } -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER #ifdef CONFIG_DYNAMIC_FTRACE @@ -99,13 +99,6 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace, /* passed in by parameter to fool gcc from optimizing */ func(); - /* update the records */ - ret = ftrace_force_update(); - if (ret) { - printk(KERN_CONT ".. ftraced failed .. "); - return ret; - } - /* * Some archs *cough*PowerPC*cough* add charachters to the * start of the function names. We simply put a '*' to @@ -183,13 +176,6 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) /* make sure msleep has been recorded */ msleep(1); - /* force the recorded functions to be traced */ - ret = ftrace_force_update(); - if (ret) { - printk(KERN_CONT ".. ftraced failed .. "); - return ret; - } - /* start the tracing */ ftrace_enabled = 1; tracer_enabled = 1; @@ -226,7 +212,7 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr) return ret; } -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_IRQSOFF_TRACER int diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 74c5d9a..be682b6 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c @@ -44,6 +44,10 @@ static inline void check_stack(void) if (this_size <= max_stack_size) return; + /* we do not handle interrupt stacks yet */ + if (!object_is_on_stack(&this_size)) + return; + raw_local_irq_save(flags); __raw_spin_lock(&max_stack_lock); diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index f2b7c28..af8c856 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -131,6 +131,9 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe) old = entry->funcs; + if (!old) + return NULL; + debug_print_probes(entry); /* (N -> M), (N > 1, M >= 0) probes */ for (nr_probes = 0; old[nr_probes]; nr_probes++) { @@ -388,6 +391,11 @@ int tracepoint_probe_unregister(const char *name, void *probe) if (entry->rcu_pending) rcu_barrier_sched(); old = tracepoint_entry_remove_probe(entry, probe); + if (!old) { + printk(KERN_WARNING "Warning: Trying to unregister a probe" + "that doesn't exist\n"); + goto end; + } mutex_unlock(&tracepoints_mutex); tracepoint_update_probes(); /* may update entry */ mutex_lock(&tracepoints_mutex); diff --git a/lib/Makefile b/lib/Makefile index 16feaab..7cb65d8 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for some libs needed in the kernel. # -ifdef CONFIG_FTRACE +ifdef CONFIG_FUNCTION_TRACER ORIG_CFLAGS := $(KBUILD_CFLAGS) KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) endif diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c index d640f87..d83660f 100644 --- a/lib/dynamic_printk.c +++ b/lib/dynamic_printk.c @@ -402,6 +402,8 @@ static int __init dynamic_printk_init(void) iter->logical_modname, iter->flag_names, iter->hash, iter->hash2); } + if (dynamic_enabled == DYNAMIC_ENABLED_ALL) + set_all(true); return 0; } module_init(dynamic_printk_init); @@ -411,7 +413,7 @@ static int __init dynamic_printk_setup(char *str) { if (str) return -ENOENT; - set_all(true); + dynamic_enabled = DYNAMIC_ENABLED_ALL; return 0; } /* Use early_param(), so we can get debug output as early as possible */ diff --git a/lib/swiotlb.c b/lib/swiotlb.c index f8eebd48..78330c3 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -497,8 +497,10 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, printk("hwdev DMA mask = 0x%016Lx, dev_addr = 0x%016Lx\n", (unsigned long long)*hwdev->dma_mask, (unsigned long long)dev_addr); - panic("swiotlb_alloc_coherent: allocated memory is out of " - "range for device"); + + /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ + unmap_single(hwdev, ret, size, DMA_TO_DEVICE); + return NULL; } *dma_handle = dev_addr; return ret; diff --git a/mm/filemap.c b/mm/filemap.c index ab85536..f3e5f89 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2029,48 +2029,8 @@ int pagecache_write_begin(struct file *file, struct address_space *mapping, { const struct address_space_operations *aops = mapping->a_ops; - if (aops->write_begin) { - return aops->write_begin(file, mapping, pos, len, flags, + return aops->write_begin(file, mapping, pos, len, flags, pagep, fsdata); - } else { - int ret; - pgoff_t index = pos >> PAGE_CACHE_SHIFT; - unsigned offset = pos & (PAGE_CACHE_SIZE - 1); - struct inode *inode = mapping->host; - struct page *page; -again: - page = __grab_cache_page(mapping, index); - *pagep = page; - if (!page) - return -ENOMEM; - - if (flags & AOP_FLAG_UNINTERRUPTIBLE && !PageUptodate(page)) { - /* - * There is no way to resolve a short write situation - * for a !Uptodate page (except by double copying in - * the caller done by generic_perform_write_2copy). - * - * Instead, we have to bring it uptodate here. - */ - ret = aops->readpage(file, page); - page_cache_release(page); - if (ret) { - if (ret == AOP_TRUNCATED_PAGE) - goto again; - return ret; - } - goto again; - } - - ret = aops->prepare_write(file, page, offset, offset+len); - if (ret) { - unlock_page(page); - page_cache_release(page); - if (pos + len > inode->i_size) - vmtruncate(inode, inode->i_size); - } - return ret; - } } EXPORT_SYMBOL(pagecache_write_begin); @@ -2079,32 +2039,9 @@ int pagecache_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { const struct address_space_operations *aops = mapping->a_ops; - int ret; - - if (aops->write_end) { - mark_page_accessed(page); - ret = aops->write_end(file, mapping, pos, len, copied, - page, fsdata); - } else { - unsigned offset = pos & (PAGE_CACHE_SIZE - 1); - struct inode *inode = mapping->host; - - flush_dcache_page(page); - ret = aops->commit_write(file, page, offset, offset+len); - unlock_page(page); - mark_page_accessed(page); - page_cache_release(page); - - if (ret < 0) { - if (pos + len > inode->i_size) - vmtruncate(inode, inode->i_size); - } else if (ret > 0) - ret = min_t(size_t, copied, ret); - else - ret = copied; - } - return ret; + mark_page_accessed(page); + return aops->write_end(file, mapping, pos, len, copied, page, fsdata); } EXPORT_SYMBOL(pagecache_write_end); @@ -2226,174 +2163,6 @@ repeat: } EXPORT_SYMBOL(__grab_cache_page); -static ssize_t generic_perform_write_2copy(struct file *file, - struct iov_iter *i, loff_t pos) -{ - struct address_space *mapping = file->f_mapping; - const struct address_space_operations *a_ops = mapping->a_ops; - struct inode *inode = mapping->host; - long status = 0; - ssize_t written = 0; - - do { - struct page *src_page; - struct page *page; - pgoff_t index; /* Pagecache index for current page */ - unsigned long offset; /* Offset into pagecache page */ - unsigned long bytes; /* Bytes to write to page */ - size_t copied; /* Bytes copied from user */ - - offset = (pos & (PAGE_CACHE_SIZE - 1)); - index = pos >> PAGE_CACHE_SHIFT; - bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset, - iov_iter_count(i)); - - /* - * a non-NULL src_page indicates that we're doing the - * copy via get_user_pages and kmap. - */ - src_page = NULL; - - /* - * Bring in the user page that we will copy from _first_. - * Otherwise there's a nasty deadlock on copying from the - * same page as we're writing to, without it being marked - * up-to-date. - * - * Not only is this an optimisation, but it is also required - * to check that the address is actually valid, when atomic - * usercopies are used, below. - */ - if (unlikely(iov_iter_fault_in_readable(i, bytes))) { - status = -EFAULT; - break; - } - - page = __grab_cache_page(mapping, index); - if (!page) { - status = -ENOMEM; - break; - } - - /* - * non-uptodate pages cannot cope with short copies, and we - * cannot take a pagefault with the destination page locked. - * So pin the source page to copy it. - */ - if (!PageUptodate(page) && !segment_eq(get_fs(), KERNEL_DS)) { - unlock_page(page); - - src_page = alloc_page(GFP_KERNEL); - if (!src_page) { - page_cache_release(page); - status = -ENOMEM; - break; - } - - /* - * Cannot get_user_pages with a page locked for the - * same reason as we can't take a page fault with a - * page locked (as explained below). - */ - copied = iov_iter_copy_from_user(src_page, i, - offset, bytes); - if (unlikely(copied == 0)) { - status = -EFAULT; - page_cache_release(page); - page_cache_release(src_page); - break; - } - bytes = copied; - - lock_page(page); - /* - * Can't handle the page going uptodate here, because - * that means we would use non-atomic usercopies, which - * zero out the tail of the page, which can cause - * zeroes to become transiently visible. We could just - * use a non-zeroing copy, but the APIs aren't too - * consistent. - */ - if (unlikely(!page->mapping || PageUptodate(page))) { - unlock_page(page); - page_cache_release(page); - page_cache_release(src_page); - continue; - } - } - - status = a_ops->prepare_write(file, page, offset, offset+bytes); - if (unlikely(status)) - goto fs_write_aop_error; - - if (!src_page) { - /* - * Must not enter the pagefault handler here, because - * we hold the page lock, so we might recursively - * deadlock on the same lock, or get an ABBA deadlock - * against a different lock, or against the mmap_sem - * (which nests outside the page lock). So increment - * preempt count, and use _atomic usercopies. - * - * The page is uptodate so we are OK to encounter a - * short copy: if unmodified parts of the page are - * marked dirty and written out to disk, it doesn't - * really matter. - */ - pagefault_disable(); - copied = iov_iter_copy_from_user_atomic(page, i, - offset, bytes); - pagefault_enable(); - } else { - void *src, *dst; - src = kmap_atomic(src_page, KM_USER0); - dst = kmap_atomic(page, KM_USER1); - memcpy(dst + offset, src + offset, bytes); - kunmap_atomic(dst, KM_USER1); - kunmap_atomic(src, KM_USER0); - copied = bytes; - } - flush_dcache_page(page); - - status = a_ops->commit_write(file, page, offset, offset+bytes); - if (unlikely(status < 0)) - goto fs_write_aop_error; - if (unlikely(status > 0)) /* filesystem did partial write */ - copied = min_t(size_t, copied, status); - - unlock_page(page); - mark_page_accessed(page); - page_cache_release(page); - if (src_page) - page_cache_release(src_page); - - iov_iter_advance(i, copied); - pos += copied; - written += copied; - - balance_dirty_pages_ratelimited(mapping); - cond_resched(); - continue; - -fs_write_aop_error: - unlock_page(page); - page_cache_release(page); - if (src_page) - page_cache_release(src_page); - - /* - * prepare_write() may have instantiated a few blocks - * outside i_size. Trim these off again. Don't need - * i_size_read because we hold i_mutex. - */ - if (pos + bytes > inode->i_size) - vmtruncate(inode, inode->i_size); - break; - } while (iov_iter_count(i)); - - return written ? written : status; -} - static ssize_t generic_perform_write(struct file *file, struct iov_iter *i, loff_t pos) { @@ -2494,10 +2263,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, struct iov_iter i; iov_iter_init(&i, iov, nr_segs, count, written); - if (a_ops->write_begin) - status = generic_perform_write(file, &i, pos); - else - status = generic_perform_write_2copy(file, &i, pos); + status = generic_perform_write(file, &i, pos); if (likely(status >= 0)) { written += status; @@ -175,7 +175,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) /* Don't let a single process grow too big: leave 3% of the size of this process for other processes */ - allowed -= mm->total_vm / 32; + if (mm) + allowed -= mm->total_vm / 32; /* * cast `allowed' as a signed long because vm_committed_space @@ -1454,7 +1454,8 @@ int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin) /* Don't let a single process grow too big: leave 3% of the size of this process for other processes */ - allowed -= current->mm->total_vm / 32; + if (mm) + allowed -= mm->total_vm / 32; /* * cast `allowed' as a signed long because vm_committed_space @@ -161,8 +161,8 @@ static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) */ static inline int shmem_acct_size(unsigned long flags, loff_t size) { - return (flags & VM_ACCOUNT)? - security_vm_enough_memory(VM_ACCT(size)): 0; + return (flags & VM_ACCOUNT) ? + security_vm_enough_memory_kern(VM_ACCT(size)) : 0; } static inline void shmem_unacct_size(unsigned long flags, loff_t size) @@ -179,8 +179,8 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) */ static inline int shmem_acct_block(unsigned long flags) { - return (flags & VM_ACCOUNT)? - 0: security_vm_enough_memory(VM_ACCT(PAGE_CACHE_SIZE)); + return (flags & VM_ACCOUNT) ? + 0 : security_vm_enough_memory_kern(VM_ACCT(PAGE_CACHE_SIZE)); } static inline void shmem_unacct_blocks(unsigned long flags, long pages) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 0365369..f1cc03b 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -897,7 +897,8 @@ EXPORT_SYMBOL(vm_unmap_ram); * @count: number of pages * @node: prefer to allocate data structures on this node * @prot: memory protection to use. PAGE_KERNEL for regular RAM - * @returns: a pointer to the address that has been mapped, or NULL on failure + * + * Returns: a pointer to the address that has been mapped, or %NULL on failure */ void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t prot) { diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 99f656d..a47f5ba 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1973,28 +1973,27 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) /* make sure that we don't pick a non-existing transmit queue */ ntxq = pkt_dev->odev->real_num_tx_queues; - if (ntxq <= num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) { + if (ntxq > num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) { printk(KERN_WARNING "pktgen: WARNING: QUEUE_MAP_CPU " - "disabled because CPU count (%d) exceeds number ", - num_online_cpus()); - printk(KERN_WARNING "pktgen: WARNING: of tx queues " - "(%d) on %s \n", ntxq, pkt_dev->odev->name); + "disabled because CPU count (%d) exceeds number " + "of tx queues (%d) on %s\n", num_online_cpus(), ntxq, + pkt_dev->odev->name); pkt_dev->flags &= ~F_QUEUE_MAP_CPU; } if (ntxq <= pkt_dev->queue_map_min) { printk(KERN_WARNING "pktgen: WARNING: Requested " - "queue_map_min (%d) exceeds number of tx\n", - pkt_dev->queue_map_min); - printk(KERN_WARNING "pktgen: WARNING: queues (%d) on " - "%s, resetting\n", ntxq, pkt_dev->odev->name); + "queue_map_min (zero-based) (%d) exceeds valid range " + "[0 - %d] for (%d) queues on %s, resetting\n", + pkt_dev->queue_map_min, (ntxq ?: 1)- 1, ntxq, + pkt_dev->odev->name); pkt_dev->queue_map_min = ntxq - 1; } - if (ntxq <= pkt_dev->queue_map_max) { + if (pkt_dev->queue_map_max >= ntxq) { printk(KERN_WARNING "pktgen: WARNING: Requested " - "queue_map_max (%d) exceeds number of tx\n", - pkt_dev->queue_map_max); - printk(KERN_WARNING "pktgen: WARNING: queues (%d) on " - "%s, resetting\n", ntxq, pkt_dev->odev->name); + "queue_map_max (zero-based) (%d) exceeds valid range " + "[0 - %d] for (%d) queues on %s, resetting\n", + pkt_dev->queue_map_max, (ntxq ?: 1)- 1, ntxq, + pkt_dev->odev->name); pkt_dev->queue_map_max = ntxq - 1; } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e4c5ac9..ba85d88 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2279,6 +2279,11 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, } memset(&opts, 0, sizeof(opts)); +#ifdef CONFIG_SYN_COOKIES + if (unlikely(req->cookie_ts)) + TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); + else +#endif TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, &md5) + @@ -2304,11 +2309,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ th->window = htons(min(req->rcv_wnd, 65535U)); -#ifdef CONFIG_SYN_COOKIES - if (unlikely(req->cookie_ts)) - TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); - else -#endif tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); th->doff = (tcp_header_size >> 2); TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index 0b024cd..98f4807 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c @@ -94,8 +94,8 @@ minstrel_stats_open(struct inode *inode, struct file *file) prob / 10, prob % 10, mr->last_success, mr->last_attempts, - mr->succ_hist, - mr->att_hist); + (unsigned long long)mr->succ_hist, + (unsigned long long)mr->att_hist); } p += sprintf(p, "\nTotal packet count:: ideal %d " "lookaround %d\n\n", @@ -106,7 +106,7 @@ minstrel_stats_open(struct inode *inode, struct file *file) return 0; } -static int +static ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) { struct minstrel_stats_info *ms; diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index b9d97ef..defeb7a 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -261,6 +261,8 @@ static inline int can_respond(struct sk_buff *skb) return 0; /* we are not the destination */ if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5)) return 0; + if (ph->pn_res == PN_COMMGR) /* indications */ + return 0; ph = pn_hdr(skb); /* re-acquires the pointer */ pm = pn_msg(skb); @@ -309,7 +311,8 @@ static int send_reset_indications(struct sk_buff *rskb) return pn_raw_send(data, sizeof(data), rskb->dev, pn_object(oph->pn_sdev, 0x00), - pn_object(oph->pn_rdev, oph->pn_robj), 0x10); + pn_object(oph->pn_rdev, oph->pn_robj), + PN_COMMGR); } diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 21124ec..bfdade7 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c @@ -256,6 +256,11 @@ static struct input_handler rfkill_handler = { static int __init rfkill_handler_init(void) { + unsigned long last_run = jiffies - msecs_to_jiffies(500); + rfkill_wlan.last = last_run; + rfkill_bt.last = last_run; + rfkill_uwb.last = last_run; + rfkill_wimax.last = last_run; return input_register_handler(&rfkill_handler); } diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 5ed4cbf..468fbc9 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -198,10 +198,16 @@ cmd_modversions = \ fi; endif +ifdef CONFIG_64BIT +arch_bits = 64 +else +arch_bits = 32 +endif + ifdef CONFIG_FTRACE_MCOUNT_RECORD cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \ - "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \ - "$(MV)" "$(@)"; + "$(ARCH)" "$(arch_bits)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" \ + "$(NM)" "$(RM)" "$(MV)" "$(@)"; endif define rule_cc_o_c diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl index 5e7316e..d2c61ef 100644 --- a/scripts/bootgraph.pl +++ b/scripts/bootgraph.pl @@ -37,7 +37,10 @@ # dmesg | perl scripts/bootgraph.pl > output.svg # -my %start, %end; +use strict; + +my %start; +my %end; my $done = 0; my $maxtime = 0; my $firsttime = 100; @@ -105,18 +108,20 @@ my $threshold = ($maxtime - $firsttime) / 60.0; my $stylecounter = 0; my %rows; my $rowscount = 1; -while (($key,$value) = each %start) { +my @initcalls = sort { $start{$a} <=> $start{$b} } keys(%start); +my $key; +foreach $key (@initcalls) { my $duration = $end{$key} - $start{$key}; if ($duration >= $threshold) { - my $s, $s2, $e, $y; - $pid = $pids{$key}; + my ($s, $s2, $e, $w, $y, $y2, $style); + my $pid = $pids{$key}; if (!defined($rows{$pid})) { $rows{$pid} = $rowscount; $rowscount = $rowscount + 1; } - $s = ($value - $firsttime) * $mult; + $s = ($start{$key} - $firsttime) * $mult; $s2 = $s + 6; $e = ($end{$key} - $firsttime) * $mult; $w = $e - $s; @@ -140,9 +145,9 @@ while (($key,$value) = each %start) { my $time = $firsttime; my $step = ($maxtime - $firsttime) / 15; while ($time < $maxtime) { - my $s2 = ($time - $firsttime) * $mult; + my $s3 = ($time - $firsttime) * $mult; my $tm = int($time * 100) / 100.0; - print "<text transform=\"translate($s2,89) rotate(90)\">$tm</text>\n"; + print "<text transform=\"translate($s3,89) rotate(90)\">$tm</text>\n"; $time = $time + $step; } diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index f56d760..6b9fe3e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl @@ -106,7 +106,13 @@ if ($#ARGV < 6) { exit(1); } -my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV; +my ($arch, $bits, $objdump, $objcopy, $cc, + $ld, $nm, $rm, $mv, $inputfile) = @ARGV; + +# Acceptable sections to record. +my %text_sections = ( + ".text" => 1, +); $objdump = "objdump" if ((length $objdump) == 0); $objcopy = "objcopy" if ((length $objcopy) == 0); @@ -129,8 +135,16 @@ my $function_regex; # Find the name of a function # (return offset and func name) my $mcount_regex; # Find the call site to mcount (return offset) +if ($arch eq "x86") { + if ($bits == 64) { + $arch = "x86_64"; + } else { + $arch = "i386"; + } +} + if ($arch eq "x86_64") { - $section_regex = "Disassembly of section"; + $section_regex = "Disassembly of section\\s+(\\S+):"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$"; $type = ".quad"; @@ -142,7 +156,7 @@ if ($arch eq "x86_64") { $cc .= " -m64"; } elsif ($arch eq "i386") { - $section_regex = "Disassembly of section"; + $section_regex = "Disassembly of section\\s+(\\S+):"; $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:"; $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$"; $type = ".long"; @@ -289,7 +303,13 @@ my $text; while (<IN>) { # is it a section? if (/$section_regex/) { - $read_function = 1; + + # Only record text sections that we know are safe + if (defined($text_sections{$1})) { + $read_function = 1; + } else { + $read_function = 0; + } # print out any recorded offsets update_funcs() if ($text_found); diff --git a/security/security.c b/security/security.c index 255b085..c0acfa7 100644 --- a/security/security.c +++ b/security/security.c @@ -198,14 +198,23 @@ int security_settime(struct timespec *ts, struct timezone *tz) int security_vm_enough_memory(long pages) { + WARN_ON(current->mm == NULL); return security_ops->vm_enough_memory(current->mm, pages); } int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) { + WARN_ON(mm == NULL); return security_ops->vm_enough_memory(mm, pages); } +int security_vm_enough_memory_kern(long pages) +{ + /* If current->mm is a kernel thread then we will pass NULL, + for this specific case that is fine */ + return security_ops->vm_enough_memory(current->mm, pages); +} + int security_bprm_alloc(struct linux_binprm *bprm) { return security_ops->bprm_alloc_security(bprm); diff --git a/sound/core/control.c b/sound/core/control.c index 6d71f9a..b0bf426 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -225,8 +225,13 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, kctl.id.iface = ncontrol->iface; kctl.id.device = ncontrol->device; kctl.id.subdevice = ncontrol->subdevice; - if (ncontrol->name) + if (ncontrol->name) { strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)); + if (strcmp(ncontrol->name, kctl.id.name) != 0) + snd_printk(KERN_WARNING + "Control name '%s' truncated to '%s'\n", + ncontrol->name, kctl.id.name); + } kctl.id.index = ncontrol->index; kctl.count = ncontrol->count ? ncontrol->count : 1; access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c index eb9bc36..c180598 100644 --- a/sound/oss/kahlua.c +++ b/sound/oss/kahlua.c @@ -1,7 +1,7 @@ /* * Initialisation code for Cyrix/NatSemi VSA1 softaudio * - * (C) Copyright 2003 Red Hat Inc <alan@redhat.com> + * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk> * * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. * The older version (VSA1) provides fairly good soundblaster emulation diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 6704acb..bd510ec 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1927,9 +1927,9 @@ static int snd_ac97_dev_register(struct snd_device *device) ac97->dev.bus = &ac97_bus_type; ac97->dev.parent = ac97->bus->card->dev; ac97->dev.release = ac97_device_release; - snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s", - ac97->bus->card->number, ac97->num, - snd_ac97_get_short_name(ac97)); + dev_set_name(&ac97->dev, "%d-%d:%s", + ac97->bus->card->number, ac97->num, + snd_ac97_get_short_name(ac97)); if ((err = device_register(&ac97->dev)) < 0) { snd_printk(KERN_ERR "Can't register ac97 bus\n"); ac97->dev.bus = NULL; diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 92f3a97..a7f38e6 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -932,7 +932,7 @@ snd_ad1889_create(struct snd_card *card, goto free_and_ret; chip->bar = pci_resource_start(pci, 0); - chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0)); + chip->iobase = pci_ioremap_bar(pci, 0); if (chip->iobase == NULL) { printk(KERN_ERR PFX "unable to reserve region.\n"); err = -EBUSY; diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 085a52b..226fe82 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1609,7 +1609,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, return err; } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); snd_atiixp_free(chip); diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 2f10630..0e6e5cc 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -1252,7 +1252,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, return err; } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); snd_atiixp_free(chip); diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 68368e4..a36d4d1 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -180,8 +180,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0) goto regions_out; - chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + chip->mmio = pci_ioremap_bar(pci, 0); if (!chip->mmio) { printk(KERN_ERR "MMIO area remap failed.\n"); err = -ENOMEM; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 3aa8d97..1aa1c04 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -749,8 +749,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card, pci_disable_device(pci); return err; } - chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + chip->mmio = pci_ioremap_bar(pci, 0); if (!chip->mmio) { snd_printk(KERN_ERR "cannot remap io memory\n"); err = -ENOMEM; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index ef9308f..192e784 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1382,8 +1382,8 @@ static int __devinit snd_cs4281_create(struct snd_card *card, chip->ba0_addr = pci_resource_start(pci, 0); chip->ba1_addr = pci_resource_start(pci, 1); - chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0)); - chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1)); + chip->ba0 = pci_ioremap_bar(pci, 0); + chip->ba1 = pci_ioremap_bar(pci, 1); if (!chip->ba0 || !chip->ba1) { snd_cs4281_free(chip); return -ENOMEM; diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index 7ff8b68..6dea5b5 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c @@ -2,7 +2,7 @@ * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio * * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net> - * (C) Copyright 2003 Red Hat Inc <alan@redhat.com> + * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk> * * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did * mess with it a bit. The chip seems to have to have trouble with full duplex @@ -132,7 +132,7 @@ static int __devinit snd_cs5530_create(struct snd_card *card, } chip->pci_base = pci_resource_start(pci, 0); - mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); + mem = pci_ioremap_bar(pci, 0); if (mem == NULL) { kfree(chip); pci_disable_device(pci); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 6447754..ba1ab73 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -64,6 +64,7 @@ static struct hda_vendor_id hda_vendor_ids[] = { { 0x14f1, "Conexant" }, { 0x17e8, "Chrontel" }, { 0x1854, "LG" }, + { 0x1aec, "Wolfson Microelectronics" }, { 0x434d, "C-Media" }, { 0x8384, "SigmaTel" }, {} /* terminator */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9f316c1..35722ec 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -45,6 +45,7 @@ #include <linux/slab.h> #include <linux/pci.h> #include <linux/mutex.h> +#include <linux/reboot.h> #include <sound/core.h> #include <sound/initval.h> #include "hda_codec.h" @@ -397,6 +398,9 @@ struct azx { /* for pending irqs */ struct work_struct irq_pending_work; + + /* reboot notifier (for mysterious hangup problem at power-down) */ + struct notifier_block reboot_notifier; }; /* driver types */ @@ -1979,12 +1983,36 @@ static int azx_resume(struct pci_dev *pci) /* + * reboot notifier for hang-up problem at power-down + */ +static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) +{ + struct azx *chip = container_of(nb, struct azx, reboot_notifier); + azx_stop_chip(chip); + return NOTIFY_OK; +} + +static void azx_notifier_register(struct azx *chip) +{ + chip->reboot_notifier.notifier_call = azx_halt; + register_reboot_notifier(&chip->reboot_notifier); +} + +static void azx_notifier_unregister(struct azx *chip) +{ + if (chip->reboot_notifier.notifier_call) + unregister_reboot_notifier(&chip->reboot_notifier); +} + +/* * destructor */ static int azx_free(struct azx *chip) { int i; + azx_notifier_unregister(chip); + if (chip->initialized) { azx_clear_irq_pending(chip); for (i = 0; i < chip->num_streams; i++) @@ -2158,7 +2186,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR SFX "ioremap error\n"); err = -ENXIO; @@ -2348,6 +2376,7 @@ static int __devinit azx_probe(struct pci_dev *pci, pci_set_drvdata(pci, card); chip->running = 1; power_down_all_codecs(chip); + azx_notifier_register(chip); dev++; return err; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2b00c4a..d3fd432 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3860,6 +3860,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ef4955c..4eceab9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -307,6 +307,13 @@ struct alc_spec { /* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; + +#ifdef SND_HDA_NEEDS_RESUME +#define ALC_MAX_PINS 16 + unsigned int num_pins; + hda_nid_t pin_nids[ALC_MAX_PINS]; + unsigned int pin_cfgs[ALC_MAX_PINS]; +#endif }; /* @@ -2778,6 +2785,64 @@ static void alc_free(struct hda_codec *codec) codec->spec = NULL; /* to be sure */ } +#ifdef SND_HDA_NEEDS_RESUME +static void store_pin_configs(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t nid, end_nid; + + end_nid = codec->start_nid + codec->num_nodes; + for (nid = codec->start_nid; nid < end_nid; nid++) { + unsigned int wid_caps = get_wcaps(codec, nid); + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wid_type != AC_WID_PIN) + continue; + if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) + break; + spec->pin_nids[spec->num_pins] = nid; + spec->pin_cfgs[spec->num_pins] = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + spec->num_pins++; + } +} + +static void resume_pin_configs(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_pins; i++) { + hda_nid_t pin_nid = spec->pin_nids[i]; + unsigned int pin_config = spec->pin_cfgs[i]; + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, + pin_config & 0x000000ff); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, + (pin_config & 0x0000ff00) >> 8); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, + (pin_config & 0x00ff0000) >> 16); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + pin_config >> 24); + } +} + +static int alc_resume(struct hda_codec *codec) +{ + resume_pin_configs(codec); + codec->patch_ops.init(codec); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); + return 0; +} +#else +#define store_pin_configs(codec) +#endif + /* */ static struct hda_codec_ops alc_patch_ops = { @@ -2786,6 +2851,9 @@ static struct hda_codec_ops alc_patch_ops = { .init = alc_init, .free = alc_free, .unsol_event = alc_unsol_event, +#ifdef SND_HDA_NEEDS_RESUME + .resume = alc_resume, +#endif #ifdef CONFIG_SND_HDA_POWER_SAVE .check_power_status = alc_check_power_status, #endif @@ -3832,6 +3900,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + store_pin_configs(codec); return 1; } @@ -5250,6 +5319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) } spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -10313,6 +10383,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -11447,6 +11518,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -12230,6 +12302,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc269_capture_mixer; spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -13316,6 +13389,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc861_capture_mixer; spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -14427,6 +14501,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -16258,6 +16333,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; + + store_pin_configs(codec); return 1; } diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 788fdc6..df9b0bc 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -566,10 +566,8 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, nid = codec->slave_dig_outs[smux_idx - 1]; if (spec->cur_smux[smux_idx] == smux->num_items - 1) val = AMP_OUT_MUTE; - if (smux_idx == 0) - nid = spec->multiout.dig_out_nid; else - nid = codec->slave_dig_outs[smux_idx - 1]; + val = AMP_OUT_UNMUTE; /* un/mute SPDIF out */ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 5b44238..58d7cda 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2688,12 +2688,13 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, return err; } - if (ice_has_con_ac97(ice)) + if (ice_has_con_ac97(ice)) { err = snd_ice1712_pcm(ice, pcm_dev++, NULL); if (err < 0) { snd_card_free(card); return err; } + } err = snd_ice1712_ac97_mixer(ice); if (err < 0) { @@ -2715,12 +2716,13 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, } } - if (ice_has_con_ac97(ice)) + if (ice_has_con_ac97(ice)) { err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); if (err < 0) { snd_card_free(card); return err; } + } if (!c->no_mpu401) { err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index c88d1ea..19d3391 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2702,6 +2702,7 @@ static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = { SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000), SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100), SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000), + SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000), SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000), { } /* terminator */ }; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 2d0dce6..ae7601f 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1314,8 +1314,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, } for (i = 0; i < 2; i++) { mgr->mem[i].phys = pci_resource_start(pci, i); - mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys, - pci_resource_len(pci, i)); + mgr->mem[i].virt = pci_ioremap_bar(pci, i); if (!mgr->mem[i].virt) { printk(KERN_ERR "unable to remap resource 0x%lx\n", mgr->mem[i].phys); diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 827587f..e020c16 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -70,12 +70,24 @@ static struct sport_param sport_params[2] = { } }; -static u16 sport_req[][7] = { - { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}, - { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, - P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}, -}; +/* + * Setting the TFS pin selector for SPORT 0 based on whether the selected + * port id F or G. If the port is F then no conflict should exist for the + * TFS. When Port G is selected and EMAC then there is a conflict between + * the PHY interrupt line and TFS. Current settings prevent the conflict + * by ignoring the TFS pin when Port G is selected. This allows both + * ssm2602 using Port G and EMAC concurrently. + */ +#ifdef CONFIG_BF527_SPORT0_PORTF +#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) +#else +#define LOCAL_SPORT0_TFS (0) +#endif + +static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0}, + {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI, + P_SPORT1_RSCLK, P_SPORT1_TFS, 0} }; static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) @@ -98,23 +110,21 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, ret = -EINVAL; break; default: + printk(KERN_ERR "%s: Unknown DAI format type\n", __func__); ret = -EINVAL; break; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - ret = -EINVAL; - break; - case SND_SOC_DAIFMT_CBM_CFS: - ret = -EINVAL; - break; case SND_SOC_DAIFMT_CBM_CFM: break; + case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBM_CFS: case SND_SOC_DAIFMT_CBS_CFM: ret = -EINVAL; break; default: + printk(KERN_ERR "%s: Unknown DAI master type\n", __func__); ret = -EINVAL; break; } diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index aba402b..945b32e 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -140,7 +140,7 @@ SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), -SOC_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), +SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), SOC_ENUM("ALC Function", wm9713_enum[6]), SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 8692329..94a02ea 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -277,7 +277,7 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs; u16 imr; u8 psc_cmd; - long flags; + unsigned long flags; if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) s = &psc_i2s->capture; @@ -699,9 +699,11 @@ static ssize_t psc_i2s_stat_store(struct device *dev, return count; } -DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); -DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); -DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); +static DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); +static DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); +static DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); /* --------------------------------------------------------------------- * OF platform bus binding code: @@ -819,8 +821,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op, /* Register the SYSFS files */ rc = device_create_file(psc_i2s->dev, &dev_attr_status); - rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); - rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); + rc |= device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); + rc |= device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); if (rc) dev_info(psc_i2s->dev, "error creating sysfs files\n"); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 462e635d..a3adbf0 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1462,7 +1462,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - unsigned int shift = mc->min; + unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; if (max == 1) diff --git a/sound/sound_core.c b/sound/sound_core.c index faef87a..a75b289 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -57,7 +57,7 @@ module_exit(cleanup_soundcore); /* * OSS sound core handling. Breaks out sound functions to submodules * - * Author: Alan Cox <alan.cox@linux.org> + * Author: Alan Cox <alan@lxorguk.ukuu.org.uk> * * Fixes: * diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h index 69689e7..9211575 100644 --- a/sound/usb/usbquirks.h +++ b/sound/usb/usbquirks.h @@ -1480,6 +1480,36 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +{ + /* Advanced modes of the Edirol UA-25EX. + * For the standard mode, UA-25EX has ID 0582:00e7, which + * offers only 16-bit PCM at 44.1 kHz and no MIDI. + */ + USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e6), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "EDIROL", + .product_name = "UA-25EX", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_EDIROL_UAXX + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_EDIROL_UAXX + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_EDIROL_UAXX + }, + { + .ifnum = -1 + } + } + } +}, /* Guillemot devices */ { diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index d0169f5..55ad76e 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c @@ -25,15 +25,23 @@ #include "ioapic.h" /* This should be called with the kvm->lock mutex held */ -void kvm_set_irq(struct kvm *kvm, int irq, int level) +void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level) { + unsigned long *irq_state = (unsigned long *)&kvm->arch.irq_states[irq]; + + /* Logical OR for level trig interrupt */ + if (level) + set_bit(irq_source_id, irq_state); + else + clear_bit(irq_source_id, irq_state); + /* Not possible to detect if the guest uses the PIC or the * IOAPIC. So set the bit in both. The guest will ignore * writes to the unused one. */ - kvm_ioapic_set_irq(kvm->arch.vioapic, irq, level); + kvm_ioapic_set_irq(kvm->arch.vioapic, irq, !!(*irq_state)); #ifdef CONFIG_X86 - kvm_pic_set_irq(pic_irqchip(kvm), irq, level); + kvm_pic_set_irq(pic_irqchip(kvm), irq, !!(*irq_state)); #endif } @@ -58,3 +66,31 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, { hlist_del(&kian->link); } + +/* The caller must hold kvm->lock mutex */ +int kvm_request_irq_source_id(struct kvm *kvm) +{ + unsigned long *bitmap = &kvm->arch.irq_sources_bitmap; + int irq_source_id = find_first_zero_bit(bitmap, + sizeof(kvm->arch.irq_sources_bitmap)); + if (irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { + printk(KERN_WARNING "kvm: exhaust allocatable IRQ sources!\n"); + irq_source_id = -EFAULT; + } else + set_bit(irq_source_id, bitmap); + return irq_source_id; +} + +void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id) +{ + int i; + + if (irq_source_id <= 0 || + irq_source_id >= sizeof(kvm->arch.irq_sources_bitmap)) { + printk(KERN_ERR "kvm: IRQ source ID out of range!\n"); + return; + } + for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++) + clear_bit(irq_source_id, &kvm->arch.irq_states[i]); + clear_bit(irq_source_id, &kvm->arch.irq_sources_bitmap); +} diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cf0ab8e..a87f45e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -105,14 +105,12 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) */ mutex_lock(&assigned_dev->kvm->lock); kvm_set_irq(assigned_dev->kvm, + assigned_dev->irq_source_id, assigned_dev->guest_irq, 1); mutex_unlock(&assigned_dev->kvm->lock); kvm_put_kvm(assigned_dev->kvm); } -/* FIXME: Implement the OR logic needed to make shared interrupts on - * this line behave properly - */ static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) { struct kvm_assigned_dev_kernel *assigned_dev = @@ -134,7 +132,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) dev = container_of(kian, struct kvm_assigned_dev_kernel, ack_notifier); - kvm_set_irq(dev->kvm, dev->guest_irq, 0); + kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); enable_irq(dev->host_irq); } @@ -146,6 +144,7 @@ static void kvm_free_assigned_device(struct kvm *kvm, free_irq(assigned_dev->host_irq, (void *)assigned_dev); kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier); + kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id); if (cancel_work_sync(&assigned_dev->interrupt_work)) /* We had pending work. That means we will have to take @@ -215,6 +214,11 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, match->ack_notifier.gsi = assigned_irq->guest_irq; match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; kvm_register_irq_ack_notifier(kvm, &match->ack_notifier); + r = kvm_request_irq_source_id(kvm); + if (r < 0) + goto out_release; + else + match->irq_source_id = r; /* Even though this is PCI, we don't want to use shared * interrupts. Sharing host devices with guest-assigned devices |