summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/bluez/bluez-cups-backend_3.28.bb27
-rw-r--r--packages/bluez/bluez-gnome_0.24.bb14
-rw-r--r--packages/bluez/bluez-gstreamer-plugin_3.28.bb27
-rw-r--r--packages/bluez/bluez-libs_3.28.bb4
-rw-r--r--packages/bluez/bluez-utils-3.28/.mtn2git_empty (renamed from packages/dbench/dbench/.mtn2git_empty)0
-rw-r--r--packages/bluez/bluez-utils-3.28/hciattach-ti-bts.patch477
-rw-r--r--packages/bluez/bluez-utils-alsa_3.28.bb25
-rw-r--r--packages/bluez/bluez-utils_3.28.bb30
-rw-r--r--packages/cmake/cmake-native_2.4.8.bb10
-rw-r--r--packages/cmake/cmake.inc1
-rw-r--r--packages/dbench/dbench_4.0.bb (renamed from packages/dbench/dbench_3.04.bb)8
-rw-r--r--packages/dbench/files/.mtn2git_empty0
-rw-r--r--packages/dbench/files/destdir.patch (renamed from packages/dbench/dbench/destdir.patch)0
-rw-r--r--packages/dbench/files/makefile.patch13
-rw-r--r--packages/dbus/dbus-native_1.0.3.bb2
-rw-r--r--packages/glibc/eglibc-initial_svn.bb2
-rw-r--r--packages/glibc/glibc-initial_2.5.bb2
-rw-r--r--packages/glibc/glibc_2.2.5.bb2
-rw-r--r--packages/glibc/glibc_2.3.2+cvs20040726.bb2
-rw-r--r--packages/glibc/glibc_2.3.2.bb2
-rw-r--r--packages/glibc/glibc_2.3.3+cvs20041128.bb2
-rw-r--r--packages/glibc/glibc_2.3.3+cvs20050221.bb2
-rw-r--r--packages/glibc/glibc_2.3.3+cvs20050420.bb2
-rw-r--r--packages/glibc/glibc_2.3.3.bb2
-rw-r--r--packages/glibc/glibc_2.3.5+cvs20050627.bb2
-rw-r--r--packages/glibc/glibc_cvs.bb2
-rw-r--r--packages/gstreamer/gst-plugins-bad_0.10.3.bb5
-rw-r--r--packages/gstreamer/gst-plugins-bad_0.10.6.bb (renamed from packages/gstreamer/gst-plugins-bad_0.10.5.bb)2
-rw-r--r--packages/gstreamer/gst-plugins-base_0.10.12.bb12
-rw-r--r--packages/gstreamer/gst-plugins-base_0.10.14.bb12
-rw-r--r--packages/gstreamer/gst-plugins-good_0.10.6.bb5
-rw-r--r--packages/gstreamer/gst-plugins-good_0.10.7.bb (renamed from packages/gstreamer/gst-plugins-good_0.10.5.bb)1
-rw-r--r--packages/gstreamer/gst-plugins-ugly_0.10.6.bb9
-rw-r--r--packages/gstreamer/gst-plugins-ugly_0.10.7.bb10
-rw-r--r--packages/gstreamer/gst-plugins.inc3
-rw-r--r--packages/gstreamer/gstreamer_0.10.12.bb3
-rw-r--r--packages/gstreamer/gstreamer_0.10.14.bb3
-rw-r--r--packages/images/liveramdisk-image.bb7
-rw-r--r--packages/initrdscripts/files/30-bootmenu.sh10
-rw-r--r--packages/initrdscripts/initramfs-jffs2/jffs2boot.sh1
-rw-r--r--packages/initrdscripts/initramfs-jffs2_0.1.bb3
-rw-r--r--packages/initrdscripts/initramfs-module-bootmenu_1.0.bb4
-rw-r--r--packages/keymaps/files/tosa/keymap-2.6.map350
-rw-r--r--packages/keymaps/keymaps_1.0.bb2
-rw-r--r--packages/klibc/files/fstype-sane-and-vfat-jffs2.patch68
-rw-r--r--packages/klibc/files/losetup.patch571
-rw-r--r--packages/klibc/files/modprobe.patch1985
-rw-r--r--packages/klibc/klibc-common.inc2
-rw-r--r--packages/klibc/klibc-utils-fstype-static_1.1.1.bb14
-rw-r--r--packages/klibc/klibc-utils-static_1.5.bb10
-rw-r--r--packages/klibc/klibc.inc11
-rw-r--r--packages/klibc/klibc_1.5.bb2
-rw-r--r--packages/less/less_382.bb22
-rw-r--r--packages/less/less_418.bb (renamed from packages/less/less_406.bb)2
-rw-r--r--packages/libgee/.mtn2git_empty0
-rw-r--r--packages/libgee/files/.mtn2git_empty0
-rw-r--r--packages/libgee/files/no-tests.patch12
-rw-r--r--packages/libgee/libgee_0.1.2.bb12
-rw-r--r--packages/linux/gumstix-linux.inc13
-rw-r--r--packages/linux/linux-handhelds-2.6-2.6.21/keep-initramfs.patch11
-rw-r--r--packages/linux/linux-handhelds-2.6.inc4
-rw-r--r--packages/linux/linux-handhelds-2.6_2.6.21-hh20.bb5
-rw-r--r--packages/linux/linux-rp-2.6.24/defconfig-tosa1728
-rw-r--r--packages/linux/linux-rp-2.6.24/htcuni.patch299
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/.mtn2git_empty0
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch201
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch260
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch243
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch907
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch249
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch653
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch81
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch608
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch1128
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch431
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch891
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch593
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch61
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch38
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch32
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch44
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch280
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch225
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch128
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch257
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch121
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch746
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch498
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch238
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch434
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch134
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch59
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch72
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch163
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch1083
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch383
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch492
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch490
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch329
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch122
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch35
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch41
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch57
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch446
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch108
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch593
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch26
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch153
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch26
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch416
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch66
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch412
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch225
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch373
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch99
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch86
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch400
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch56
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch28
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch30
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch126
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch70
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch27
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch46
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch623
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch342
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch78
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch84
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch27
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch49
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch26
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch225
-rw-r--r--packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch239
-rw-r--r--packages/linux/linux-rp_2.6.24.bb99
-rw-r--r--packages/linux/linux.inc1
-rw-r--r--packages/linux/linux_2.6.24.bb9
-rw-r--r--packages/meta/cross-linkage_1.0.bb10
-rw-r--r--packages/meta/staging-linkage_1.0.bb2
-rw-r--r--packages/ncdu/.mtn2git_empty0
-rw-r--r--packages/ncdu/ncdu_1.3.bb6
-rw-r--r--packages/ncurses/ncurses.inc35
-rw-r--r--packages/ncurses/ncurses_5.3.bb11
-rw-r--r--packages/ncurses/ncurses_5.4.bb4
-rw-r--r--packages/openttd/openttd_0.4.0.1.bb33
-rw-r--r--packages/python/python-2.5-manifest.inc12
-rw-r--r--packages/python/python-gsmd_svn.bb4
-rw-r--r--packages/python/python-pycairo_1.4.0.bb5
-rw-r--r--packages/python/python-pygtk/nodocs.patch13
-rw-r--r--packages/python/python-pygtk_2.10.4.bb3
-rw-r--r--packages/python/python-pyiw_0.3.3.bb15
-rw-r--r--packages/python/python_2.5.2.bb7
-rw-r--r--packages/tasks/task-python-everything.bb10
-rw-r--r--packages/wireless-tools/wireless-tools.inc18
-rw-r--r--packages/wireless-tools/wireless-tools_28+29pre10.bb14
-rw-r--r--packages/wireless-tools/wireless-tools_28+29pre21.bb16
-rw-r--r--packages/wireless-tools/wireless-tools_28.bb14
156 files changed, 23919 insertions, 607 deletions
diff --git a/packages/bluez/bluez-cups-backend_3.28.bb b/packages/bluez/bluez-cups-backend_3.28.bb
new file mode 100644
index 0000000000..40e099642a
--- /dev/null
+++ b/packages/bluez/bluez-cups-backend_3.28.bb
@@ -0,0 +1,27 @@
+require bluez-utils3.inc
+
+PR = "r1"
+
+DEPENDS += "cups"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --enable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+
+FILES_${PN} = "${libdir}/cups/backend/bluetooth"
+RDEPENDS_${PN} = "cups"
diff --git a/packages/bluez/bluez-gnome_0.24.bb b/packages/bluez/bluez-gnome_0.24.bb
new file mode 100644
index 0000000000..e3aaeafeb3
--- /dev/null
+++ b/packages/bluez/bluez-gnome_0.24.bb
@@ -0,0 +1,14 @@
+DESCRIPTION = "Bluetooth configuration applet"
+LICENSE = "GPL+LGPL"
+
+PR = "r1"
+
+DEPENDS = "dbus-glib gconf libnotify gtk+"
+RRECOMMENDS = "gnome-icon-theme"
+
+SRC_URI = "http://bluez.sourceforge.net/download/${P}.tar.gz"
+
+inherit autotools pkgconfig gconf
+
+FILES_${PN} += "${datadir}/gconf"
+
diff --git a/packages/bluez/bluez-gstreamer-plugin_3.28.bb b/packages/bluez/bluez-gstreamer-plugin_3.28.bb
new file mode 100644
index 0000000000..53b7eb86f2
--- /dev/null
+++ b/packages/bluez/bluez-gstreamer-plugin_3.28.bb
@@ -0,0 +1,27 @@
+require bluez-utils3.inc
+
+PR = "r1"
+
+DEPENDS += "gstreamer gst-plugins-base "
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --enable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --enable-gstreamer \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+
+FILES_${PN} = "${libdir}/gstreamer-0.10/libgstbluetooth.so"
diff --git a/packages/bluez/bluez-libs_3.28.bb b/packages/bluez/bluez-libs_3.28.bb
new file mode 100644
index 0000000000..eb515b4aba
--- /dev/null
+++ b/packages/bluez/bluez-libs_3.28.bb
@@ -0,0 +1,4 @@
+require bluez-libs.inc
+
+PR = "r1"
+
diff --git a/packages/dbench/dbench/.mtn2git_empty b/packages/bluez/bluez-utils-3.28/.mtn2git_empty
index e69de29bb2..e69de29bb2 100644
--- a/packages/dbench/dbench/.mtn2git_empty
+++ b/packages/bluez/bluez-utils-3.28/.mtn2git_empty
diff --git a/packages/bluez/bluez-utils-3.28/hciattach-ti-bts.patch b/packages/bluez/bluez-utils-3.28/hciattach-ti-bts.patch
new file mode 100644
index 0000000000..1b208f7979
--- /dev/null
+++ b/packages/bluez/bluez-utils-3.28/hciattach-ti-bts.patch
@@ -0,0 +1,477 @@
+--- bluez-utils-3.1/tools/hciattach.c.orig 2006-07-23 14:02:14.000000000 +0200
++++ bluez-utils-3.1/tools/hciattach.c 2006-07-23 14:06:29.000000000 +0200
+@@ -60,6 +60,8 @@
+ #define HCI_UART_3WIRE 2
+ #define HCI_UART_H4DS 3
+
++#include "ti_bts.h"
++
+ struct uart_t {
+ char *type;
+ int m_id;
+@@ -70,6 +72,7 @@
+ int flags;
+ char *bdaddr;
+ int (*init) (int fd, struct uart_t *u, struct termios *ti);
++ char *bts; /* bluetooth script */
+ };
+
+ #define FLOW_CTL 0x0001
+@@ -279,6 +282,114 @@
+ return 0;
+ }
+
++static int brf6150(int fd, struct uart_t *u, struct termios *ti)
++{
++ bts_t *bfp;
++ int i;
++ unsigned long vers;
++ unsigned char actionbuf[256];
++ unsigned char resp[128]; /* Response */
++ unsigned long count;
++ unsigned short atype;
++
++ if (u->bts == NULL) /* no script, ignore */
++ return 0;
++
++ bfp = bts_load_script( u->bts, &vers );
++ if (bfp == NULL)
++ return -1;
++
++ fprintf( stderr, "Loading BTS script version %lu\n", vers );
++
++ while ((count = bts_next_action( bfp, actionbuf,
++ sizeof actionbuf - 1, &atype )) != 0) {
++ if (atype == ACTION_REMARKS) {
++ if (actionbuf[0] != 0)
++ fprintf( stderr, "%s\n", actionbuf );
++ }
++ else if (atype == ACTION_SEND_COMMAND) {
++#if 0
++ fprintf( stderr, "ACTION_SEND_COMMAND: ", (int)atype );
++ for (i=0; i<count; i++) {
++ fprintf( stderr, "0x%02x ", actionbuf[i] );
++ }
++ fprintf( stderr, "\n" );
++#endif
++ int n;
++ n = write(fd, actionbuf, count);
++ if (n < 0 || n < count) {
++ perror("Failed to write TI action command");
++ return -1;
++ }
++ }
++ else if (atype == ACTION_WAIT_EVENT) {
++ action_wait_t *wait = (action_wait_t *)actionbuf;
++#if 0
++ fprintf( stderr, "ACTION_WAIT_EVENT: %u msec, %u size, data = ", wait->msec, wait->size );
++ for (i=0; i<wait->size; i++) {
++ fprintf( stderr, "0x%02x ", wait->data[i] );
++ }
++ fprintf( stderr, "\n" );
++#endif
++ usleep(wait->msec); /* seems they give usec, not msec */
++ /* Read reply. */
++ if ((count = read_hci_event(fd, resp, sizeof resp)) < 0) {
++ perror("Failed to read TI command response");
++ return -1;
++ }
++ if (count < wait->size) {
++ fprintf( stderr, "TI command response is short.");
++ }
++ for (i=0; i<wait->size; i++) {
++ if (i == 3) continue; /* ignore */
++ if (resp[i] != wait->data[i]) {
++ fprintf( stderr, "TI command response does not match expected result.\n" );
++ }
++ }
++ }
++ else if (atype == ACTION_SERIAL_PORT_PARAMETERS) {
++ action_serial_t *sercmd = (action_serial_t *)actionbuf;
++
++ /* Set actual baudrate */
++ fprintf( stderr,
++ "BTS changing baud rate to %u, flow control to %u\n",
++ sercmd->baud, sercmd->flow_control );
++
++ tcflush(fd, TCIOFLUSH);
++
++ if (sercmd->flow_control)
++ ti->c_cflag |= CRTSCTS;
++ else
++ ti->c_cflag &= ~CRTSCTS;
++ if (tcsetattr(fd, TCSANOW, ti) < 0) {
++ perror("Can't set port settings");
++ return -1;
++ }
++
++ u->speed = sercmd->baud;
++
++ tcflush(fd, TCIOFLUSH);
++ if (set_speed(fd, ti, sercmd->baud) < 0) {
++ perror("Can't set baud rate");
++ return -1;
++ }
++ }
++ else if (atype == ACTION_DELAY) {
++ action_delay_t *delay = (action_delay_t *)actionbuf;
++ usleep(delay->msec); /* seems they give usec, not msec */
++ }
++ else {
++ fprintf( stderr, "BTS action type = %d: ", (int)atype );
++ for (i=0; i<count; i++) {
++ fprintf( stderr, "0x%02x ", actionbuf[i] );
++ }
++ fprintf( stderr, "\n" );
++ }
++ }
++ bts_unload_script( bfp );
++ return 0;
++}
++
+ static int texas(int fd, struct uart_t *u, struct termios *ti)
+ {
+ struct timespec tm = {0, 50000};
+@@ -328,6 +439,17 @@
+ /* Print LMP subversion */
+ fprintf(stderr, "Texas module LMP sub-version : 0x%02x%02x\n", resp[14] & 0xFF, resp[13] & 0xFF);
+
++ if ((resp[14] >> 2) == 3) {
++ /* BRF6150 */
++ int err;
++
++ nanosleep(&tm, NULL);
++ if ((err = brf6150(fd, u, ti)) != 0) {
++ fprintf(stderr, "Texas module script failed (err=%d)\n", err);
++ return -1;
++ }
++ }
++
+ nanosleep(&tm, NULL);
+ return 0;
+ }
+@@ -1204,7 +1326,7 @@
+ {
+ printf("hciattach - HCI UART driver initialization utility\n");
+ printf("Usage:\n");
+- printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");
++ printf("\thciattach [-n] [-p] [-b] [-t timeout] [-s initial_speed] [-S bts-script] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");
+ printf("\thciattach -l\n");
+ }
+
+@@ -1219,11 +1341,12 @@
+ struct sigaction sa;
+ struct pollfd p;
+ char dev[PATH_MAX];
++ char *bts = NULL;
+
+ detach = 1;
+ printpid = 0;
+
+- while ((opt=getopt(argc, argv, "bnpt:s:l")) != EOF) {
++ while ((opt=getopt(argc, argv, "bnpt:s:S:l")) != EOF) {
+ switch(opt) {
+ case 'b':
+ send_break = 1;
+@@ -1245,6 +1368,10 @@
+ init_speed = atoi(optarg);
+ break;
+
++ case 'S':
++ bts = optarg;
++ break;
++
+ case 'l':
+ for (i = 0; uart[i].type; i++) {
+ printf("%-10s0x%04x,0x%04x\n", uart[i].type,
+@@ -1320,6 +1447,8 @@
+ if (init_speed)
+ u->init_speed = init_speed;
+
++ u->bts = bts;
++
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_flags = SA_NOCLDSTOP;
+ sa.sa_handler = sig_alarm;
+--- bluez-utils-3.1/tools/ti_bts.h.orig 2006-07-23 14:07:26.000000000 +0200
++++ bluez-utils-3.1/tools/ti_bts.h 2006-07-23 14:07:46.000000000 +0200
+@@ -0,0 +1,116 @@
++/*
++ * Copyright (c) 2005 Texas Instruments, Inc.
++ * Ported by SDG Systems, LLC
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation;
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
++ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
++ * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
++ * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
++ * SOFTWARE IS DISCLAIMED.
++ *
++ */
++
++#ifndef BT_SCRIPT_H
++#define BT_SCRIPT_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/*
++ * Define the interface of Bluetooth Script
++ */
++
++typedef void bts_t;
++
++
++#define ACTION_SEND_COMMAND 1 /* Send out raw data (as is) */
++#define ACTION_WAIT_EVENT 2 /* Wait for data */
++#define ACTION_SERIAL_PORT_PARAMETERS 3
++#define ACTION_DELAY 4
++#define ACTION_RUN_SCRIPT 5
++#define ACTION_REMARKS 6
++
++/*
++ * Structure for ACTION_SEND_COMMAND
++ */
++typedef struct tagCActionCommand
++{
++ unsigned char data[1]; /* Data to send */
++} action_command_t;
++
++/*
++ * Structure for ACTION_WAIT_EVENT
++ */
++typedef struct tagCActionWaitEvent
++{
++ unsigned long msec; /* in milliseconds */
++ unsigned long size;
++ unsigned char data[1]; /* Data to wait for */
++} action_wait_t;
++
++
++/*
++ * Structure for ACTION_SERIAL_PORT_PARAMETERS
++ */
++typedef struct tagCActionSerialPortParameters
++{
++ unsigned long baud;
++ unsigned long flow_control;
++} action_serial_t;
++
++/* Flow Control Type */
++#define FCT_NONE 0
++#define FCT_HARDWARE 1
++
++#define DONT_CHANGE 0xFFFFFFFF /* For both baud rate and flow control */
++
++
++/*
++ * Structure for ACTION_DELAY
++ */
++typedef struct tagCActionDelay
++{
++ unsigned long msec; /* in milliseconds */
++} action_delay_t;
++
++/*
++ * Structure for ACTION_RUN_SCRIPT
++ */
++typedef struct tagCActionRunScript
++{
++ char filename[1];
++} action_run_t;
++
++/*
++ * Structure for ACTION_REMARKS
++ */
++typedef struct tagCActionRemarks
++{
++ char m_szRemarks[1];
++} action_remarks_t;
++
++
++const char *cis_create_filename(const unsigned char* cmdparms);
++bts_t * bts_load_script(const char* fname, unsigned long* version);
++unsigned long bts_next_action(const bts_t* bts_fp, unsigned char* action_buf,
++ unsigned long nMaxSize, unsigned short* ptype);
++void bts_unload_script(bts_t* bts_fp);
++
++#ifdef __cplusplus
++};
++#endif
++
++#endif /* BT_SCRIPT_H */
++
+--- bluez-utils-3.1/tools/ti_bts.c.orig 2006-07-23 14:07:28.000000000 +0200
++++ bluez-utils-3.1/tools/ti_bts.c 2006-07-23 14:07:46.000000000 +0200
+@@ -0,0 +1,149 @@
++/*
++ * Copyright (c) 2005 Texas Instruments, Inc.
++ * Ported by SDG Systems, LLC
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation;
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
++ * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
++ * CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
++ * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
++ * SOFTWARE IS DISCLAIMED.
++ *
++ */
++
++
++#include <stdio.h>
++#include <stdlib.h>
++#include "ti_bts.h"
++
++#ifndef MAKEWORD
++#define MAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) | ((unsigned short)((unsigned char)(b))) << 8))
++#endif
++
++#define TI_MANUFACTURER_ID 13
++
++/*
++ * Common Init Script specific
++ */
++const char *
++cis_create_filename(const unsigned char* cmdparms)
++{
++ static char bts_file[50];
++
++ /* Check for TI's id */
++ unsigned short manfid = MAKEWORD(cmdparms[8], cmdparms[9]);
++
++ if (TI_MANUFACTURER_ID == manfid) {
++ unsigned short version = MAKEWORD(cmdparms[10], cmdparms[11]);
++
++ unsigned short chip = (version & 0x7C00) >> 10;
++ unsigned short min_ver = (version & 0x007F);
++ unsigned short maj_ver = (version & 0x0380) >> 7;
++
++ if (0 != (version & 0x8000)) {
++ maj_ver |= 0x0008;
++ }
++
++ sprintf( bts_file, "TIInit_%d.%d.%d.bts",
++ (int)chip, (int)maj_ver, (int)min_ver);
++
++ return &bts_file[0];
++ }
++ return NULL;
++}
++
++typedef struct tagCHeader
++{
++ unsigned long magic;
++ unsigned long version;
++ unsigned char future[24];
++} cheader_t;
++
++
++/* The value 0x42535442 stands for (in ASCII) BTSB */
++/* which is Bluetooth Script Binary */
++#define FILE_HEADER_MAGIC 0x42535442
++
++
++bts_t *
++bts_load_script(const char* fname, unsigned long* version)
++{
++ bts_t* bts = NULL;
++ FILE* fp = fopen(fname, "rb");
++
++ if (NULL != fp) {
++ /* Read header */
++ cheader_t header;
++
++ /* Read header */
++ if (1 == fread(&header, sizeof(header), 1, fp)) {
++ /* Check magic number for correctness */
++ if (header.magic == FILE_HEADER_MAGIC) {
++ /* If user wants the version number */
++ if (NULL != version) {
++ *version = header.version;
++ }
++ bts = (bts_t*)fp;
++ }
++ }
++ /* If failed reading the file, close it */
++ if (NULL == bts) {
++ fclose(fp);
++ }
++ }
++ return bts;
++}
++
++unsigned long
++bts_next_action(const bts_t* bts_fp, unsigned char* action_buf,
++ unsigned long nMaxSize, unsigned short* ptype)
++{
++ unsigned long bytes = 0;
++ FILE* fp = (FILE*)bts_fp;
++ unsigned char action_hdr[4];
++
++ if (bts_fp == NULL)
++ return 0;
++
++ /* Each Action has the following: */
++ /* UINT16 type of this action */
++ /* UINT16 size of rest */
++ /* BYTE[] action buffer (for HCI, includes the type byte e.g. 1 for hci command) */
++
++ if (1 == fread(&action_hdr[0], sizeof(action_hdr), 1, fp)) {
++ unsigned short type = *(unsigned short*)&action_hdr[0];
++ unsigned short size = *(unsigned short*)&action_hdr[2];
++
++ if (size <= nMaxSize) {
++ int nread = fread(action_buf, sizeof(action_buf[0]), size, fp);
++
++ if (nread == size) {
++ *ptype = type;
++ bytes = (unsigned long)size;
++ }
++ }
++ }
++
++ return bytes;
++}
++
++void
++bts_unload_script(bts_t* bts_fp)
++{
++ FILE* fp = (FILE*)bts_fp;
++
++ if (NULL != fp) {
++ fclose(fp);
++ }
++}
++
+--- bluez-utils-3.1/tools/Makefile.am.orig 2006-07-23 14:06:59.000000000 +0200
++++ bluez-utils-3.1/tools/Makefile.am 2006-07-23 14:07:18.000000000 +0200
+@@ -45,7 +45,7 @@
+
+ noinst_PROGRAMS = hcisecfilter ppporc
+
+-hciattach_SOURCES = hciattach.c hciattach_st.c
++hciattach_SOURCES = hciattach.c hciattach_st.c ti_bts.h ti_bts.c
+ hciattach_LDADD = @BLUEZ_LIBS@
+
+ hciconfig_SOURCES = hciconfig.c csr.h csr.c
diff --git a/packages/bluez/bluez-utils-alsa_3.28.bb b/packages/bluez/bluez-utils-alsa_3.28.bb
new file mode 100644
index 0000000000..a1e3e85818
--- /dev/null
+++ b/packages/bluez/bluez-utils-alsa_3.28.bb
@@ -0,0 +1,25 @@
+require bluez-utils3.inc
+
+PR = "r1"
+
+DEPENDS += "alsa-lib"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --disable-hid2hci \
+ --enable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+FILES_${PN} = "${libdir}/alsa-lib/libasound*"
diff --git a/packages/bluez/bluez-utils_3.28.bb b/packages/bluez/bluez-utils_3.28.bb
new file mode 100644
index 0000000000..37365f67fc
--- /dev/null
+++ b/packages/bluez/bluez-utils_3.28.bb
@@ -0,0 +1,30 @@
+require bluez-utils3.inc
+PR = "r2"
+
+# see bluez-utils3.inc for the explanation of these option
+EXTRA_OECONF = " \
+ --enable-bccmd \
+ --enable-hid2hci \
+ --disable-alsa \
+ --disable-cups \
+ --enable-glib \
+ --disable-sdpd \
+ --enable-network \
+ --enable-serial \
+ --enable-input \
+ --enable-audio \
+ --enable-echo \
+ --enable-configfile \
+ --enable-initscripts \
+ --enable-test \
+ "
+
+CONFFILES_${PN} = " \
+ ${sysconfdir}/bluetooth/hcid.conf \
+ ${sysconfdir}/default/bluetooth \
+ "
+
+CONFFILES_${PN}-compat = " \
+ ${sysconfdir}/bluetooth/rfcomm.conf \
+ "
+
diff --git a/packages/cmake/cmake-native_2.4.8.bb b/packages/cmake/cmake-native_2.4.8.bb
index fcfdda1c1a..1a56fa40e0 100644
--- a/packages/cmake/cmake-native_2.4.8.bb
+++ b/packages/cmake/cmake-native_2.4.8.bb
@@ -1,3 +1,13 @@
CMAKE_MAJOR_VERSION="2.4"
require cmake.inc
inherit native
+
+do_stage() {
+ for i in cpack ctest ccmake cmake; do
+ install -m 0755 bin/$i ${STAGING_BINDIR_NATIVE}
+ done
+}
+
+do_install() {
+ :
+}
diff --git a/packages/cmake/cmake.inc b/packages/cmake/cmake.inc
index 83475bb5eb..5190b6233f 100644
--- a/packages/cmake/cmake.inc
+++ b/packages/cmake/cmake.inc
@@ -1,4 +1,3 @@
-# cppunit OE build file
# Copyright (C) 2005, Koninklijke Philips Electronics NV. All Rights Reserved
# Released under the MIT license (see packages/COPYING)
diff --git a/packages/dbench/dbench_3.04.bb b/packages/dbench/dbench_4.0.bb
index 1f6b703ba8..aade4170ba 100644
--- a/packages/dbench/dbench_3.04.bb
+++ b/packages/dbench/dbench_4.0.bb
@@ -3,10 +3,12 @@ DESCRIPTION_dbench = "Filesystem load benchmark"
DESCRIPTION_tbench = "TCP load benchmark"
HOMEPAGE = "http://samba.org/ftp/tridge/dbench/"
LICENSE = "GPL"
-PR = "r1"
+PR = "r0"
-SRC_URI = "http://samba.org/ftp/tridge/dbench/dbench-${PV}.tar.gz \
- file://destdir.patch;patch=1"
+SRC_URI = "\
+ http://samba.org/ftp/tridge/dbench/dbench-${PV}.tar.gz \
+ file://destdir.patch;patch=1 \
+ file://makefile.patch;patch=1"
inherit autotools
diff --git a/packages/dbench/files/.mtn2git_empty b/packages/dbench/files/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/dbench/files/.mtn2git_empty
diff --git a/packages/dbench/dbench/destdir.patch b/packages/dbench/files/destdir.patch
index 9fe1508f97..9fe1508f97 100644
--- a/packages/dbench/dbench/destdir.patch
+++ b/packages/dbench/files/destdir.patch
diff --git a/packages/dbench/files/makefile.patch b/packages/dbench/files/makefile.patch
new file mode 100644
index 0000000000..4f57085e41
--- /dev/null
+++ b/packages/dbench/files/makefile.patch
@@ -0,0 +1,13 @@
+Index: dbench-4.0/Makefile.in
+===================================================================
+--- dbench-4.0.orig/Makefile.in
++++ dbench-4.0/Makefile.in
+@@ -35,7 +35,7 @@ install: all
+ ${INSTALLCMD} -d $(DESTDIR)$(bindir) $(DESTDIR)$(datadir) $(DESTDIR)$(mandir)
+ ${INSTALLCMD} dbench tbench tbench_srv $(DESTDIR)$(bindir)
+ ${INSTALLCMD} client.txt $(DESTDIR)$(datadir)
+- ${INSTALLCMD} -m644 dbench.1 $(DESTDIR)$(mandir)
++ ${INSTALLCMD} -m 644 dbench.1 $(DESTDIR)$(mandir)
+ ln -sf dbench.1 $(DESTDIR)$(mandir)/tbench.1
+ ln -sf dbench.1 $(DESTDIR)$(mandir)/tbench_srv.1
+
diff --git a/packages/dbus/dbus-native_1.0.3.bb b/packages/dbus/dbus-native_1.0.3.bb
index 0149ab374f..195557b35b 100644
--- a/packages/dbus/dbus-native_1.0.3.bb
+++ b/packages/dbus/dbus-native_1.0.3.bb
@@ -8,7 +8,7 @@ DEPENDS = "glib-2.0-native libxml2-native expat-native"
FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/dbus-${PV}"
SRC_URI = "\
- http://freedesktop.org/software/dbus/releases/dbus-${PV}.tar.gz \
+ http://freedesktop.org/software/dbus/releases/dbus/dbus-${PV}.tar.gz \
file://cross.patch;patch=1 \
file://tmpdir.patch;patch=1 \
file://dbus-1.init \
diff --git a/packages/glibc/eglibc-initial_svn.bb b/packages/glibc/eglibc-initial_svn.bb
index 298c775152..cbe4878529 100644
--- a/packages/glibc/eglibc-initial_svn.bb
+++ b/packages/glibc/eglibc-initial_svn.bb
@@ -14,7 +14,7 @@ do_configure () {
find ${S} -name "configure" | xargs touch
CC="${BUILD_CC}" CPP="${BUILD_CPP}" LD="${BUILD_LD}" ${S}/configure --host=${TARGET_SYS} --build=${BUILD_SYS} \
--without-cvs --disable-sanity-checks \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--enable-hacker-mode
if grep -q GLIBC_2.3 ${S}/ChangeLog; then
# glibc-2.3.x passes cross options to $(CC) when generating errlist-compat.c, which fails without a real cross-compiler.
diff --git a/packages/glibc/glibc-initial_2.5.bb b/packages/glibc/glibc-initial_2.5.bb
index 1e41d218d2..44f5775fd7 100644
--- a/packages/glibc/glibc-initial_2.5.bb
+++ b/packages/glibc/glibc-initial_2.5.bb
@@ -7,7 +7,7 @@ do_configure () {
unset CFLAGS
CC="${BUILD_CC}" CPP="${BUILD_CPP}" LD="${BUILD_LD}" ${S}/configure --host=${TARGET_SYS} --build=${BUILD_SYS} \
--without-cvs --disable-sanity-checks \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--enable-hacker-mode
if grep -q GLIBC_2.5 ${S}/ChangeLog; then
# glibc-2.3.x passes cross options to $(CC) when generating errlist-compat.c, which fails without a real cross-compiler.
diff --git a/packages/glibc/glibc_2.2.5.bb b/packages/glibc/glibc_2.2.5.bb
index 2a3bfd26df..b3a779c6ef 100644
--- a/packages/glibc/glibc_2.2.5.bb
+++ b/packages/glibc/glibc_2.2.5.bb
@@ -113,7 +113,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
${GLIBC_EXTRA_OECONF}"
EXTRA_OECONF += "${@get_glibc_fpu_setting(bb, d)}"
diff --git a/packages/glibc/glibc_2.3.2+cvs20040726.bb b/packages/glibc/glibc_2.3.2+cvs20040726.bb
index c44bf7dd15..21568e24b3 100644
--- a/packages/glibc/glibc_2.3.2+cvs20040726.bb
+++ b/packages/glibc/glibc_2.3.2+cvs20040726.bb
@@ -35,7 +35,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
${GLIBC_EXTRA_OECONF}"
do_configure () {
diff --git a/packages/glibc/glibc_2.3.2.bb b/packages/glibc/glibc_2.3.2.bb
index 9290c9b831..e782ecfa82 100644
--- a/packages/glibc/glibc_2.3.2.bb
+++ b/packages/glibc/glibc_2.3.2.bb
@@ -110,7 +110,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
${GLIBC_EXTRA_OECONF}"
EXTRA_OECONF += "${@get_glibc_fpu_setting(bb, d)}"
diff --git a/packages/glibc/glibc_2.3.3+cvs20041128.bb b/packages/glibc/glibc_2.3.3+cvs20041128.bb
index 829ef8f64e..0af357a883 100644
--- a/packages/glibc/glibc_2.3.3+cvs20041128.bb
+++ b/packages/glibc/glibc_2.3.3+cvs20041128.bb
@@ -54,7 +54,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--without-selinux \
${GLIBC_EXTRA_OECONF}"
diff --git a/packages/glibc/glibc_2.3.3+cvs20050221.bb b/packages/glibc/glibc_2.3.3+cvs20050221.bb
index b94025881e..f6a7d43812 100644
--- a/packages/glibc/glibc_2.3.3+cvs20050221.bb
+++ b/packages/glibc/glibc_2.3.3+cvs20050221.bb
@@ -39,7 +39,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--without-selinux \
${GLIBC_EXTRA_OECONF}"
diff --git a/packages/glibc/glibc_2.3.3+cvs20050420.bb b/packages/glibc/glibc_2.3.3+cvs20050420.bb
index 0a3759b6d2..2894ce835a 100644
--- a/packages/glibc/glibc_2.3.3+cvs20050420.bb
+++ b/packages/glibc/glibc_2.3.3+cvs20050420.bb
@@ -40,7 +40,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--without-selinux \
${GLIBC_EXTRA_OECONF}"
diff --git a/packages/glibc/glibc_2.3.3.bb b/packages/glibc/glibc_2.3.3.bb
index 46fc230d29..7f2d67e87a 100644
--- a/packages/glibc/glibc_2.3.3.bb
+++ b/packages/glibc/glibc_2.3.3.bb
@@ -55,7 +55,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
${GLIBC_EXTRA_OECONF}"
EXTRA_OECONF += "${@get_glibc_fpu_setting(bb, d)}"
diff --git a/packages/glibc/glibc_2.3.5+cvs20050627.bb b/packages/glibc/glibc_2.3.5+cvs20050627.bb
index 62cfd21cb9..c916b2ba05 100644
--- a/packages/glibc/glibc_2.3.5+cvs20050627.bb
+++ b/packages/glibc/glibc_2.3.5+cvs20050627.bb
@@ -70,7 +70,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR \
--without-selinux \
${GLIBC_EXTRA_OECONF}"
diff --git a/packages/glibc/glibc_cvs.bb b/packages/glibc/glibc_cvs.bb
index 9dbea14876..63fbba93e7 100644
--- a/packages/glibc/glibc_cvs.bb
+++ b/packages/glibc/glibc_cvs.bb
@@ -56,7 +56,7 @@ EXTRA_OECONF = "--enable-kernel=${OLDEST_KERNEL} \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-clocale=gnu \
--enable-add-ons=${GLIBC_ADDONS} \
- --with-headers=${CROSS_DIR}/${TARGET_SYS}/include \
+ --with-headers=${STAGING_INCDIR} \
--without-selinux \
${GLIBC_EXTRA_OECONF}"
diff --git a/packages/gstreamer/gst-plugins-bad_0.10.3.bb b/packages/gstreamer/gst-plugins-bad_0.10.3.bb
deleted file mode 100644
index 3e487314be..0000000000
--- a/packages/gstreamer/gst-plugins-bad_0.10.3.bb
+++ /dev/null
@@ -1,5 +0,0 @@
-require gst-plugins.inc
-
-DEPENDS += "gst-plugins-base directfb"
-SRC_URI += "file://cross-compile.patch;patch=1"
-PR = "r6"
diff --git a/packages/gstreamer/gst-plugins-bad_0.10.5.bb b/packages/gstreamer/gst-plugins-bad_0.10.6.bb
index ce61d10010..2a998589ac 100644
--- a/packages/gstreamer/gst-plugins-bad_0.10.5.bb
+++ b/packages/gstreamer/gst-plugins-bad_0.10.6.bb
@@ -8,5 +8,3 @@ do_compile_prepend() {
# work around missing files in upstream tarball (upstream bug #454078)
install -m 0644 ${WORKDIR}/vorbis*.h ${S}/ext/ivorbis/
}
-
-PR = "r1"
diff --git a/packages/gstreamer/gst-plugins-base_0.10.12.bb b/packages/gstreamer/gst-plugins-base_0.10.12.bb
deleted file mode 100644
index 33b189a0ff..0000000000
--- a/packages/gstreamer/gst-plugins-base_0.10.12.bb
+++ /dev/null
@@ -1,12 +0,0 @@
-require gst-plugins.inc
-
-PROVIDES += "gst-plugins"
-
-# gst-plugins-base only builds the alsa plugin
-# if alsa has been built and is present. You will
-# not get an error if this is not present, just
-# a missing alsa plugin
-DEPENDS += "alsa-lib"
-
-PR = "r2"
-
diff --git a/packages/gstreamer/gst-plugins-base_0.10.14.bb b/packages/gstreamer/gst-plugins-base_0.10.14.bb
deleted file mode 100644
index 33b189a0ff..0000000000
--- a/packages/gstreamer/gst-plugins-base_0.10.14.bb
+++ /dev/null
@@ -1,12 +0,0 @@
-require gst-plugins.inc
-
-PROVIDES += "gst-plugins"
-
-# gst-plugins-base only builds the alsa plugin
-# if alsa has been built and is present. You will
-# not get an error if this is not present, just
-# a missing alsa plugin
-DEPENDS += "alsa-lib"
-
-PR = "r2"
-
diff --git a/packages/gstreamer/gst-plugins-good_0.10.6.bb b/packages/gstreamer/gst-plugins-good_0.10.6.bb
deleted file mode 100644
index e009145ead..0000000000
--- a/packages/gstreamer/gst-plugins-good_0.10.6.bb
+++ /dev/null
@@ -1,5 +0,0 @@
-require gst-plugins.inc
-
-EXTRA_OECONF += "--with-check=no"
-DEPENDS += "gst-plugins-base"
-PR = "r3"
diff --git a/packages/gstreamer/gst-plugins-good_0.10.5.bb b/packages/gstreamer/gst-plugins-good_0.10.7.bb
index e009145ead..e84c4801f1 100644
--- a/packages/gstreamer/gst-plugins-good_0.10.5.bb
+++ b/packages/gstreamer/gst-plugins-good_0.10.7.bb
@@ -2,4 +2,3 @@ require gst-plugins.inc
EXTRA_OECONF += "--with-check=no"
DEPENDS += "gst-plugins-base"
-PR = "r3"
diff --git a/packages/gstreamer/gst-plugins-ugly_0.10.6.bb b/packages/gstreamer/gst-plugins-ugly_0.10.6.bb
deleted file mode 100644
index c88a4db990..0000000000
--- a/packages/gstreamer/gst-plugins-ugly_0.10.6.bb
+++ /dev/null
@@ -1,9 +0,0 @@
-require gst-plugins.inc
-
-DEPENDS += "gst-plugins-base mpeg2dec libsidplay"
-PR = "r3"
-
-SRC_URI += "file://cross-compile.patch;patch=1 \
- file://gstmad_16bit.patch;patch=1 \
- file://gstsid_autofoo_HACK.patch;patch=1"
-
diff --git a/packages/gstreamer/gst-plugins-ugly_0.10.7.bb b/packages/gstreamer/gst-plugins-ugly_0.10.7.bb
new file mode 100644
index 0000000000..fd008b065a
--- /dev/null
+++ b/packages/gstreamer/gst-plugins-ugly_0.10.7.bb
@@ -0,0 +1,10 @@
+require gst-plugins.inc
+PR = "r0"
+
+DEPENDS += "gst-plugins-base mpeg2dec libsidplay"
+
+SRC_URI += "\
+# file://cross-compile.patch;patch=1 \
+ file://gstmad_16bit.patch;patch=1 \
+ file://gstsid_autofoo_HACK.patch;patch=1 \
+"
diff --git a/packages/gstreamer/gst-plugins.inc b/packages/gstreamer/gst-plugins.inc
index 8e8fd0f1ca..66546d5f2b 100644
--- a/packages/gstreamer/gst-plugins.inc
+++ b/packages/gstreamer/gst-plugins.inc
@@ -24,3 +24,6 @@ python populate_packages_prepend () {
}
ALLOW_EMPTY = "1"
+
+FILES_${PN}-dbg += "${libdir}/gstreamer-${LIBV}/.debug"
+
diff --git a/packages/gstreamer/gstreamer_0.10.12.bb b/packages/gstreamer/gstreamer_0.10.12.bb
deleted file mode 100644
index 49d7f37053..0000000000
--- a/packages/gstreamer/gstreamer_0.10.12.bb
+++ /dev/null
@@ -1,3 +0,0 @@
-require gstreamer.inc
-
-PR = "r1" \ No newline at end of file
diff --git a/packages/gstreamer/gstreamer_0.10.14.bb b/packages/gstreamer/gstreamer_0.10.14.bb
deleted file mode 100644
index 9e9ae62cb1..0000000000
--- a/packages/gstreamer/gstreamer_0.10.14.bb
+++ /dev/null
@@ -1,3 +0,0 @@
-require gstreamer.inc
-
-PR = "r0"
diff --git a/packages/images/liveramdisk-image.bb b/packages/images/liveramdisk-image.bb
index b3c288ec31..5d2362353b 100644
--- a/packages/images/liveramdisk-image.bb
+++ b/packages/images/liveramdisk-image.bb
@@ -12,6 +12,11 @@ export IMAGE_BASENAME = "liveramdisk"
export IMAGE_LINGUAS = ""
# Install only ${IMAGE_INSTALL}, not even deps
-PACKAGE_INSTALL_NO_DEPS = "1"
+#PACKAGE_INSTALL_NO_DEPS = "1"
+
+# Remove any kernel-image that the kernel-module-* packages may have pulled in.
+PACKAGE_REMOVE = "kernel-image-* update-modules module-init-tools-depmod uclibc update-rc.d"
+ROOTFS_POSTPROCESS_COMMAND += "ipkg-cl ${IPKG_ARGS} -force-depends \
+ remove ${PACKAGE_REMOVE};"
inherit image
diff --git a/packages/initrdscripts/files/30-bootmenu.sh b/packages/initrdscripts/files/30-bootmenu.sh
index 3f3b8c7079..f5ecb8c828 100644
--- a/packages/initrdscripts/files/30-bootmenu.sh
+++ b/packages/initrdscripts/files/30-bootmenu.sh
@@ -15,6 +15,13 @@ if ! (echo " " | read -n1 foo) >/dev/null 2>&1; then
exit 1
fi
+if [ -z "$rootdelay" ]; then
+ echo "rootdelay parameter was not passed on kernel command line - assuming 2s delay"
+ echo "If you would like to avoid this delay, pass explicit rootdelay=0"
+ sleep 2
+ dev_setup
+fi
+
mkdir -p $MOUNTLOC
list=""
@@ -82,7 +89,8 @@ while read maj min nblk dev; do
get_partition_type
if [ "$fstype" != "ext2" -a "$fstype" != "ext3" -a "$fstype" != "vfat" -a "$fstype" != "jffs2" ]; then
-# continue
+ # Comment following line to show all available block devices regardless of FS (for debug purposes)
+ continue
true
fi
diff --git a/packages/initrdscripts/initramfs-jffs2/jffs2boot.sh b/packages/initrdscripts/initramfs-jffs2/jffs2boot.sh
index 18f4d93273..f81fc5226f 100644
--- a/packages/initrdscripts/initramfs-jffs2/jffs2boot.sh
+++ b/packages/initrdscripts/initramfs-jffs2/jffs2boot.sh
@@ -4,6 +4,7 @@ echo "Starting initrd boot..."
mkdir /proc
mount -t proc proc /proc
+modprobe -q mtdblock
modprobe mtdram total_size=25088 erase_size=256
sleep 1
diff --git a/packages/initrdscripts/initramfs-jffs2_0.1.bb b/packages/initrdscripts/initramfs-jffs2_0.1.bb
index f938b9d3b1..812e612126 100644
--- a/packages/initrdscripts/initramfs-jffs2_0.1.bb
+++ b/packages/initrdscripts/initramfs-jffs2_0.1.bb
@@ -1,5 +1,6 @@
SRC_URI = "file://jffs2boot.sh"
-PR = "r2"
+PR = "r3"
+RRECOMMENDS = "kernel-module-mtdblock kernel-module-mtdram"
do_install() {
install -m 0755 ${WORKDIR}/jffs2boot.sh ${D}/init
diff --git a/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb b/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb
index 02d696aa2e..6c01b5edc5 100644
--- a/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb
+++ b/packages/initrdscripts/initramfs-module-bootmenu_1.0.bb
@@ -1,7 +1,7 @@
SRC_URI = "file://30-bootmenu.sh"
-PR = "r12"
+PR = "r15"
DESCRIPTION = "An initramfs module with UI for selection of boot device."
-RDEPENDS = "klibc-utils-fstype-static initramfs-uniboot initramfs-module-block initramfs-module-loop initramfs-module-nfs"
+RDEPENDS = "klibc-utils-static-fstype initramfs-uniboot initramfs-module-block initramfs-module-loop initramfs-module-nfs"
# For VFAT mounting.
RRECOMMENDS = "kernel-module-nls-cp437 kernel-module-nls-iso8859-1"
diff --git a/packages/keymaps/files/tosa/keymap-2.6.map b/packages/keymaps/files/tosa/keymap-2.6.map
index b85d5616e5..f83e4bfe39 100644
--- a/packages/keymaps/files/tosa/keymap-2.6.map
+++ b/packages/keymaps/files/tosa/keymap-2.6.map
@@ -1,117 +1,297 @@
# Default kernel keymap. This uses 7 modifier combinations.
keymaps 0-2,4-5,8,12
-# Change the above line into
-# keymaps 0-2,4-6,8,12
-# in case you want the entries
-# altgr control keycode 83 = Boot
-# altgr control keycode 111 = Boot
-# below.
#
-keycode 1 =
-keycode 14 = BackSpace
- altgr keycode 14 = Delete
-keycode 15 = Tab
- altgr keycode 65 = Caps_Lock
-keycode 16 = q
- altgr keycode 16 = one
+keycode 1 = Escape Escape
+# alt keycode 1 = Meta_Escape
+#keycode 2 = one exclam
+# alt keycode 2 = Meta_one
+#keycode 3 = two at at
+# control keycode 3 = nul
+# shift control keycode 3 = nul
+# alt keycode 3 = Meta_two
+#keycode 4 = three numbersign
+# control keycode 4 = Escape
+# alt keycode 4 = Meta_three
+#keycode 5 = four dollar dollar
+# control keycode 5 = Control_backslash
+# alt keycode 5 = Meta_four
+#keycode 6 = five percent
+# control keycode 6 = Control_bracketright
+# alt keycode 6 = Meta_five
+#keycode 7 = six asciicircum
+# control keycode 7 = Control_asciicircum
+# alt keycode 7 = Meta_six
+#keycode 8 = seven ampersand braceleft
+# control keycode 8 = Control_underscore
+# alt keycode 8 = Meta_seven
+#keycode 9 = eight asterisk bracketleft
+# control keycode 9 = Delete
+# alt keycode 9 = Meta_eight
+#keycode 10 = nine parenleft bracketright
+# alt keycode 10 = Meta_nine
+#keycode 11 = zero parenright braceright
+# alt keycode 11 = Meta_zero
+#keycode 12 = minus underscore backslash
+# control keycode 12 = Control_underscore
+# shift control keycode 12 = Control_underscore
+# alt keycode 12 = Meta_minus
+#keycode 13 = equal plus
+# alt keycode 13 = Meta_equal
+keycode 14 = BackSpace BackSpace
+ altgr keycode 14 = Delete
+#keycode 14 = Delete Delete
+# control keycode 14 = BackSpace
+# alt keycode 14 = Meta_Delete
+keycode 15 = Tab Tab
+ altgr keycode 15 = Caps_Lock
+keycode 16 = q
+ altgr keycode 16 = one
keycode 17 = w
- altgr keycode 17 = two
+ altgr keycode 17 = two
keycode 18 = e
- altgr keycode 18 = three
-keycode 19 = r
- altgr keycode 19 = four
+ altgr keycode 18 = three
+# altgr keycode 18 = Hex_E
+keycode 19 = r
+ altgr keycode 19 = four
keycode 20 = t
- altgr keycode 20 = five
+ altgr keycode 20 = five
keycode 21 = y
- altgr keycode 21 = six
-keycode 22 = u
- altgr keycode 22 = seven
-keycode 23 = i
- altgr keycode 23 = eight
+ altgr keycode 21 = six
+keycode 22 = u
+ altgr keycode 22 = seven
+keycode 23 = i
+ altgr keycode 23 = eight
keycode 24 = o
- altgr keycode 24 = nine
+ altgr keycode 24 = nine
keycode 25 = p
- altgr keycode 25 = zero
-keycode 26 =
-keycode 27 =
+ altgr keycode 25 = zero
+#keycode 26 = bracketleft braceleft
+# control keycode 26 = Escape
+# alt keycode 26 = Meta_bracketleft
+#keycode 27 = bracketright braceright asciitilde
+# control keycode 27 = Control_bracketright
+# alt keycode 27 = Meta_bracketright
keycode 28 = Return
- altgr keycode 28 = greater
+ altgr keycode 28 = greater
+# alt keycode 28 = Meta_Control_m
keycode 29 = Control
keycode 30 = a
- altgr keycode 30 = exclam
+ altgr keycode 30 = exclam
+# altgr keycode 30 = Hex_A
keycode 31 = s
- altgr keycode 31 = at
+ altgr keycode 31 = at
keycode 32 = d
- altgr keycode 32 = numbersign
+ altgr keycode 32 = numbersign
+# altgr keycode 32 = Hex_D
keycode 33 = f
- altgr keycode 33 = dollar
+ altgr keycode 33 = dollar
+# altgr keycode 33 = Hex_F
keycode 34 = g
- altgr keycode 34 = percent
-keycode 35 = h
- altgr keycode 35 = underscore
-keycode 36 = j
- altgr keycode 36 = ampersand
-keycode 37 = k
- altgr keycode 37 = asterisk
-keycode 38 = l
- altgr keycode 38 = parenleft
-keycode 39 =
-keycode 40 = apostrophe
- altgr keycode 40 = asciitilde
- shift keycode 40 = quotedbl
-keycode 41 =
+ altgr keycode 34 = percent
+keycode 35 = h
+ altgr keycode 35 = underscore
+keycode 36 = j
+ altgr keycode 36 = ampersand
+keycode 37 = k
+ altgr keycode 37 = asterisk
+keycode 38 = l
+ altgr keycode 38 = parenleft
+#keycode 39 = semicolon colon
+# alt keycode 39 = Meta_semicolon
+keycode 40 = apostrophe quotedbl
+ altgr keycode 40 = asciitilde
+# control keycode 40 = Control_g
+# alt keycode 40 = Meta_apostrophe
+#keycode 41 = grave asciitilde
+# control keycode 41 = nul
+# alt keycode 41 = Meta_grave
keycode 42 = Shift
-keycode 43 =
+#keycode 43 = backslash bar
+# control keycode 43 = Control_backslash
+# alt keycode 43 = Meta_backslash
keycode 44 = z
+## alt keycode 44 =
keycode 45 = x
+ altgr keycode 45 = Control_x
keycode 46 = c
+ altgr keycode 46 = Control_c
+# altgr keycode 46 = Hex_C
keycode 47 = v
+ altgr keycode 47 = Control_v
keycode 48 = b
- altgr keycode 48 = minus
+ altgr keycode 48 = minus
+# altgr keycode 48 = Hex_B
keycode 49 = n
- altgr keycode 49 = plus
+ altgr keycode 49 = plus
keycode 50 = m
- altgr keycode 50 = equal
-keycode 51 = comma
- altgr keycode 51 = parenright
- shift keycode 51 = semicolon
-keycode 52 = period
- shift keycode 52 = colon
- altgr keycode 52 = less
-
-keycode 53 = slash
- shift keycode 53 = question
- altgr keycode 53 = Num_Lock
-
+ altgr keycode 50 = equal
+keycode 51 = comma semicolon
+ altgr keycode 51 = parenright
+#keycode 51 = comma less
+# alt keycode 51 = Meta_comma
+keycode 52 = period colon
+ control keycode 52 = Compose
+ altgr keycode 52 = less
+#keycode 52 = period greater
+# control keycode 52 = Compose
+# alt keycode 52 = Meta_period
+keycode 53 = slash question
+ altgr keycode 53 = Num_Lock
+# control keycode 53 = Delete
+# alt keycode 53 = Meta_slash
keycode 54 = Shift
-keycode 55 =
-keycode 56 = Alt
+#keycode 55 = KP_Multiply
+#keycode 56 = Alt
keycode 57 = space space
- control keycode 57 = nul
- altgr keycode 57 = bar
-keycode 59 = F9
-keycode 60 = F10
-keycode 61 = AltGr
-keycode 62 = Escape
-keycode 63 = space
-keycode 64 = Control
-keycode 65 = F15
-keycode 66 = F24
-keycode 67 = F12
-keycode 68 = F13
-keycode 79 = F15
-keycode 80 = F16
-keycode 82 = F17
-keycode 87 = Return
-keycode 88 = F11
-keycode 97 = Control
-keycode 99 = F12
+ altgr keycode 57 = bar
+# control keycode 57 = nul
+# alt keycode 57 = Meta_space
+#keycode 58 = Caps_Lock
+#keycode 59 = F1 F11 Console_13
+# control keycode 59 = F1
+# alt keycode 59 = Console_1
+# control alt keycode 59 = Console_1
+#keycode 60 = F2 F12 Console_14
+# control keycode 60 = F2
+# alt keycode 60 = Console_2
+# control alt keycode 60 = Console_2
+#keycode 61 = F3 F13 Console_15
+# control keycode 61 = F3
+# alt keycode 61 = Console_3
+# control alt keycode 61 = Console_3
+#keycode 62 = F4 F14 Console_16
+# control keycode 62 = F4
+# alt keycode 62 = Console_4
+# control alt keycode 62 = Console_4
+#keycode 63 = F5 F15 Console_17
+# control keycode 63 = F5
+# alt keycode 63 = Console_5
+# control alt keycode 63 = Console_5
+#keycode 64 = F6 F16 Console_18
+# control keycode 64 = F6
+# alt keycode 64 = Console_6
+# control alt keycode 64 = Console_6
+#keycode 65 = F7 F17 Console_19
+# control keycode 65 = F7
+# alt keycode 65 = Console_7
+# control alt keycode 65 = Console_7
+#keycode 66 = F8 F18 Console_20
+# control keycode 66 = F8
+# alt keycode 66 = Console_8
+# control alt keycode 66 = Console_8
+#keycode 67 = F9 F19 Console_21
+# control keycode 67 = F9
+# alt keycode 67 = Console_9
+# control alt keycode 67 = Console_9
+#keycode 68 = F10 F20 Console_22
+# control keycode 68 = F10
+# alt keycode 68 = Console_10
+# control alt keycode 68 = Console_10
+#keycode 69 = Num_Lock
+# shift keycode 69 = Bare_Num_Lock
+#keycode 70 = Scroll_Lock Show_Memory Show_Registers
+# control keycode 70 = Show_State
+# alt keycode 70 = Scroll_Lock
+#keycode 71 = KP_7
+# alt keycode 71 = Ascii_7
+# altgr keycode 71 = Hex_7
+#keycode 72 = KP_8
+# alt keycode 72 = Ascii_8
+# altgr keycode 72 = Hex_8
+#keycode 73 = KP_9
+# alt keycode 73 = Ascii_9
+# altgr keycode 73 = Hex_9
+#keycode 74 = KP_Subtract
+#keycode 75 = KP_4
+# alt keycode 75 = Ascii_4
+# altgr keycode 75 = Hex_4
+#keycode 76 = KP_5
+# alt keycode 76 = Ascii_5
+# altgr keycode 76 = Hex_5
+#keycode 77 = KP_6
+# alt keycode 77 = Ascii_6
+# altgr keycode 77 = Hex_6
+#keycode 78 = KP_Add
+#keycode 79 = KP_1
+# alt keycode 79 = Ascii_1
+# altgr keycode 79 = Hex_1
+#keycode 80 = KP_2
+# alt keycode 80 = Ascii_2
+# altgr keycode 80 = Hex_2
+#keycode 81 = KP_3
+# alt keycode 81 = Ascii_3
+# altgr keycode 81 = Hex_3
+#keycode 82 = KP_0
+# alt keycode 82 = Ascii_0
+# altgr keycode 82 = Hex_0
+#keycode 83 = KP_Period
+## altgr control keycode 83 = Boot
+# control alt keycode 83 = Boot
+#keycode 84 = Last_Console
+#keycode 85 =
+#keycode 86 = less greater bar
+# alt keycode 86 = Meta_less
+#keycode 87 = F11 F11 Console_23
+# control keycode 87 = F11
+# alt keycode 87 = Console_11
+# control alt keycode 87 = Console_11
+#keycode 88 = F12 F12 Console_24
+# control keycode 88 = F12
+# alt keycode 88 = Console_12
+# control alt keycode 88 = Console_12
+#keycode 89 =
+#keycode 90 =
+keycode 91 = space
+#keycode 91 =
+keycode 92 = Return
+#keycode 92 =
+#keycode 93 =
+#keycode 94 =
+#keycode 95 =
+#keycode 96 = KP_Enter
+#keycode 97 = Control
+#keycode 98 = KP_Divide
+#keycode 99 = Control_backslash
+# control keycode 99 = Control_backslash
+# alt keycode 99 = Control_backslash
+keycode 100 = AltGr
+#keycode 101 = Break
+#keycode 102 = Find
keycode 103 = Up
+ altgr keycode 103 = Prior
+ shift keycode 104 = Scroll_Backward
+#keycode 104 = Prior
+# shift keycode 104 = Scroll_Backward
keycode 105 = Left
- altgr keycode 105 = Decr_Console
+ altgr keycode 105 = Decr_Console
keycode 106 = Right
- altgr keycode 106 = Incr_Console
-keycode 108 = Down
+ altgr keycode 106 = Incr_Console
+#keycode 107 = Select
+keycode 108 = Down
+ altgr keycode 108 = Next
+ shift keycode 108 = Scroll_Forward
+#keycode 109 = Next
+# shift keycode 109 = Scroll_Forward
+#keycode 110 = Insert
+#keycode 111 = Remove
+## altgr control keycode 111 = Boot
+# control alt keycode 111 = Boot
+#keycode 112 = Macro
+#keycode 113 = F13
+#keycode 114 = F14
+#keycode 115 = Help
+#keycode 116 = Do
+#keycode 117 = F17
+#keycode 118 = KP_MinPlus
+#keycode 119 = Pause
+#keycode 120 =
+#keycode 121 =
+#keycode 122 =
+#keycode 123 =
+#keycode 124 =
+#keycode 125 =
+#keycode 126 =
+#keycode 127 =
string F1 = "\033[[A"
string F2 = "\033[[B"
string F3 = "\033[[C"
diff --git a/packages/keymaps/keymaps_1.0.bb b/packages/keymaps/keymaps_1.0.bb
index 00a215f948..bf60ce0448 100644
--- a/packages/keymaps/keymaps_1.0.bb
+++ b/packages/keymaps/keymaps_1.0.bb
@@ -3,7 +3,7 @@ SECTION = "base"
RDEPENDS = "initscripts console-tools"
LICENSE = "GPL"
PACKAGE_ARCH = "${MACHINE}"
-PR = "r16"
+PR = "r17"
inherit update-rc.d
diff --git a/packages/klibc/files/fstype-sane-and-vfat-jffs2.patch b/packages/klibc/files/fstype-sane-and-vfat-jffs2.patch
deleted file mode 100644
index e89c5adb9a..0000000000
--- a/packages/klibc/files/fstype-sane-and-vfat-jffs2.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-diff -r 3c9d84425ba7 utils/fstype.c
---- a/utils/fstype.c Thu Feb 14 02:09:30 2008 +0200
-+++ b/utils/fstype.c Thu Feb 14 02:13:46 2008 +0200
-@@ -13,11 +13,18 @@
- */
-
- #include <sys/types.h>
-+#include <linux/types.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <endian.h>
- #include <netinet/in.h>
-+#if __BYTE_ORDER == __BIG_ENDIAN
-+#include <linux/byteorder/big_endian.h>
-+#else
-+#include <linux/byteorder/little_endian.h>
-+#endif
-+
-
- #define cpu_to_be32(x) __cpu_to_be32(x) /* Needed by romfs_fs.h */
-
-@@ -105,6 +112,27 @@ static int romfs_image(const unsigned ch
- return 0;
- }
-
-+static int jffs2_image(const unsigned char *buf, unsigned long *blocks)
-+{
-+ // Very sloppy! ;-E
-+ if (*buf == 0x85 && buf[1] == 0x19)
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static int vfat_image(const unsigned char *buf, unsigned long *blocks)
-+{
-+ const struct romfs_super_block *sb =
-+ (const struct romfs_super_block *)buf;
-+ if (!strncmp(buf + 54, "FAT12 ", 8)
-+ || !strncmp(buf + 54, "FAT16 ", 8)
-+ || !strncmp(buf + 82, "FAT32 ", 8))
-+ return 1;
-+
-+ return 0;
-+}
-+
- static int minix_image(const unsigned char *buf, unsigned long *blocks)
- {
- const struct minix_super_block *sb =
-@@ -167,8 +195,6 @@ static int xfs_image(const unsigned char
- (const struct xfs_sb *)buf;
-
- if (__be32_to_cpu(sb->sb_magicnum) == XFS_SB_MAGIC) {
-- *blocks = __be64_to_cpu(sb->sb_dblocks) *
-- (__be32_to_cpu(sb->sb_blocksize) / BLOCK_SIZE);
- return 1;
- }
- return 0;
-@@ -184,6 +210,8 @@ static struct imagetype images[] = {
- { 0, "gzip", gzip_image },
- { 0, "cramfs", cramfs_image },
- { 0, "romfs", romfs_image },
-+ { 0, "jffs2", jffs2_image },
-+ { 0, "vfat", vfat_image },
- { 0, "xfs", xfs_image },
- { 1, "minix", minix_image },
- { 1, "ext3", ext3_image },
diff --git a/packages/klibc/files/losetup.patch b/packages/klibc/files/losetup.patch
new file mode 100644
index 0000000000..77049bd05f
--- /dev/null
+++ b/packages/klibc/files/losetup.patch
@@ -0,0 +1,571 @@
+Index: klibc-1.5/usr/utils/losetup.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/losetup.c 2008-03-07 23:13:38.635692852 +0100
+@@ -0,0 +1,485 @@
++/* Originally from Ted's losetup.c */
++
++#define LOOPMAJOR 7
++
++/*
++ * losetup.c - setup and control loop devices
++ */
++
++#include <stdio.h>
++#include <string.h>
++#include <ctype.h>
++#include <fcntl.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/ioctl.h>
++#include <sys/stat.h>
++#include <sys/mman.h>
++#include <sys/sysmacros.h>
++#include <string.h>
++
++#include "loop.h"
++
++extern int verbose;
++extern char *progname;
++extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
++extern void error (const char *fmt, ...); /* idem */
++
++/* caller guarantees n > 0 */
++void
++xstrncpy(char *dest, const char *src, size_t n) {
++ strncpy(dest, src, n-1);
++ dest[n-1] = 0;
++}
++
++
++static int
++loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
++{
++ memset(info, 0, sizeof(*info));
++ info->lo_number = info64->lo_number;
++ info->lo_device = info64->lo_device;
++ info->lo_inode = info64->lo_inode;
++ info->lo_rdevice = info64->lo_rdevice;
++ info->lo_offset = info64->lo_offset;
++ info->lo_encrypt_type = info64->lo_encrypt_type;
++ info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
++ info->lo_flags = info64->lo_flags;
++ info->lo_init[0] = info64->lo_init[0];
++ info->lo_init[1] = info64->lo_init[1];
++ if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
++ memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
++ else
++ memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
++ memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
++
++ /* error in case values were truncated */
++ if (info->lo_device != info64->lo_device ||
++ info->lo_rdevice != info64->lo_rdevice ||
++ info->lo_inode != info64->lo_inode ||
++ info->lo_offset != info64->lo_offset)
++ return -EOVERFLOW;
++
++ return 0;
++}
++
++
++static int
++show_loop(char *device) {
++ struct loop_info loopinfo;
++ struct loop_info64 loopinfo64;
++ int fd, errsv;
++
++ if ((fd = open(device, O_RDONLY)) < 0) {
++ int errsv = errno;
++ fprintf(stderr, "loop: can't open device %s: %s\n",
++ device, strerror (errsv));
++ return 2;
++ }
++
++ if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
++
++ loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
++ loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
++ loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
++
++ printf("%s: [%04llx]:%llu (%s)",
++ device, loopinfo64.lo_device, loopinfo64.lo_inode,
++ loopinfo64.lo_file_name);
++
++ if (loopinfo64.lo_offset)
++ printf(", offset %lld", loopinfo64.lo_offset);
++
++ if (loopinfo64.lo_sizelimit)
++ printf(", sizelimit %lld", loopinfo64.lo_sizelimit);
++
++ if (loopinfo64.lo_encrypt_type ||
++ loopinfo64.lo_crypt_name[0]) {
++ char *e = loopinfo64.lo_crypt_name;
++
++ if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
++ e = "XOR";
++ printf(", encryption %s (type %d)",
++ e, loopinfo64.lo_encrypt_type);
++ }
++ printf("\n");
++ close (fd);
++ return 0;
++ }
++
++ if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
++ printf ("%s: [%04x]:%ld (%s)",
++ device, loopinfo.lo_device, loopinfo.lo_inode,
++ loopinfo.lo_name);
++
++ if (loopinfo.lo_offset)
++ printf(", offset %d", loopinfo.lo_offset);
++
++ if (loopinfo.lo_encrypt_type)
++ printf(", encryption type %d\n",
++ loopinfo.lo_encrypt_type);
++
++ printf("\n");
++ close (fd);
++ return 0;
++ }
++
++ errsv = errno;
++ fprintf(stderr, "loop: can't get info on device %s: %s\n",
++ device, strerror (errsv));
++ close (fd);
++ return 1;
++}
++
++int
++is_loop_device (const char *device) {
++ struct stat statbuf;
++
++ return (stat(device, &statbuf) == 0 &&
++ S_ISBLK(statbuf.st_mode) &&
++ major(statbuf.st_rdev) == LOOPMAJOR);
++}
++
++#define SIZE(a) (sizeof(a)/sizeof(a[0]))
++
++char *
++find_unused_loop_device (void) {
++ /* Just creating a device, say in /tmp, is probably a bad idea -
++ people might have problems with backup or so.
++ So, we just try /dev/loop[0-7]. */
++ char dev[20];
++ char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
++ int i, j, fd, somedev = 0, someloop = 0, permission = 0;
++ struct stat statbuf;
++ struct loop_info loopinfo;
++
++ for (j = 0; j < SIZE(loop_formats); j++) {
++ for(i = 0; i < 256; i++) {
++ sprintf(dev, loop_formats[j], i);
++ if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
++ somedev++;
++ fd = open (dev, O_RDONLY);
++ if (fd >= 0) {
++ if(ioctl (fd, LOOP_GET_STATUS, &loopinfo) == 0)
++ someloop++; /* in use */
++ else if (errno == ENXIO) {
++ close (fd);
++ return xstrdup(dev);/* probably free */
++ }
++ close (fd);
++ } else if (errno == EACCES)
++ permission++;
++
++ continue;/* continue trying as long as devices exist */
++ }
++ break;
++ }
++ }
++
++ if (!somedev)
++ error("%s: could not find any device /dev/loop#", progname);
++ else if (!someloop && permission)
++ error("%s: no permission to look at /dev/loop#", progname);
++ else if (!someloop)
++ error(
++ "%s: Could not find any loop device. Maybe this kernel "
++ "does not know\n"
++ " about the loop device? (If so, recompile or "
++ "`modprobe loop'.)", progname);
++ else
++ error("%s: could not find any free loop device", progname);
++ return 0;
++}
++
++/*
++ * A function to read the passphrase either from the terminal or from
++ * an open file descriptor.
++ */
++static char *
++xgetpass(int pfd, const char *prompt) {
++ char *pass;
++ int buflen, i;
++
++ pass = NULL;
++ buflen = 0;
++ for (i=0; ; i++) {
++ if (i >= buflen-1) {
++ /* we're running out of space in the buffer.
++ * Make it bigger: */
++ char *tmppass = pass;
++ buflen += 128;
++ pass = realloc(tmppass, buflen);
++ if (pass == NULL) {
++ /* realloc failed. Stop reading. */
++ error("Out of memory while reading passphrase");
++ pass = tmppass; /* the old buffer hasn't changed */
++ break;
++ }
++ }
++ if (read(pfd, pass+i, 1) != 1 ||
++ pass[i] == '\n' || pass[i] == 0)
++ break;
++ }
++
++ if (pass == NULL)
++ return "";
++
++ pass[i] = 0;
++ return pass;
++}
++
++static int
++digits_only(const char *s) {
++ while (*s)
++ if (!isdigit(*s++))
++ return 0;
++ return 1;
++}
++
++int
++set_loop(const char *device, const char *file, unsigned long long offset,
++ const char *encryption, int pfd, int *loopro) {
++ struct loop_info64 loopinfo64;
++ int fd, ffd, mode, i;
++ char *pass;
++
++ mode = (*loopro ? O_RDONLY : O_RDWR);
++ if ((ffd = open(file, mode)) < 0) {
++ if (!*loopro && errno == EROFS)
++ ffd = open(file, mode = O_RDONLY);
++ if (ffd < 0) {
++ perror(file);
++ return 1;
++ }
++ }
++ if ((fd = open(device, mode)) < 0) {
++ perror (device);
++ return 1;
++ }
++ *loopro = (mode == O_RDONLY);
++
++ memset(&loopinfo64, 0, sizeof(loopinfo64));
++
++ xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
++
++ if (encryption && *encryption) {
++ if (digits_only(encryption)) {
++ loopinfo64.lo_encrypt_type = atoi(encryption);
++ } else {
++ loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
++ snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
++ "%s", encryption);
++ }
++ }
++
++ loopinfo64.lo_offset = offset;
++
++
++ switch (loopinfo64.lo_encrypt_type) {
++ case LO_CRYPT_NONE:
++ loopinfo64.lo_encrypt_key_size = 0;
++ break;
++ case LO_CRYPT_XOR:
++ pass = xgetpass(pfd, "Password: ");
++ goto gotpass;
++ default:
++ pass = xgetpass(pfd, "Password: ");
++ gotpass:
++ memset(loopinfo64.lo_encrypt_key, 0, LO_KEY_SIZE);
++ xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
++ memset(pass, 0, strlen(pass));
++ loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
++ }
++
++ if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
++ perror("ioctl: LOOP_SET_FD");
++ return 1;
++ }
++ close (ffd);
++
++ i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
++ if (i) {
++ struct loop_info loopinfo;
++ int errsv = errno;
++
++ i = loop_info64_to_old(&loopinfo64, &loopinfo);
++ if (i) {
++ errno = errsv;
++ perror("ioctl: LOOP_SET_STATUS64");
++ } else {
++ i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
++ if (i)
++ perror("ioctl: LOOP_SET_STATUS");
++ }
++ memset(&loopinfo, 0, sizeof(loopinfo));
++ }
++ memset(&loopinfo64, 0, sizeof(loopinfo64));
++
++ if (i) {
++ ioctl (fd, LOOP_CLR_FD, 0);
++ close (fd);
++ return 1;
++ }
++ close (fd);
++
++ if (verbose > 1)
++ printf("set_loop(%s,%s,%llu): success\n",
++ device, file, offset);
++ return 0;
++}
++
++int
++del_loop (const char *device) {
++ int fd;
++
++ if ((fd = open (device, O_RDONLY)) < 0) {
++ int errsv = errno;
++ fprintf(stderr, "loop: can't delete device %s: %s\n",
++ device, strerror (errsv));
++ return 1;
++ }
++ if (ioctl (fd, LOOP_CLR_FD, 0) < 0) {
++ perror ("ioctl: LOOP_CLR_FD");
++ return 1;
++ }
++ close (fd);
++ if (verbose > 1)
++ printf("del_loop(%s): success\n", device);
++ return 0;
++}
++
++
++#include <getopt.h>
++#include <stdarg.h>
++
++int verbose = 0;
++char *progname;
++
++static void
++usage(void) {
++ fprintf(stderr, "usage:\n\
++ %s loop_device # give info\n\
++ %s -d loop_device # delete\n\
++ %s -f # find unused\n\
++ %s [-e encryption] [-o offset] {-f|loop_device} file # setup\n",
++ progname, progname, progname, progname);
++ exit(1);
++}
++
++char *
++xstrdup (const char *s) {
++ char *t;
++
++ if (s == NULL)
++ return NULL;
++
++ t = strdup (s);
++
++ if (t == NULL) {
++ fprintf(stderr, "not enough memory");
++ exit(1);
++ }
++
++ return t;
++}
++
++void
++error (const char *fmt, ...) {
++ va_list args;
++
++ va_start (args, fmt);
++ vfprintf (stderr, fmt, args);
++ va_end (args);
++ fprintf (stderr, "\n");
++}
++
++int
++main(int argc, char **argv) {
++ char *p, *offset, *encryption, *passfd, *device, *file;
++ int delete, find, c;
++ int res = 0;
++ int ro = 0;
++ int pfd = -1;
++ unsigned long long off;
++
++
++ delete = find = 0;
++ off = 0;
++ offset = encryption = passfd = NULL;
++
++ progname = argv[0];
++ if ((p = strrchr(progname, '/')) != NULL)
++ progname = p+1;
++
++ while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
++ switch (c) {
++ case 'd':
++ delete = 1;
++ break;
++ case 'E':
++ case 'e':
++ encryption = optarg;
++ break;
++ case 'f':
++ find = 1;
++ break;
++ case 'o':
++ offset = optarg;
++ break;
++ case 'p':
++ passfd = optarg;
++ break;
++ case 'v':
++ verbose = 1;
++ break;
++ default:
++ usage();
++ }
++ }
++
++ if (argc == 1) {
++ usage();
++ } else if (delete) {
++ if (argc != optind+1 || encryption || offset || find)
++ usage();
++ } else if (find) {
++ if (argc < optind || argc > optind+1)
++ usage();
++ } else {
++ if (argc < optind+1 || argc > optind+2)
++ usage();
++ }
++
++ if (find) {
++ device = find_unused_loop_device();
++ if (device == NULL)
++ return -1;
++ if (verbose)
++ printf("Loop device is %s\n", device);
++ if (argc == optind) {
++ printf("%s\n", device);
++ return 0;
++ }
++ file = argv[optind];
++ } else {
++ device = argv[optind];
++ if (argc == optind+1)
++ file = NULL;
++ else
++ file = argv[optind+1];
++ }
++
++ if (delete)
++ res = del_loop(device);
++ else if (file == NULL)
++ res = show_loop(device);
++ else {
++ if (offset && sscanf(offset, "%llu", &off) != 1)
++ usage();
++ if (passfd && sscanf(passfd, "%d", &pfd) != 1)
++ usage();
++ res = set_loop(device, file, off, encryption, pfd, &ro);
++ }
++ return res;
++}
+Index: klibc-1.5/usr/utils/loop.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/loop.h 2008-03-07 23:01:49.336694297 +0100
+@@ -0,0 +1,51 @@
++#define LO_CRYPT_NONE 0
++#define LO_CRYPT_XOR 1
++#define LO_CRYPT_DES 2
++#define LO_CRYPT_CRYPTOAPI 18
++
++#define LOOP_SET_FD 0x4C00
++#define LOOP_CLR_FD 0x4C01
++#define LOOP_SET_STATUS 0x4C02
++#define LOOP_GET_STATUS 0x4C03
++#define LOOP_SET_STATUS64 0x4C04
++#define LOOP_GET_STATUS64 0x4C05
++
++#define LO_NAME_SIZE 64
++#define LO_KEY_SIZE 32
++
++#include "my_dev_t.h"
++
++struct loop_info {
++ int lo_number;
++ my_dev_t lo_device;
++ unsigned long lo_inode;
++ my_dev_t lo_rdevice;
++ int lo_offset;
++ int lo_encrypt_type;
++ int lo_encrypt_key_size;
++ int lo_flags;
++ char lo_name[LO_NAME_SIZE];
++ unsigned char lo_encrypt_key[LO_KEY_SIZE];
++ unsigned long lo_init[2];
++ char reserved[4];
++};
++
++/*
++ * Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
++ * and get punished when someone comes with 128-bit long longs.
++ */
++struct loop_info64 {
++ unsigned long long lo_device;
++ unsigned long long lo_inode;
++ unsigned long long lo_rdevice;
++ unsigned long long lo_offset;
++ unsigned long long lo_sizelimit; /* bytes, 0 == max available */
++ unsigned int lo_number;
++ unsigned int lo_encrypt_type;
++ unsigned int lo_encrypt_key_size;
++ unsigned int lo_flags;
++ unsigned char lo_file_name[LO_NAME_SIZE];
++ unsigned char lo_crypt_name[LO_NAME_SIZE];
++ unsigned char lo_encrypt_key[LO_KEY_SIZE];
++ unsigned long long lo_init[2];
++};
+Index: klibc-1.5/usr/utils/my_dev_t.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/my_dev_t.h 2008-03-07 23:03:45.148693283 +0100
+@@ -0,0 +1,20 @@
++/* silliness to get dev_t defined as the kernel defines it */
++/* glibc uses a different dev_t */
++
++#include <linux/posix_types.h>
++#include <linux/version.h>
++
++#ifndef KERNEL_VERSION
++#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
++#endif
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(1,3,78)
++/* for i386 - alpha uses unsigned int */
++#define my_dev_t unsigned short
++#else
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)
++#define my_dev_t __kernel_dev_t
++#else
++#define my_dev_t __kernel_old_dev_t
++#endif
++#endif
diff --git a/packages/klibc/files/modprobe.patch b/packages/klibc/files/modprobe.patch
new file mode 100644
index 0000000000..074b0b6311
--- /dev/null
+++ b/packages/klibc/files/modprobe.patch
@@ -0,0 +1,1985 @@
+Index: klibc-1.5/usr/utils/Kbuild
+===================================================================
+--- klibc-1.5.orig/usr/utils/Kbuild 2008-03-07 22:01:45.223695348 +0100
++++ klibc-1.5/usr/utils/Kbuild 2008-03-07 22:48:44.660783243 +0100
+@@ -3,8 +3,8 @@
+ #
+
+ progs := chroot dd mkdir mkfifo mknod mount pivot_root umount
+-progs += true false sleep ln nuke minips cat
+-progs += insmod uname halt kill readlink cpio
++progs += true false sleep ln nuke minips cat losetup
++progs += insmod uname halt kill readlink cpio modprobe
+
+ static-y := $(addprefix static/, $(progs))
+ shared-y := $(addprefix shared/, $(progs))
+@@ -52,7 +52,10 @@
+ shared/readlink-y := readlink.o
+ static/cpio-y := cpio.o
+ shared/cpio-y := cpio.o
+-
++static/modprobe-y := modprobe.o
++shared/modprobe-y := modprobe.o
++static/losetup-y := losetup.o
++shared/losetup-y := losetup.o
+ # Additionally linked targets
+ always := static/reboot static/poweroff shared/reboot shared/poweroff
+
+Index: klibc-1.5/usr/utils/list.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/list.h 2008-03-07 22:33:22.287688586 +0100
+@@ -0,0 +1,238 @@
++/* Stolen from Linux Kernel Source's list.h -- GPL. */
++#ifndef _MODINITTOOLS_LIST_H
++#define _MODINITTOOLS_LIST_H
++
++#undef offsetof
++#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
++
++/**
++ * container_of - cast a member of a structure out to the containing structure
++ *
++ * @ptr: the pointer to the member.
++ * @type: the type of the container struct this is embedded in.
++ * @member: the name of the member within the struct.
++ *
++ */
++#define container_of(ptr, type, member) ({ \
++ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
++ (type *)( (char *)__mptr - offsetof(type,member) );})
++
++/*
++ * Simple doubly linked list implementation.
++ *
++ * Some of the internal functions ("__xxx") are useful when
++ * manipulating whole lists rather than single entries, as
++ * sometimes we already know the next/prev entries and we can
++ * generate better code by using them directly rather than
++ * using the generic single-entry routines.
++ */
++
++struct list_head {
++ struct list_head *next, *prev;
++};
++
++#define LIST_HEAD_INIT(name) { &(name), &(name) }
++
++#define LIST_HEAD(name) \
++ struct list_head name = LIST_HEAD_INIT(name)
++
++#define INIT_LIST_HEAD(ptr) do { \
++ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
++} while (0)
++
++/*
++ * Insert a new entry between two known consecutive entries.
++ *
++ * This is only for internal list manipulation where we know
++ * the prev/next entries already!
++ */
++static inline void __list_add(struct list_head *new,
++ struct list_head *prev,
++ struct list_head *next)
++{
++ next->prev = new;
++ new->next = next;
++ new->prev = prev;
++ prev->next = new;
++}
++
++/**
++ * list_add - add a new entry
++ * @new: new entry to be added
++ * @head: list head to add it after
++ *
++ * Insert a new entry after the specified head.
++ * This is good for implementing stacks.
++ */
++static inline void list_add(struct list_head *new, struct list_head *head)
++{
++ __list_add(new, head, head->next);
++}
++
++/**
++ * list_add_tail - add a new entry
++ * @new: new entry to be added
++ * @head: list head to add it before
++ *
++ * Insert a new entry before the specified head.
++ * This is useful for implementing queues.
++ */
++static inline void list_add_tail(struct list_head *new, struct list_head *head)
++{
++ __list_add(new, head->prev, head);
++}
++
++/*
++ * Delete a list entry by making the prev/next entries
++ * point to each other.
++ *
++ * This is only for internal list manipulation where we know
++ * the prev/next entries already!
++ */
++static inline void __list_del(struct list_head * prev, struct list_head * next)
++{
++ next->prev = prev;
++ prev->next = next;
++}
++
++/**
++ * list_del - deletes entry from list.
++ * @entry: the element to delete from the list.
++ * Note: list_empty on entry does not return true after this, the entry is
++ * in an undefined state.
++ */
++static inline void list_del(struct list_head *entry)
++{
++ __list_del(entry->prev, entry->next);
++}
++
++/**
++ * list_del_init - deletes entry from list and reinitialize it.
++ * @entry: the element to delete from the list.
++ */
++static inline void list_del_init(struct list_head *entry)
++{
++ __list_del(entry->prev, entry->next);
++ INIT_LIST_HEAD(entry);
++}
++
++/**
++ * list_move - delete from one list and add as another's head
++ * @list: the entry to move
++ * @head: the head that will precede our entry
++ */
++static inline void list_move(struct list_head *list, struct list_head *head)
++{
++ __list_del(list->prev, list->next);
++ list_add(list, head);
++}
++
++/**
++ * list_move_tail - delete from one list and add as another's tail
++ * @list: the entry to move
++ * @head: the head that will follow our entry
++ */
++static inline void list_move_tail(struct list_head *list,
++ struct list_head *head)
++{
++ __list_del(list->prev, list->next);
++ list_add_tail(list, head);
++}
++
++/**
++ * list_empty - tests whether a list is empty
++ * @head: the list to test.
++ */
++static inline int list_empty(struct list_head *head)
++{
++ return head->next == head;
++}
++
++static inline void __list_splice(struct list_head *list,
++ struct list_head *head)
++{
++ struct list_head *first = list->next;
++ struct list_head *last = list->prev;
++ struct list_head *at = head->next;
++
++ first->prev = head;
++ head->next = first;
++
++ last->next = at;
++ at->prev = last;
++}
++
++/**
++ * list_splice - join two lists
++ * @list: the new list to add.
++ * @head: the place to add it in the first list.
++ */
++static inline void list_splice(struct list_head *list, struct list_head *head)
++{
++ if (!list_empty(list))
++ __list_splice(list, head);
++}
++
++/**
++ * list_splice_init - join two lists and reinitialise the emptied list.
++ * @list: the new list to add.
++ * @head: the place to add it in the first list.
++ *
++ * The list at @list is reinitialised
++ */
++static inline void list_splice_init(struct list_head *list,
++ struct list_head *head)
++{
++ if (!list_empty(list)) {
++ __list_splice(list, head);
++ INIT_LIST_HEAD(list);
++ }
++}
++
++/**
++ * list_entry - get the struct for this entry
++ * @ptr: the &struct list_head pointer.
++ * @type: the type of the struct this is embedded in.
++ * @member: the name of the list_struct within the struct.
++ */
++#define list_entry(ptr, type, member) \
++ container_of(ptr, type, member)
++
++/**
++ * list_for_each - iterate over a list
++ * @pos: the &struct list_head to use as a loop counter.
++ * @head: the head for your list.
++ */
++#define list_for_each(pos, head) \
++ for (pos = (head)->next; pos != (head); pos = pos->next)
++
++/**
++ * list_for_each_prev - iterate over a list backwards
++ * @pos: the &struct list_head to use as a loop counter.
++ * @head: the head for your list.
++ */
++#define list_for_each_prev(pos, head) \
++ for (pos = (head)->prev; pos != (head); pos = pos->prev)
++
++/**
++ * list_for_each_safe - iterate over a list safe against removal of list entry
++ * @pos: the &struct list_head to use as a loop counter.
++ * @n: another &struct list_head to use as temporary storage
++ * @head: the head for your list.
++ */
++#define list_for_each_safe(pos, n, head) \
++ for (pos = (head)->next, n = pos->next; pos != (head); \
++ pos = n, n = pos->next)
++
++/**
++ * list_for_each_entry - iterate over list of given type
++ * @pos: the type * to use as a loop counter.
++ * @head: the head for your list.
++ * @member: the name of the list_struct within the struct.
++ */
++#define list_for_each_entry(pos, head, member) \
++ for (pos = list_entry((head)->next, typeof(*pos), member); \
++ &pos->member != (head); \
++ pos = list_entry(pos->member.next, typeof(*pos), member))
++
++#endif
+Index: klibc-1.5/usr/utils/modprobe.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ klibc-1.5/usr/utils/modprobe.c 2008-03-08 03:05:51.847688952 +0100
+@@ -0,0 +1,1710 @@
++/* modprobe.c: insert a module into the kernel, intelligently.
++ Copyright (C) 2001 Rusty Russell.
++ Copyright (C) 2002, 2003 Rusty Russell, IBM Corporation.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++*/
++#define _GNU_SOURCE /* asprintf */
++
++#include <sys/utsname.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/mman.h>
++#include <fcntl.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <ctype.h>
++#include <string.h>
++#include <errno.h>
++#include <unistd.h>
++#include <dirent.h>
++#include <limits.h>
++#include <elf.h>
++#include <getopt.h>
++#include <fnmatch.h>
++#include <asm/unistd.h>
++#include <sys/wait.h>
++#include <syslog.h>
++#include <zlib.h>
++
++#define streq(a,b) (strcmp((a),(b)) == 0)
++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
++
++#include "list.h"
++static inline void try_old_version(const char *progname, char *argv[])
++{
++}
++extern long init_module(void *, unsigned long, const char *);
++extern long delete_module(const char *, unsigned int);
++
++struct module {
++ struct list_head list;
++ char *modname;
++ char filename[0];
++};
++
++#ifndef MODULE_DIR
++#define MODULE_DIR "/lib/modules"
++#endif
++
++typedef void (*errfn_t)(const char *fmt, ...);
++
++/* Do we use syslog or stderr for messages? */
++static int log;
++
++static void message(const char *prefix, const char *fmt, va_list *arglist)
++{
++ char *buf, *buf2;
++
++ vasprintf(&buf, fmt, *arglist);
++ asprintf(&buf2, "%s%s", prefix, buf);
++
++ if (log)
++ syslog(LOG_NOTICE, "%s", buf2);
++ else
++ fprintf(stderr, "%s", buf2);
++ free(buf2);
++ free(buf);
++}
++void *grab_contents(gzFile *gzfd, unsigned long *size)
++{
++ unsigned int max = 16384;
++ void *buffer = malloc(max);
++ int ret;
++
++ if (!buffer)
++ return NULL;
++
++ *size = 0;
++ while ((ret = gzread(gzfd, buffer + *size, max - *size)) > 0) {
++ *size += ret;
++ if (*size == max) {
++ buffer = realloc(buffer, max *= 2);
++ if (!buffer)
++ return NULL;
++ }
++ }
++ if (ret < 0) {
++ free(buffer);
++ buffer = NULL;
++ }
++ return buffer;
++}
++
++void *grab_fd(int fd, unsigned long *size)
++{
++ gzFile gzfd;
++
++ gzfd = gzdopen(fd, "rb");
++ if (!gzfd)
++ return NULL;
++
++ /* gzclose(gzfd) would close fd, which would drop locks.
++ Don't blame zlib: POSIX locking semantics are so horribly
++ broken that they should be ripped out. */
++ return grab_contents(gzfd, size);
++}
++void release_file(void *data, unsigned long size)
++{
++ free(data);
++}
++
++
++static int warned = 0;
++static void warn(const char *fmt, ...)
++{
++ va_list arglist;
++ warned++;
++ va_start(arglist, fmt);
++ message("WARNING: ", fmt, &arglist);
++ va_end(arglist);
++}
++
++static void fatal(const char *fmt, ...)
++{
++ va_list arglist;
++ va_start(arglist, fmt);
++ message("FATAL: ", fmt, &arglist);
++ va_end(arglist);
++ exit(1);
++}
++
++
++static void grammar(const char *cmd, const char *filename, unsigned int line)
++{
++ warn("%s line %u: ignoring bad line starting with '%s'\n",
++ filename, line, cmd);
++}
++
++static void *do_nofail(void *ptr, const char *file, int line, const char *expr)
++{
++ if (!ptr) {
++ fatal("Memory allocation failure %s line %d: %s.\n",
++ file, line, expr);
++ }
++ return ptr;
++}
++
++#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
++
++static void print_usage(const char *progname)
++{
++ fprintf(stderr,
++ "Usage: %s [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] [-o <modname>] <modname> [parameters...]\n"
++ "%s -r [-n] [-i] [-v] <modulename> ...\n"
++ "%s -l -t <dirname> [ -a <modulename> ...]\n",
++ progname, progname, progname);
++ exit(1);
++}
++
++static int fgetc_wrapped(FILE *file, unsigned int *linenum)
++{
++ for (;;) {
++ int ch = fgetc(file);
++ if (ch != '\\')
++ return ch;
++ ch = fgetc(file);
++ if (ch != '\n')
++ return ch;
++ if (linenum)
++ (*linenum)++;
++ }
++}
++
++static char *getline_wrapped(FILE *file, unsigned int *linenum)
++{
++ int size = 1024;
++ int i = 0;
++ char *buf = NOFAIL(malloc(size));
++ for(;;) {
++ int ch = fgetc_wrapped(file, linenum);
++ if (i == size) {
++ size *= 2;
++ buf = NOFAIL(realloc(buf, size));
++ }
++ if (ch < 0 && i == 0) {
++ free(buf);
++ return NULL;
++ }
++ if (ch < 0 || ch == '\n') {
++ if (linenum)
++ (*linenum)++;
++ buf[i] = '\0';
++ return NOFAIL(realloc(buf, i+1));
++ }
++ buf[i++] = ch;
++ }
++}
++
++static struct module *find_module(const char *filename, struct list_head *list)
++{
++ struct module *i;
++
++ list_for_each_entry(i, list, list) {
++ if (strcmp(i->filename, filename) == 0)
++ return i;
++ }
++ return NULL;
++}
++
++/* Convert filename to the module name. Works if filename == modname, too. */
++static void filename2modname(char *modname, const char *filename)
++{
++ const char *afterslash;
++ unsigned int i;
++
++ afterslash = strrchr(filename, '/');
++ if (!afterslash)
++ afterslash = filename;
++ else
++ afterslash++;
++
++ /* Convert to underscores, stop at first . */
++ for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
++ if (afterslash[i] == '-')
++ modname[i] = '_';
++ else
++ modname[i] = afterslash[i];
++ }
++ modname[i] = '\0';
++}
++
++static int lock_file(const char *filename)
++{
++ int fd = open(filename, O_RDWR, 0);
++
++ if (fd >= 0) {
++ struct flock lock;
++ lock.l_type = F_WRLCK;
++ lock.l_whence = SEEK_SET;
++ lock.l_start = 0;
++ lock.l_len = 1;
++ fcntl(fd, F_SETLKW, &lock);
++ } else
++ /* Read-only filesystem? There goes locking... */
++ fd = open(filename, O_RDONLY, 0);
++ return fd;
++}
++
++static void unlock_file(int fd)
++{
++ /* Valgrind is picky... */
++ close(fd);
++}
++
++static void add_module(char *filename, int namelen, struct list_head *list)
++{
++ struct module *mod;
++
++ /* If it's a duplicate: move it to the end, so it gets
++ inserted where it is *first* required. */
++ mod = find_module(filename, list);
++ if (mod)
++ list_del(&mod->list);
++ else {
++ /* No match. Create a new module. */
++ mod = NOFAIL(malloc(sizeof(struct module) + namelen + 1));
++ memcpy(mod->filename, filename, namelen);
++ mod->filename[namelen] = '\0';
++ mod->modname = NOFAIL(malloc(namelen + 1));
++ filename2modname(mod->modname, mod->filename);
++ }
++
++ list_add_tail(&mod->list, list);
++}
++
++/* Compare len chars of a to b, with _ and - equivalent. */
++static int modname_equal(const char *a, const char *b, unsigned int len)
++{
++ unsigned int i;
++
++ if (strlen(b) != len)
++ return 0;
++
++ for (i = 0; i < len; i++) {
++ if ((a[i] == '_' || a[i] == '-')
++ && (b[i] == '_' || b[i] == '-'))
++ continue;
++ if (a[i] != b[i])
++ return 0;
++ }
++ return 1;
++}
++
++/* Fills in list of modules if this is the line we want. */
++static int add_modules_dep_line(char *line,
++ const char *name,
++ struct list_head *list)
++{
++ char *ptr;
++ int len;
++ char *modname;
++
++ /* Ignore lines without : or which start with a # */
++ ptr = strchr(line, ':');
++ if (ptr == NULL || line[strspn(line, "\t ")] == '#')
++ return 0;
++
++ /* Is this the module we are looking for? */
++ *ptr = '\0';
++ if (strrchr(line, '/'))
++ modname = strrchr(line, '/') + 1;
++ else
++ modname = line;
++
++ len = strlen(modname);
++ if (strchr(modname, '.'))
++ len = strchr(modname, '.') - modname;
++ if (!modname_equal(modname, name, len))
++ return 0;
++
++ /* Create the list. */
++ add_module(line, ptr - line, list);
++
++ ptr++;
++ for(;;) {
++ char *dep_start;
++ ptr += strspn(ptr, " \t");
++ if (*ptr == '\0')
++ break;
++ dep_start = ptr;
++ ptr += strcspn(ptr, " \t");
++ add_module(dep_start, ptr - dep_start, list);
++ }
++ return 1;
++}
++
++static void read_depends(const char *dirname,
++ const char *start_name,
++ struct list_head *list)
++{
++ char *modules_dep_name;
++ char *line;
++ FILE *modules_dep;
++ int done = 0;
++
++ asprintf(&modules_dep_name, "%s/%s", dirname, "modules.dep");
++ modules_dep = fopen(modules_dep_name, "r");
++ if (!modules_dep)
++ fatal("Could not load %s: %s\n",
++ modules_dep_name, strerror(errno));
++
++ /* Stop at first line, as we can have duplicates (eg. symlinks
++ from boot/ */
++ while (!done && (line = getline_wrapped(modules_dep, NULL)) != NULL) {
++ done = add_modules_dep_line(line, start_name, list);
++ free(line);
++ }
++ fclose(modules_dep);
++ free(modules_dep_name);
++}
++
++/* We use error numbers in a loose translation... */
++static const char *insert_moderror(int err)
++{
++ switch (err) {
++ case ENOEXEC:
++ return "Invalid module format";
++ case ENOENT:
++ return "Unknown symbol in module, or unknown parameter (see dmesg)";
++ case ENOSYS:
++ return "Kernel does not have module support";
++ default:
++ return strerror(err);
++ }
++}
++
++static const char *remove_moderror(int err)
++{
++ switch (err) {
++ case ENOENT:
++ return "No such module";
++ case ENOSYS:
++ return "Kernel does not have module unloading support";
++ default:
++ return strerror(err);
++ }
++}
++
++/* Is module in /proc/modules? If so, fill in usecount if not NULL.
++ 0 means no, 1 means yes, -1 means unknown.
++ */
++static int module_in_kernel(const char *modname, unsigned int *usecount)
++{
++ FILE *proc_modules;
++ char *line;
++
++again:
++ /* Might not be mounted yet. Don't fail. */
++ proc_modules = fopen("/proc/modules", "r");
++ if (!proc_modules)
++ return -1;
++
++ while ((line = getline_wrapped(proc_modules, NULL)) != NULL) {
++ char *entry = strtok(line, " \n");
++
++ if (entry && streq(entry, modname)) {
++ /* If it exists, usecount is the third entry. */
++ if (!strtok(NULL, " \n"))
++ goto out;
++
++ if (!(entry = strtok(NULL, " \n"))) /* usecount */
++ goto out;
++ else
++ if (usecount)
++ *usecount = atoi(entry);
++
++ /* Followed by - then status. */
++ if (strtok(NULL, " \n")
++ && (entry = strtok(NULL, " \n")) != NULL) {
++ /* Locking will fail on ro fs, we might hit
++ * cases where module is in flux. Spin. */
++ if (streq(entry, "Loading")
++ || streq(entry, "Unloading")) {
++ usleep(100000);
++ free(line);
++ fclose(proc_modules);
++ goto again;
++ }
++ }
++
++ out:
++ free(line);
++ fclose(proc_modules);
++ return 1;
++ }
++ free(line);
++ }
++ fclose(proc_modules);
++ return 0;
++}
++
++static void replace_modname(struct module *module,
++ void *mem, unsigned long len,
++ const char *oldname, const char *newname)
++{
++ char *p;
++
++ /* 64 - sizeof(unsigned long) - 1 */
++ if (strlen(newname) > 55)
++ fatal("New name %s is too long\n", newname);
++
++ /* Find where it is in the module structure. Don't assume layout! */
++ for (p = mem; p < (char *)mem + len - strlen(oldname); p++) {
++ if (memcmp(p, oldname, strlen(oldname)) == 0) {
++ strcpy(p, newname);
++ return;
++ }
++ }
++
++ warn("Could not find old name in %s to replace!\n", module->filename);
++}
++
++static void *get_section32(void *file,
++ unsigned long size,
++ const char *name,
++ unsigned long *secsize)
++{
++ Elf32_Ehdr *hdr = file;
++ Elf32_Shdr *sechdrs = file + hdr->e_shoff;
++ const char *secnames;
++ unsigned int i;
++
++ /* Too short? */
++ if (size < sizeof(*hdr))
++ return NULL;
++ if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
++ return NULL;
++ if (size < sechdrs[hdr->e_shstrndx].sh_offset)
++ return NULL;
++
++ secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
++ for (i = 1; i < hdr->e_shnum; i++)
++ if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
++ *secsize = sechdrs[i].sh_size;
++ return file + sechdrs[i].sh_offset;
++ }
++ return NULL;
++}
++
++static void *get_section64(void *file,
++ unsigned long size,
++ const char *name,
++ unsigned long *secsize)
++{
++ Elf64_Ehdr *hdr = file;
++ Elf64_Shdr *sechdrs = file + hdr->e_shoff;
++ const char *secnames;
++ unsigned int i;
++
++ /* Too short? */
++ if (size < sizeof(*hdr))
++ return NULL;
++ if (size < hdr->e_shoff + hdr->e_shnum * sizeof(sechdrs[0]))
++ return NULL;
++ if (size < sechdrs[hdr->e_shstrndx].sh_offset)
++ return NULL;
++
++ secnames = file + sechdrs[hdr->e_shstrndx].sh_offset;
++ for (i = 1; i < hdr->e_shnum; i++)
++ if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
++ *secsize = sechdrs[i].sh_size;
++ return file + sechdrs[i].sh_offset;
++ }
++ return NULL;
++}
++
++static int elf_ident(void *mod, unsigned long size)
++{
++ /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
++ char *ident = mod;
++
++ if (size < EI_CLASS || memcmp(mod, ELFMAG, SELFMAG) != 0)
++ return ELFCLASSNONE;
++ return ident[EI_CLASS];
++}
++
++static void *get_section(void *file,
++ unsigned long size,
++ const char *name,
++ unsigned long *secsize)
++{
++ switch (elf_ident(file, size)) {
++ case ELFCLASS32:
++ return get_section32(file, size, name, secsize);
++ case ELFCLASS64:
++ return get_section64(file, size, name, secsize);
++ default:
++ return NULL;
++ }
++}
++
++static void rename_module(struct module *module,
++ void *mod,
++ unsigned long len,
++ const char *newname)
++{
++ void *modstruct;
++ unsigned long modstruct_len;
++
++ /* Old-style */
++ modstruct = get_section(mod, len, ".gnu.linkonce.this_module",
++ &modstruct_len);
++ /* New-style */
++ if (!modstruct)
++ modstruct = get_section(mod, len, "__module", &modstruct_len);
++ if (!modstruct)
++ warn("Could not find module name to change in %s\n",
++ module->filename);
++ else
++ replace_modname(module, modstruct, modstruct_len,
++ module->modname, newname);
++}
++
++/* Kernel told to ignore these sections if SHF_ALLOC not set. */
++static void invalidate_section32(void *mod, const char *secname)
++{
++ Elf32_Ehdr *hdr = mod;
++ Elf32_Shdr *sechdrs = mod + hdr->e_shoff;
++ const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
++ unsigned int i;
++
++ for (i = 1; i < hdr->e_shnum; i++)
++ if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
++ sechdrs[i].sh_flags &= ~SHF_ALLOC;
++}
++
++static void invalidate_section64(void *mod, const char *secname)
++{
++ Elf64_Ehdr *hdr = mod;
++ Elf64_Shdr *sechdrs = mod + hdr->e_shoff;
++ const char *secnames = mod + sechdrs[hdr->e_shstrndx].sh_offset;
++ unsigned int i;
++
++ for (i = 1; i < hdr->e_shnum; i++)
++ if (strcmp(secnames+sechdrs[i].sh_name, secname) == 0)
++ sechdrs[i].sh_flags &= ~(unsigned long long)SHF_ALLOC;
++}
++
++static void strip_section(struct module *module,
++ void *mod,
++ unsigned long len,
++ const char *secname)
++{
++ switch (elf_ident(mod, len)) {
++ case ELFCLASS32:
++ invalidate_section32(mod, secname);
++ break;
++ case ELFCLASS64:
++ invalidate_section64(mod, secname);
++ break;
++ default:
++ warn("Unknown module format in %s: not forcing version\n",
++ module->filename);
++ }
++}
++
++static const char *next_string(const char *string, unsigned long *secsize)
++{
++ /* Skip non-zero chars */
++ while (string[0]) {
++ string++;
++ if ((*secsize)-- <= 1)
++ return NULL;
++ }
++
++ /* Skip any zero padding. */
++ while (!string[0]) {
++ string++;
++ if ((*secsize)-- <= 1)
++ return NULL;
++ }
++ return string;
++}
++
++static void clear_magic(struct module *module, void *mod, unsigned long len)
++{
++ const char *p;
++ unsigned long modlen;
++
++ /* Old-style: __vermagic section */
++ strip_section(module, mod, len, "__vermagic");
++
++ /* New-style: in .modinfo section */
++ for (p = get_section(mod, len, ".modinfo", &modlen);
++ p;
++ p = next_string(p, &modlen)) {
++ if (strncmp(p, "vermagic=", strlen("vermagic=")) == 0) {
++ memset((char *)p, 0, strlen(p));
++ return;
++ }
++ }
++}
++
++struct module_options
++{
++ struct module_options *next;
++ char *modulename;
++ char *options;
++};
++
++struct module_command
++{
++ struct module_command *next;
++ char *modulename;
++ char *command;
++};
++
++struct module_alias
++{
++ struct module_alias *next;
++ char *module;
++};
++
++struct module_blacklist
++{
++ struct module_blacklist *next;
++ char *modulename;
++};
++
++/* Link in a new option line from the config file. */
++static struct module_options *
++add_options(const char *modname,
++ const char *option,
++ struct module_options *options)
++{
++ struct module_options *new;
++ char *tab;
++
++ new = NOFAIL(malloc(sizeof(*new)));
++ new->modulename = NOFAIL(strdup(modname));
++ new->options = NOFAIL(strdup(option));
++ /* We can handle tabs, kernel can't. */
++ for (tab = strchr(new->options, '\t'); tab; tab = strchr(tab, '\t'))
++ *tab = ' ';
++ new->next = options;
++ return new;
++}
++
++/* Link in a new install line from the config file. */
++static struct module_command *
++add_command(const char *modname,
++ const char *command,
++ struct module_command *commands)
++{
++ struct module_command *new;
++
++ new = NOFAIL(malloc(sizeof(*new)));
++ new->modulename = NOFAIL(strdup(modname));
++ new->command = NOFAIL(strdup(command));
++ new->next = commands;
++ return new;
++}
++
++/* Link in a new alias line from the config file. */
++static struct module_alias *
++add_alias(const char *modname, struct module_alias *aliases)
++{
++ struct module_alias *new;
++
++ new = NOFAIL(malloc(sizeof(*new)));
++ new->module = NOFAIL(strdup(modname));
++ new->next = aliases;
++ return new;
++}
++
++/* Link in a new blacklist line from the config file. */
++static struct module_blacklist *
++add_blacklist(const char *modname, struct module_blacklist *blacklist)
++{
++ struct module_blacklist *new;
++
++ new = NOFAIL(malloc(sizeof(*new)));
++ new->modulename = NOFAIL(strdup(modname));
++ new->next = blacklist;
++ return new;
++}
++
++/* Find blacklist commands if any. */
++static int
++find_blacklist(const char *modname, const struct module_blacklist *blacklist)
++{
++ while (blacklist) {
++ if (strcmp(blacklist->modulename, modname) == 0)
++ return 1;
++ blacklist = blacklist->next;
++ }
++ return 0;
++}
++
++/* return a new alias list, with backlisted elems filtered out */
++static struct module_alias *
++apply_blacklist(const struct module_alias *aliases,
++ const struct module_blacklist *blacklist)
++{
++ struct module_alias *result = NULL;
++ while (aliases) {
++ char *modname = aliases->module;
++ if (!find_blacklist(modname, blacklist))
++ result = add_alias(modname, result);
++ aliases = aliases->next;
++ }
++ return result;
++}
++
++/* Find install commands if any. */
++static const char *find_command(const char *modname,
++ const struct module_command *commands)
++{
++ while (commands) {
++ if (fnmatch(commands->modulename, modname, 0) == 0)
++ return commands->command;
++ commands = commands->next;
++ }
++ return NULL;
++}
++
++static char *append_option(char *options, const char *newoption)
++{
++ options = NOFAIL(realloc(options, strlen(options) + 1
++ + strlen(newoption) + 1));
++ if (strlen(options)) strcat(options, " ");
++ strcat(options, newoption);
++ return options;
++}
++
++/* Add to options */
++static char *add_extra_options(const char *modname,
++ char *optstring,
++ const struct module_options *options)
++{
++ while (options) {
++ if (strcmp(options->modulename, modname) == 0)
++ optstring = append_option(optstring, options->options);
++ options = options->next;
++ }
++ return optstring;
++}
++
++/* If we don't flush, then child processes print before we do */
++static void verbose_printf(int verbose, const char *fmt, ...)
++{
++ va_list arglist;
++
++ if (verbose) {
++ va_start(arglist, fmt);
++ vprintf(fmt, arglist);
++ fflush(stdout);
++ va_end(arglist);
++ }
++}
++
++/* Do an install/remove command: replace $CMDLINE_OPTS if it's specified. */
++static void do_command(const char *modname,
++ const char *command,
++ int verbose, int dry_run,
++ errfn_t error,
++ const char *type,
++ const char *cmdline_opts)
++{
++ int ret;
++ char *p, *replaced_cmd = NOFAIL(strdup(command));
++
++ while ((p = strstr(replaced_cmd, "$CMDLINE_OPTS")) != NULL) {
++ char *new;
++ asprintf(&new, "%.*s%s%s",
++ p - replaced_cmd, replaced_cmd, cmdline_opts,
++ p + strlen("$CMDLINE_OPTS"));
++ NOFAIL(new);
++ free(replaced_cmd);
++ replaced_cmd = new;
++ }
++
++ verbose_printf(verbose, "%s %s\n", type, replaced_cmd);
++ if (dry_run)
++ return;
++
++ setenv("MODPROBE_MODULE", modname, 1);
++ ret = system(replaced_cmd);
++ if (ret == -1 || WEXITSTATUS(ret))
++ error("Error running %s command for %s\n", type, modname);
++ free(replaced_cmd);
++}
++
++/* Actually do the insert. Frees second arg. */
++static void insmod(struct list_head *list,
++ char *optstring,
++ const char *newname,
++ int first_time,
++ errfn_t error,
++ int dry_run,
++ int verbose,
++ const struct module_options *options,
++ const struct module_command *commands,
++ int ignore_commands,
++ int ignore_proc,
++ int strip_vermagic,
++ int strip_modversion,
++ const char *cmdline_opts)
++{
++ int ret, fd;
++ unsigned long len;
++ void *map;
++ const char *command;
++ struct module *mod = list_entry(list->next, struct module, list);
++
++ /* Take us off the list. */
++ list_del(&mod->list);
++
++ /* Do things we (or parent) depend on first, but don't die if
++ * they fail. */
++ if (!list_empty(list)) {
++ insmod(list, NOFAIL(strdup("")), NULL, 0, warn,
++ dry_run, verbose, options, commands, 0, ignore_proc,
++ strip_vermagic, strip_modversion, cmdline_opts);
++ }
++
++ /* Lock before we look, in case it's initializing. */
++ fd = lock_file(mod->filename);
++ if (fd < 0) {
++ error("Could not open '%s': %s\n",
++ mod->filename, strerror(errno));
++ goto out_optstring;
++ }
++
++ /* Don't do ANYTHING if already in kernel. */
++ if (!ignore_proc
++ && module_in_kernel(newname ?: mod->modname, NULL) == 1) {
++ if (first_time)
++ error("Module %s already in kernel.\n",
++ newname ?: mod->modname);
++ goto out_unlock;
++ }
++
++ command = find_command(mod->modname, commands);
++ if (command && !ignore_commands) {
++ /* It might recurse: unlock. */
++ unlock_file(fd);
++ do_command(mod->modname, command, verbose, dry_run, error,
++ "install", cmdline_opts);
++ goto out_optstring;
++ }
++
++ map = grab_fd(fd, &len);
++ if (!map) {
++ error("Could not read '%s': %s\n",
++ mod->filename, strerror(errno));
++ goto out_unlock;
++ }
++
++ /* Rename it? */
++ if (newname)
++ rename_module(mod, map, len, newname);
++
++ if (strip_modversion)
++ strip_section(mod, map, len, "__versions");
++ if (strip_vermagic)
++ clear_magic(mod, map, len);
++
++ /* Config file might have given more options */
++ optstring = add_extra_options(mod->modname, optstring, options);
++
++ verbose_printf(verbose, "insmod %s %s\n", mod->filename, optstring);
++
++ if (dry_run)
++ goto out;
++
++ ret = init_module(map, len, optstring);
++ if (ret != 0) {
++ if (errno == EEXIST) {
++ if (first_time)
++ error("Module %s already in kernel.\n",
++ newname ?: mod->modname);
++ goto out_unlock;
++ }
++ error("Error inserting %s (%s): %s\n",
++ mod->modname, mod->filename, insert_moderror(errno));
++ }
++ out:
++ release_file(map, len);
++ out_unlock:
++ unlock_file(fd);
++ out_optstring:
++ free(optstring);
++ return;
++}
++
++/* Do recursive removal. */
++static void rmmod(struct list_head *list,
++ const char *name,
++ int first_time,
++ errfn_t error,
++ int dry_run,
++ int verbose,
++ struct module_command *commands,
++ int ignore_commands,
++ int ignore_inuse,
++ const char *cmdline_opts)
++{
++ const char *command;
++ unsigned int usecount = 0;
++ int lock;
++ struct module *mod = list_entry(list->next, struct module, list);
++
++ /* Take first one off the list. */
++ list_del(&mod->list);
++
++ /* Ignore failure; it's best effort here. */
++ lock = lock_file(mod->filename);
++
++ if (!name)
++ name = mod->modname;
++
++ /* Even if renamed, find commands to orig. name. */
++ command = find_command(mod->modname, commands);
++ if (command && !ignore_commands) {
++ /* It might recurse: unlock. */
++ unlock_file(lock);
++ do_command(mod->modname, command, verbose, dry_run, error,
++ "remove", cmdline_opts);
++ goto remove_rest_no_unlock;
++ }
++
++ if (module_in_kernel(name, &usecount) == 0)
++ goto nonexistent_module;
++
++ if (usecount != 0) {
++ if (!ignore_inuse)
++ error("Module %s is in use.\n", name);
++ goto remove_rest;
++ }
++
++ verbose_printf(verbose, "rmmod %s\n", mod->filename);
++
++ if (dry_run)
++ goto remove_rest;
++
++ if (delete_module(name, O_EXCL) != 0) {
++ if (errno == ENOENT)
++ goto nonexistent_module;
++ error("Error removing %s (%s): %s\n",
++ name, mod->filename,
++ remove_moderror(errno));
++ }
++
++ remove_rest:
++ unlock_file(lock);
++ remove_rest_no_unlock:
++ /* Now do things we depend. */
++ if (!list_empty(list))
++ rmmod(list, NULL, 0, warn, dry_run, verbose, commands,
++ 0, 1, cmdline_opts);
++ return;
++
++nonexistent_module:
++ if (first_time)
++ fatal("Module %s is not in kernel.\n", mod->modname);
++ goto remove_rest;
++}
++
++/* Does path contain directory(s) subpath? */
++static int type_matches(const char *path, const char *subpath)
++{
++ char *subpath_with_slashes;
++ int ret;
++
++ asprintf(&subpath_with_slashes, "/%s/", subpath);
++ NOFAIL(subpath_with_slashes);
++
++ ret = (strstr(path, subpath_with_slashes) != NULL);
++ free(subpath_with_slashes);
++ return ret;
++}
++
++static char *underscores(char *string)
++{
++ if (string) {
++ unsigned int i;
++ for (i = 0; string[i]; i++)
++ if (string[i] == '-')
++ string[i] = '_';
++ }
++ return string;
++}
++
++static int do_wildcard(const char *dirname,
++ const char *type,
++ const char *wildcard)
++{
++ char modules_dep_name[strlen(dirname) + sizeof("modules.dep") + 1];
++ char *line, *wcard;
++ FILE *modules_dep;
++
++ /* Canonicalize wildcard */
++ wcard = strdup(wildcard);
++ underscores(wcard);
++
++ sprintf(modules_dep_name, "%s/%s", dirname, "modules.dep");
++ modules_dep = fopen(modules_dep_name, "r");
++ if (!modules_dep)
++ fatal("Could not load %s: %s\n",
++ modules_dep_name, strerror(errno));
++
++ while ((line = getline_wrapped(modules_dep, NULL)) != NULL) {
++ char *ptr;
++
++ /* Ignore lines without : or which start with a # */
++ ptr = strchr(line, ':');
++ if (ptr == NULL || line[strspn(line, "\t ")] == '#')
++ goto next;
++ *ptr = '\0';
++
++ /* "type" must match complete directory component(s). */
++ if (!type || type_matches(line, type)) {
++ char modname[strlen(line)+1];
++
++ filename2modname(modname, line);
++ if (fnmatch(wcard, modname, 0) == 0)
++ printf("%s\n", line);
++ }
++ next:
++ free(line);
++ }
++
++ free(wcard);
++ return 0;
++}
++
++static char *strsep_skipspace(char **string, char *delim)
++{
++ if (!*string)
++ return NULL;
++ *string += strspn(*string, delim);
++ return strsep(string, delim);
++}
++
++/* Recursion */
++static int read_config(const char *filename,
++ const char *name,
++ int dump_only,
++ int removing,
++ struct module_options **options,
++ struct module_command **commands,
++ struct module_alias **alias,
++ struct module_blacklist **blacklist);
++
++/* FIXME: Maybe should be extended to "alias a b [and|or c]...". --RR */
++static int read_config_file(const char *filename,
++ const char *name,
++ int dump_only,
++ int removing,
++ struct module_options **options,
++ struct module_command **commands,
++ struct module_alias **aliases,
++ struct module_blacklist **blacklist)
++{
++ char *line;
++ unsigned int linenum = 0;
++ FILE *cfile;
++
++ cfile = fopen(filename, "r");
++ if (!cfile)
++ return 0;
++
++ while ((line = getline_wrapped(cfile, &linenum)) != NULL) {
++ char *ptr = line;
++ char *cmd, *modname;
++
++ if (dump_only)
++ printf("%s\n", line);
++
++ cmd = strsep_skipspace(&ptr, "\t ");
++ if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0')
++ continue;
++
++ if (strcmp(cmd, "alias") == 0) {
++ char *wildcard
++ = underscores(strsep_skipspace(&ptr, "\t "));
++ char *realname
++ = underscores(strsep_skipspace(&ptr, "\t "));
++
++ if (!wildcard || !realname)
++ grammar(cmd, filename, linenum);
++ else if (fnmatch(wildcard,name,0) == 0)
++ *aliases = add_alias(realname, *aliases);
++ } else if (strcmp(cmd, "include") == 0) {
++ struct module_alias *newalias = NULL;
++ char *newfilename;
++
++ newfilename = strsep_skipspace(&ptr, "\t ");
++ if (!newfilename)
++ grammar(cmd, filename, linenum);
++ else {
++ if (!read_config(newfilename, name,
++ dump_only, removing,
++ options, commands, &newalias,
++ blacklist))
++ warn("Failed to open included"
++ " config file %s: %s\n",
++ newfilename, strerror(errno));
++
++ /* Files included override aliases,
++ etc that was already set ... */
++ if (newalias)
++ *aliases = newalias;
++ }
++ } else if (strcmp(cmd, "options") == 0) {
++ modname = strsep_skipspace(&ptr, "\t ");
++ if (!modname || !ptr)
++ grammar(cmd, filename, linenum);
++ else {
++ ptr += strspn(ptr, "\t ");
++ *options = add_options(underscores(modname),
++ ptr, *options);
++ }
++ } else if (strcmp(cmd, "install") == 0) {
++ modname = strsep_skipspace(&ptr, "\t ");
++ if (!modname || !ptr)
++ grammar(cmd, filename, linenum);
++ else if (!removing) {
++ ptr += strspn(ptr, "\t ");
++ *commands = add_command(underscores(modname),
++ ptr, *commands);
++ }
++ } else if (strcmp(cmd, "blacklist") == 0) {
++ modname = strsep_skipspace(&ptr, "\t ");
++ if (!modname)
++ grammar(cmd, filename, linenum);
++ else if (!removing) {
++ *blacklist = add_blacklist(underscores(modname),
++ *blacklist);
++ }
++ } else if (strcmp(cmd, "remove") == 0) {
++ modname = strsep_skipspace(&ptr, "\t ");
++ if (!modname || !ptr)
++ grammar(cmd, filename, linenum);
++ else if (removing) {
++ ptr += strspn(ptr, "\t ");
++ *commands = add_command(underscores(modname),
++ ptr, *commands);
++ }
++ } else
++ grammar(cmd, filename, linenum);
++
++ free(line);
++ }
++ fclose(cfile);
++ return 1;
++}
++
++/* Simple format, ignore lines starting with #, one command per line.
++ Returns true or false. */
++static int read_config(const char *filename,
++ const char *name,
++ int dump_only,
++ int removing,
++ struct module_options **options,
++ struct module_command **commands,
++ struct module_alias **aliases,
++ struct module_blacklist **blacklist)
++{
++ DIR *dir;
++ int ret = 0;
++
++ /* ignore everything in this directory */
++ if (streq(filename, "/etc/modprobe.d/arch"))
++ return 1;
++
++ /* Reiser4 has file/directory duality: treat it as both. */
++ dir = opendir(filename);
++ if (dir) {
++ struct dirent *i;
++ while ((i = readdir(dir)) != NULL) {
++ if (!streq(i->d_name,".") && !streq(i->d_name,"..")) {
++ char sub[strlen(filename) + 1
++ + strlen(i->d_name) + 1];
++
++ sprintf(sub, "%s/%s", filename, i->d_name);
++ if (!read_config(sub, name,
++ dump_only, removing, options,
++ commands, aliases, blacklist))
++ warn("Failed to open"
++ " config file %s: %s\n",
++ sub, strerror(errno));
++ }
++ }
++ closedir(dir);
++ ret = 1;
++ }
++
++ if (read_config_file(filename, name, dump_only, removing,
++ options, commands, aliases, blacklist))
++ ret = 1;
++
++ return ret;
++}
++
++static const char *default_configs[] =
++{
++ "/etc/modprobe.conf",
++ "/etc/modprobe.d",
++};
++
++static void read_toplevel_config(const char *filename,
++ const char *name,
++ int dump_only,
++ int removing,
++ struct module_options **options,
++ struct module_command **commands,
++ struct module_alias **aliases,
++ struct module_blacklist **blacklist)
++{
++ unsigned int i;
++
++ if (filename) {
++ if (!read_config(filename, name, dump_only, removing,
++ options, commands, aliases, blacklist))
++ fatal("Failed to open config file %s: %s\n",
++ filename, strerror(errno));
++ return;
++ }
++
++ /* Try defaults. */
++ for (i = 0; i < ARRAY_SIZE(default_configs); i++) {
++ if (read_config(default_configs[i], name, dump_only, removing,
++ options, commands, aliases, blacklist))
++ return;
++ }
++}
++
++static void add_to_env_var(const char *option)
++{
++ const char *oldenv;
++
++ if ((oldenv = getenv("MODPROBE_OPTIONS")) != NULL) {
++ char *newenv;
++ asprintf(&newenv, "%s %s", oldenv, option);
++ setenv("MODPROBE_OPTIONS", newenv, 1);
++ } else
++ setenv("MODPROBE_OPTIONS", option, 1);
++}
++
++/* Prepend options from environment. */
++static char **merge_args(char *args, char *argv[], int *argc)
++{
++ char *arg, *argstring;
++ char **newargs = NULL;
++ unsigned int i, num_env = 0;
++
++ if (!args)
++ return argv;
++
++ argstring = NOFAIL(strdup(args));
++ for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) {
++ num_env++;
++ newargs = NOFAIL(realloc(newargs,
++ sizeof(newargs[0])
++ * (num_env + *argc + 1)));
++ newargs[num_env] = arg;
++ }
++
++ /* Append commandline args */
++ newargs[0] = argv[0];
++ for (i = 1; i <= *argc; i++)
++ newargs[num_env+i] = argv[i];
++
++ *argc += num_env;
++ return newargs;
++}
++
++static char *gather_options(char *argv[])
++{
++ char *optstring = NOFAIL(strdup(""));
++
++ /* Rest is module options */
++ while (*argv) {
++ /* Quote value if it contains spaces. */
++ unsigned int eq = strcspn(*argv, "=");
++
++ if (strchr(*argv+eq, ' ') && !strchr(*argv, '"')) {
++ char quoted[strlen(*argv) + 3];
++ (*argv)[eq] = '\0';
++ sprintf(quoted, "%s=\"%s\"", *argv, *argv+eq+1);
++ optstring = append_option(optstring, quoted);
++ } else
++ optstring = append_option(optstring, *argv);
++ argv++;
++ }
++ return optstring;
++}
++
++static void handle_module(const char *modname,
++ struct list_head *todo_list,
++ const char *newname,
++ int remove,
++ char *options,
++ int first_time,
++ errfn_t error,
++ int dry_run,
++ int verbose,
++ struct module_options *modoptions,
++ struct module_command *commands,
++ int ignore_commands,
++ int ignore_proc,
++ int strip_vermagic,
++ int strip_modversion,
++ int unknown_silent,
++ const char *cmdline_opts)
++{
++ if (list_empty(todo_list)) {
++ const char *command;
++
++ /* The dependencies have to be real modules, but
++ handle case where the first is completely bogus. */
++ command = find_command(modname, commands);
++ if (command && !ignore_commands) {
++ do_command(modname, command, verbose, dry_run, error,
++ remove ? "remove":"install", cmdline_opts);
++ return;
++ }
++
++ if (unknown_silent)
++ exit(1);
++ error("Module %s not found.\n", modname);
++ return;
++ }
++
++ if (remove)
++ rmmod(todo_list, newname, first_time, error, dry_run, verbose,
++ commands, ignore_commands, 0, cmdline_opts);
++ else
++ insmod(todo_list, NOFAIL(strdup(options)), newname,
++ first_time, error, dry_run, verbose, modoptions,
++ commands, ignore_commands, ignore_proc, strip_vermagic,
++ strip_modversion, cmdline_opts);
++}
++
++static struct option options[] = { { "verbose", 0, NULL, 'v' },
++ { "version", 0, NULL, 'V' },
++ { "config", 1, NULL, 'C' },
++ { "name", 1, NULL, 'o' },
++ { "remove", 0, NULL, 'r' },
++ { "showconfig", 0, NULL, 'c' },
++ { "autoclean", 0, NULL, 'k' },
++ { "quiet", 0, NULL, 'q' },
++ { "show", 0, NULL, 'n' },
++ { "dry-run", 0, NULL, 'n' },
++ { "syslog", 0, NULL, 's' },
++ { "type", 1, NULL, 't' },
++ { "list", 0, NULL, 'l' },
++ { "all", 0, NULL, 'a' },
++ { "ignore-install", 0, NULL, 'i' },
++ { "ignore-remove", 0, NULL, 'i' },
++ { "force", 0, NULL, 'f' },
++ { "force-vermagic", 0, NULL, 1 },
++ { "force-modversion", 0, NULL, 2 },
++ { "set-version", 1, NULL, 'S' },
++ { "show-depends", 0, NULL, 'D' },
++ { "first-time", 0, NULL, 3 },
++ { "use-blacklist", 0, NULL, 'b' },
++ { NULL, 0, NULL, 0 } };
++
++#define MODPROBE_DEVFSD_CONF "/etc/modprobe.devfs"
++
++/* This is a horrible hack to allow devfsd, which calls modprobe with
++ -C /etc/modules.conf or /etc/modules.devfs, to work. FIXME. */
++/* Modern devfsd or variants should use -q explicitly in 2.6. */
++static int is_devfs_call(char *argv[])
++{
++ unsigned int i;
++
++ /* Look for "/dev" arg */
++ for (i = 1; argv[i]; i++) {
++ if (strncmp(argv[i], "/dev/", 5) == 0)
++ return 1;
++ }
++ return 0;
++}
++
++int main(int argc, char *argv[])
++{
++ struct utsname buf;
++ struct stat statbuf;
++ int opt;
++ int dump_only = 0;
++ int dry_run = 0;
++ int remove = 0;
++ int verbose = 0;
++ int unknown_silent = 0;
++ int list_only = 0;
++ int all = 0;
++ int ignore_commands = 0;
++ int strip_vermagic = 0;
++ int strip_modversion = 0;
++ int ignore_proc = 0;
++ int first_time = 0;
++ int use_blacklist = 0;
++ unsigned int i, num_modules;
++ char *type = NULL;
++ const char *config = NULL;
++ char *dirname, *optstring;
++ char *newname = NULL;
++ char *aliasfilename, *symfilename;
++ errfn_t error = fatal;
++
++ /* Prepend options from environment. */
++ argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc);
++
++ /* --set-version overrides version, and disables backwards compat. */
++ for (opt = 1; opt < argc; opt++)
++ if (strncmp(argv[opt],"--set-version",strlen("--set-version"))
++ == 0)
++ break;
++
++ if (opt == argc)
++ try_old_version("modprobe", argv);
++
++ uname(&buf);
++ while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aifb", options, NULL)) != -1){
++ switch (opt) {
++ case 'v':
++ add_to_env_var("-v");
++ verbose = 1;
++ break;
++ case 'V':
++ puts("module-init-tools version 3.2.2");
++ exit(0);
++ case 'S':
++ strncpy(buf.release, optarg, sizeof(buf.release));
++ buf.release[sizeof(buf.release)-1] = '\0';
++ break;
++ case 'C':
++ if (is_devfs_call(argv)) {
++ if (streq("/etc/modules.devfs", optarg)) {
++ config = MODPROBE_DEVFSD_CONF;
++ add_to_env_var("-C");
++ add_to_env_var(config);
++ /* Fall thru to -q */
++ } else if (streq("/etc/modules.conf", optarg))
++ /* Ignore config, fall thru to -q */
++ ;
++ else {
++ /* False alarm. Treat as normal. */
++ config = optarg;
++ add_to_env_var("-C");
++ add_to_env_var(config);
++ break;
++ }
++ } else {
++ config = optarg;
++ add_to_env_var("-C");
++ add_to_env_var(config);
++ break;
++ }
++ case 'q':
++ unknown_silent = 1;
++ add_to_env_var("-q");
++ break;
++ case 'D':
++ dry_run = 1;
++ ignore_proc = 1;
++ verbose = 1;
++ add_to_env_var("-D");
++ break;
++ case 'o':
++ newname = optarg;
++ break;
++ case 'r':
++ remove = 1;
++ break;
++ case 'c':
++ dump_only = 1;
++ break;
++ case 't':
++ type = optarg;
++ break;
++ case 'l':
++ list_only = 1;
++ break;
++ case 'a':
++ all = 1;
++ error = warn;
++ break;
++ case 'k':
++ /* FIXME: This should actually do something */
++ break;
++ case 'n':
++ dry_run = 1;
++ break;
++ case 's':
++ add_to_env_var("-s");
++ log = 1;
++ break;
++ case 'i':
++ ignore_commands = 1;
++ break;
++ case 'f':
++ strip_vermagic = 1;
++ strip_modversion = 1;
++ break;
++ case 'b':
++ use_blacklist = 1;
++ break;
++ case 1:
++ strip_vermagic = 1;
++ break;
++ case 2:
++ strip_modversion = 1;
++ break;
++ case 3:
++ first_time = 1;
++ break;
++ default:
++ print_usage(argv[0]);
++ }
++ }
++
++ /* If stderr not open, go to syslog */
++ if (log || fstat(STDERR_FILENO, &statbuf) != 0) {
++ openlog("modprobe", LOG_CONS, LOG_DAEMON);
++ log = 1;
++ }
++
++ if (argc < optind + 1 && !dump_only && !list_only && !remove)
++ print_usage(argv[0]);
++
++ dirname = NOFAIL(malloc(strlen(buf.release) + sizeof(MODULE_DIR) + 1));
++ sprintf(dirname, "%s/%s", MODULE_DIR, buf.release);
++ aliasfilename = NOFAIL(malloc(strlen(dirname)
++ + sizeof("/modules.alias")));
++ sprintf(aliasfilename, "%s/modules.alias", dirname);
++ symfilename = NOFAIL(malloc(strlen(dirname)
++ + sizeof("/modules.symbols")));
++ sprintf(symfilename, "%s/modules.symbols", dirname);
++
++ /* Old-style -t xxx wildcard? Only with -l. */
++ if (list_only) {
++ if (optind+1 < argc)
++ fatal("Can't have multiple wildcards\n");
++ /* fprintf(stderr, "man find\n"); return 1; */
++ return do_wildcard(dirname, type, argv[optind]?:"*");
++ }
++ if (type)
++ fatal("-t only supported with -l");
++
++ if (dump_only) {
++ struct module_command *commands = NULL;
++ struct module_options *modoptions = NULL;
++ struct module_alias *aliases = NULL;
++ struct module_blacklist *blacklist = NULL;
++
++ read_toplevel_config(config, "", 1, 0,
++ &modoptions, &commands, &aliases, &blacklist);
++ read_config(aliasfilename, "", 1, 0,&modoptions, &commands,
++ &aliases, &blacklist);
++ read_config(symfilename, "", 1, 0, &modoptions, &commands,
++ &aliases, &blacklist);
++ exit(0);
++ }
++
++ if (remove || all) {
++ num_modules = argc - optind;
++ optstring = NOFAIL(strdup(""));
++ } else {
++ num_modules = 1;
++ optstring = gather_options(argv+optind+1);
++ }
++
++ /* num_modules is always 1 except for -r or -a. */
++ for (i = 0; i < num_modules; i++) {
++ struct module_command *commands = NULL;
++ struct module_options *modoptions = NULL;
++ struct module_alias *aliases = NULL;
++ struct module_blacklist *blacklist = NULL;
++ LIST_HEAD(list);
++ char *modulearg = argv[optind + i];
++
++ /* Convert name we are looking for */
++ underscores(modulearg);
++
++ /* Returns the resolved alias, options */
++ read_toplevel_config(config, modulearg, 0,
++ remove, &modoptions, &commands, &aliases, &blacklist);
++
++ /* No luck? Try symbol names, if starts with symbol:. */
++ if (!aliases
++ && strncmp(modulearg, "symbol:", strlen("symbol:")) == 0)
++ read_config(symfilename, modulearg, 0,
++ remove, &modoptions, &commands,
++ &aliases, &blacklist);
++
++ if (!aliases) {
++ /* We only use canned aliases as last resort. */
++ read_depends(dirname, modulearg, &list);
++
++ if (list_empty(&list)
++ && !find_command(modulearg, commands))
++ {
++ read_config(aliasfilename, modulearg, 0,
++ remove, &modoptions, &commands,
++ &aliases, &blacklist);
++ aliases = apply_blacklist(aliases, blacklist);
++ }
++ }
++
++ if (aliases) {
++ errfn_t err = error;
++
++ /* More than one alias? Don't bail out on failure. */
++ if (aliases->next)
++ err = warn;
++ while (aliases) {
++ /* Add the options for this alias. */
++ char *opts = NOFAIL(strdup(optstring));
++ opts = add_extra_options(modulearg,
++ opts, modoptions);
++
++ read_depends(dirname, aliases->module, &list);
++ handle_module(aliases->module, &list, newname,
++ remove, opts, first_time, err,
++ dry_run, verbose, modoptions,
++ commands, ignore_commands,
++ ignore_proc, strip_vermagic,
++ strip_modversion,
++ unknown_silent,
++ optstring);
++
++ aliases = aliases->next;
++ INIT_LIST_HEAD(&list);
++ }
++ } else {
++ if (use_blacklist
++ && find_blacklist(modulearg, blacklist))
++ continue;
++
++ handle_module(modulearg, &list, newname, remove,
++ optstring, first_time, error, dry_run,
++ verbose, modoptions, commands,
++ ignore_commands, ignore_proc,
++ strip_vermagic, strip_modversion,
++ unknown_silent, optstring);
++ }
++ }
++ if (log)
++ closelog();
++
++ return 0;
++}
diff --git a/packages/klibc/klibc-common.inc b/packages/klibc/klibc-common.inc
index 7b23ece856..41859d3243 100644
--- a/packages/klibc/klibc-common.inc
+++ b/packages/klibc/klibc-common.inc
@@ -6,6 +6,8 @@ minimal entaglement, and portability, not speed."
LICENSE = "BSD-ADV"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/libs/klibc/Stable/klibc-${PV}.tar.bz2 \
file://fstype-sane-vfat-and-jffs2-for-1.5.patch;patch=1 \
+ file://modprobe.patch;patch=1 \
+ file://losetup.patch;patch=1 \
"
S = "${WORKDIR}/klibc-${PV}"
PACKAGE_ARCH = "${MACHINE_ARCH}"
diff --git a/packages/klibc/klibc-utils-fstype-static_1.1.1.bb b/packages/klibc/klibc-utils-fstype-static_1.1.1.bb
deleted file mode 100644
index 2bcc0f6085..0000000000
--- a/packages/klibc/klibc-utils-fstype-static_1.1.1.bb
+++ /dev/null
@@ -1,14 +0,0 @@
-SRC_URI = "${KERNELORG_MIRROR}/pub/linux/libs/klibc/Stable/klibc-${PV}.tar.bz2"
-SRC_URI += "file://fstype-sane-and-vfat-jffs2.patch;patch=1"
-PR = "r1"
-
-S = "${WORKDIR}/klibc-${PV}"
-
-do_compile() {
- ${CC} -o fstype utils/fstype.c -static
-}
-
-do_install () {
- install -d ${D}${bindir}
- install -m 0755 fstype ${D}${bindir}/
-}
diff --git a/packages/klibc/klibc-utils-static_1.5.bb b/packages/klibc/klibc-utils-static_1.5.bb
index 6d7a199967..c6f54489ab 100644
--- a/packages/klibc/klibc-utils-static_1.5.bb
+++ b/packages/klibc/klibc-utils-static_1.5.bb
@@ -1,6 +1,6 @@
require klibc-common.inc
-PR = "r7"
+PR = "r8"
# We only want the static utils. klibc build both. So we install only what we want.
do_install() {
@@ -36,6 +36,8 @@ do_install() {
install -m 755 usr/utils/static/true ${D}${base_bindir}
install -m 755 usr/utils/static/umount ${D}${base_bindir}
install -m 755 usr/utils/static/uname ${D}${base_bindir}
+ install -m 755 usr/utils/static/modprobe ${D}${base_bindir}
+ install -m 755 usr/utils/static/losetup ${D}${base_bindir}
cd ${D}${base_bindir}
ln -s gzip gunzip
ln -s gzip zcat
@@ -57,8 +59,8 @@ PACKAGES = "klibc-utils-static-sh klibc-utils-static-gzip \
klibc-utils-static-poweroff klibc-utils-static-readlink \
klibc-utils-static-reboot klibc-utils-static-sleep \
klibc-utils-static-true klibc-utils-static-umount \
- klibc-utils-static-uname \
- "
+ klibc-utils-static-uname klibc-utils-static-modprobe \
+ klibc-utils-static-losetup"
FILES_klibc-utils-static-sh = "${base_bindir}/sh"
FILES_klibc-utils-static-gzip = "${base_bindir}/gzip ${base_bindir}/gunzip ${base_bindir}/zcat"
@@ -91,3 +93,5 @@ FILES_klibc-utils-static-sleep = "${base_bindir}/sleep"
FILES_klibc-utils-static-true = "${base_bindir}/true"
FILES_klibc-utils-static-umount = "${base_bindir}/umount"
FILES_klibc-utils-static-uname = "${base_bindir}/uname"
+FILES_klibc-utils-static-modprobe = "${base_bindir}/modprobe"
+FILES_klibc-utils-static-losetup = "${base_bindir}/losetup"
diff --git a/packages/klibc/klibc.inc b/packages/klibc/klibc.inc
index 78e1bca125..c32111af37 100644
--- a/packages/klibc/klibc.inc
+++ b/packages/klibc/klibc.inc
@@ -38,6 +38,8 @@ do_install() {
install -m 755 usr/utils/shared/true ${D}${base_bindir}
install -m 755 usr/utils/shared/umount ${D}${base_bindir}
install -m 755 usr/utils/shared/uname ${D}${base_bindir}
+ install -m 755 usr/utils/shared/modprobe ${D}${base_bindir}
+ install -m 755 usr/utils/shared/losetup ${D}${base_bindir}
install -d ${D}${base_libdir}
install -m 755 usr/klibc/klibc-*.so ${D}${base_libdir}
@@ -71,11 +73,12 @@ PACKAGES = "${PN} klibc-utils-sh klibc-utils-kinit \
klibc-utils-readlink klibc-utils-reboot \
klibc-utils-sleep klibc-utils-true \
klibc-utils-umount klibc-utils-uname \
- klibc-utils-gzip"
+ klibc-utils-gzip klibc-utils-modprobe \
+ klibc-utils-losetup"
FILES_${PN} = "${base_libdir}/klibc*.so"
FILES_klibc-utils-sh = "${base_bindir}/sh"
-FILES_klibc-utils-static-gzip = "${base_bindir}/gzip ${base_bindir}/gunzip ${base_bindir}/zcat"
+FILES_klibc-utils-gzip = "${base_bindir}/gzip ${base_bindir}/gunzip ${base_bindir}/zcat"
FILES_klibc-utils-kinit = "${base_bindir}/kinit"
FILES_klibc-utils-fstype = "${base_bindir}/fstype"
FILES_klibc-utils-ipconfig = "${base_bindir}/ipconfig"
@@ -105,6 +108,8 @@ FILES_klibc-utils-sleep = "${base_bindir}/sleep"
FILES_klibc-utils-true = "${base_bindir}/true"
FILES_klibc-utils-umount = "${base_bindir}/umount"
FILES_klibc-utils-uname = "${base_bindir}/uname"
+FILES_klibc-utils-modprobe = "${base_bindir}/modprobe"
+FILES_klibc-utils-losetup = "${base_bindir}/losetup"
# Yes we want exactly the klibc that was compiled with the utils
RDEPENDS_klibc-utils-sh = "${PN} (=${PV}-${PR})"
@@ -137,3 +142,5 @@ RDEPENDS_klibc-utils-sleep = "${PN} (=${PV}-${PR})"
RDEPENDS_klibc-utils-true = "${PN} (=${PV}-${PR})"
RDEPENDS_klibc-utils-umount = "${PN} (=${PV}-${PR})"
RDEPENDS_klibc-utils-uname = "${PN} (=${PV}-${PR})"
+RDEPENDS_klibc-utils-modprobe = "${PN} (=${PV}-${PR})"
+RDEPENDS_klibc-utils-losetup = "${PN} (=${PV}-${PR})"
diff --git a/packages/klibc/klibc_1.5.bb b/packages/klibc/klibc_1.5.bb
index b5bd3557cf..925dcd0c36 100644
--- a/packages/klibc/klibc_1.5.bb
+++ b/packages/klibc/klibc_1.5.bb
@@ -1,2 +1,2 @@
require klibc.inc
-PR = "r5"
+PR = "r6"
diff --git a/packages/less/less_382.bb b/packages/less/less_382.bb
deleted file mode 100644
index f336a59ad6..0000000000
--- a/packages/less/less_382.bb
+++ /dev/null
@@ -1,22 +0,0 @@
-DESCRIPTION = "Less is a program similar to more, i.e. a terminal \
-based program for viewing text files and the output from other \
-programs. Less offers many features beyond those that more does."
-HOMEPAGE = "http://www.greenwoodsoftware.com/"
-SECTION = "console/utils"
-LICENSE = "BSD"
-DEPENDS = "ncurses"
-PR = "r1"
-
-SRC_URI = "${GNU_MIRROR}/less/less-${PV}.tar.gz \
- file://configure.patch;patch=1"
-
-inherit autotools update-alternatives
-
-do_install () {
- oe_runmake 'bindir=${D}${bindir}' 'mandir=${D}${mandir}' install
- mv ${D}${bindir}/less ${D}${bindir}/less.${PN}
-}
-
-ALTERNATIVE_NAME = "less"
-ALTERNATIVE_PATH = "less.${PN}"
-ALTERNATIVE_PRIORITY = "100"
diff --git a/packages/less/less_406.bb b/packages/less/less_418.bb
index c8ef2fc6e6..c19a41e63d 100644
--- a/packages/less/less_406.bb
+++ b/packages/less/less_418.bb
@@ -6,7 +6,7 @@ SECTION = "console/utils"
LICENSE = "BSD"
DEPENDS = "ncurses"
-SRC_URI = "http://www.greenwoodsoftware.com/less/less-406.tar.gz "
+SRC_URI = "${GNU_MIRROR}/less/less-${PV}.tar.gz "
inherit autotools update-alternatives
diff --git a/packages/libgee/.mtn2git_empty b/packages/libgee/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/libgee/.mtn2git_empty
diff --git a/packages/libgee/files/.mtn2git_empty b/packages/libgee/files/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/libgee/files/.mtn2git_empty
diff --git a/packages/libgee/files/no-tests.patch b/packages/libgee/files/no-tests.patch
new file mode 100644
index 0000000000..d2d20b2c4e
--- /dev/null
+++ b/packages/libgee/files/no-tests.patch
@@ -0,0 +1,12 @@
+Index: libgee-0.1.2/Makefile.am
+===================================================================
+--- libgee-0.1.2.orig/Makefile.am
++++ libgee-0.1.2/Makefile.am
+@@ -4,7 +4,6 @@ NULL =
+
+ SUBDIRS = \
+ gee \
+- tests \
+ $(NULL)
+
+ pkgconfigdir = $(libdir)/pkgconfig
diff --git a/packages/libgee/libgee_0.1.2.bb b/packages/libgee/libgee_0.1.2.bb
new file mode 100644
index 0000000000..4f6d113150
--- /dev/null
+++ b/packages/libgee/libgee_0.1.2.bb
@@ -0,0 +1,12 @@
+DESCRIPTION = "libgee is a collection library providing GObject-based interfaces \
+and classes for commonly used data structures."
+HOMEPAGE = "http://live.gnome.org/Libgee"
+SECTION = "libs"
+DEPENDS = "glib-2.0"
+LICENSE = "LGPL"
+
+SRC_URI = "ftp://ftp.gnome.org/pub/GNOME/sources/libgee/0.1/libgee-${PV}.tar.bz2 \
+ file://no-tests.patch;patch=1"
+
+inherit autotools pkgconfig
+
diff --git a/packages/linux/gumstix-linux.inc b/packages/linux/gumstix-linux.inc
index 50111cb545..038089c965 100644
--- a/packages/linux/gumstix-linux.inc
+++ b/packages/linux/gumstix-linux.inc
@@ -35,16 +35,6 @@ do_configure_prepend() {
yes '' | oe_runmake oldconfig
}
-do_sizecheck() {
- if [ ! -z "${KERNEL_IMAGE_MAXSIZE}" ]; then
- size=`ls -l arch/${ARCH}/boot/${KERNEL_IMAGETYPE} | awk '{ print $5}'`
- if [ $size -ge ${KERNEL_IMAGE_MAXSIZE} ]; then
- rm arch/${ARCH}/boot/${KERNEL_IMAGETYPE}
- die "This kernel (size=$size) is too big for your device. Please reduce the size of the kernel by making more of it modular."
- fi
- fi
-}
-
do_install_prepend() {
if test -e arch/${ARCH}/boot/Image ; then
ln -f arch/${ARCH}/boot/Image arch/${ARCH}/boot/uImage
@@ -68,7 +58,4 @@ do_deploy() {
fi
}
-addtask sizecheck before do_install after do_compile
addtask deploy before do_package after do_install
-
-
diff --git a/packages/linux/linux-handhelds-2.6-2.6.21/keep-initramfs.patch b/packages/linux/linux-handhelds-2.6-2.6.21/keep-initramfs.patch
new file mode 100644
index 0000000000..b503a6326a
--- /dev/null
+++ b/packages/linux/linux-handhelds-2.6-2.6.21/keep-initramfs.patch
@@ -0,0 +1,11 @@
+--- /tmp/Makefile 2008-03-08 11:13:58.939360172 +0100
++++ kernel26/usr/Makefile 2008-03-08 11:14:03.270190232 +0100
+@@ -34,7 +34,7 @@
+ endif
+
+ quiet_cmd_initfs = GEN $@
+- cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input)
++ cmd_initfs = echo
+
+ targets := initramfs_data.cpio.gz
+ # do not try to update files included in initramfs
diff --git a/packages/linux/linux-handhelds-2.6.inc b/packages/linux/linux-handhelds-2.6.inc
index 3bd9f78ea2..9a783aa6de 100644
--- a/packages/linux/linux-handhelds-2.6.inc
+++ b/packages/linux/linux-handhelds-2.6.inc
@@ -55,7 +55,9 @@ do_configure() {
}
do_compile_prepend() {
- if [ -n "${KERNEL_INITRAMFS_PATH}" -a "${ANGSTROM_MODE}" == "glibc" ]; then
+ # Clean up any stale initramfs archive
+ rm -f usr/initramfs_data.cpio.gz
+ if [ -n "${KERNEL_INITRAMFS_PATH}" -a "${ANGSTROM_MODE}" = "glibc" ]; then
if [ ! -f ${KERNEL_INITRAMFS_PATH} ]; then
echo "${KERNEL_INITRAMFS_PATH} does not exist, you may need to bitbake it separately"
exit 1
diff --git a/packages/linux/linux-handhelds-2.6_2.6.21-hh20.bb b/packages/linux/linux-handhelds-2.6_2.6.21-hh20.bb
index 066c17faed..5c524c7ea6 100644
--- a/packages/linux/linux-handhelds-2.6_2.6.21-hh20.bb
+++ b/packages/linux/linux-handhelds-2.6_2.6.21-hh20.bb
@@ -1,7 +1,7 @@
SECTION = "kernel"
DESCRIPTION = "handhelds.org Linux kernel 2.6 for PocketPCs and other consumer handheld devices."
LICENSE = "GPL"
-PR = "r14"
+PR = "r17"
DEFAULT_PREFERENCE = "-1"
@@ -12,6 +12,7 @@ FILESPATH = "${FILE_DIRNAME}/linux-handhelds-2.6-2.6.21/${MACHINE}:${FILE_DIRNAM
SRC_URI = "${HANDHELDS_CVS};module=linux/kernel26;tag=${@'K' + bb.data.getVar('PV',d,1).replace('.', '-')} \
file://linux-2.6.git-9d20fdd58e74d4d26dc5216efaaa0f800c23dd3a.patch;patch=1 \
http://www.rpsys.net/openzaurus/patches/archive/export_atags-r0a.patch;patch=1 \
- file://defconfig"
+ file://keep-initramfs.patch;patch=1 \
+ file://defconfig"
require linux-handhelds-2.6.inc
diff --git a/packages/linux/linux-rp-2.6.24/defconfig-tosa b/packages/linux/linux-rp-2.6.24/defconfig-tosa
new file mode 100644
index 0000000000..34f0cc1210
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/defconfig-tosa
@@ -0,0 +1,1728 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+# Mon Feb 25 01:57:38 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_HAVE_CLOCK_LIB=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=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_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=m
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_IOSCHED_CFQ=m
+# 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"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_PNX4008 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+CONFIG_DMABOUNCE=y
+
+#
+# Intel PXA2xx/PXA3xx Implementations
+#
+# CONFIG_ARCH_LUBBOCK is not set
+# CONFIG_MACH_LOGICPD_PXA270 is not set
+# CONFIG_MACH_MAINSTONE is not set
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_PXA_SHARPSL=y
+# CONFIG_MACH_TRIZEPS4 is not set
+# CONFIG_MACH_HX2750 is not set
+# CONFIG_MACH_EM_X270 is not set
+# CONFIG_MACH_ZYLONITE is not set
+# CONFIG_MACH_ARMCORE is not set
+CONFIG_PXA_SHARPSL_25x=y
+# CONFIG_PXA_SHARPSL_27x is not set
+# CONFIG_MACH_HTCUNIVERSAL is not set
+# CONFIG_MACH_POODLE is not set
+# CONFIG_MACH_CORGI is not set
+# CONFIG_MACH_SHEPHERD is not set
+# CONFIG_MACH_HUSKY is not set
+CONFIG_MACH_TOSA=y
+CONFIG_PXA25x=y
+CONFIG_PXA_SSP=y
+# CONFIG_PXA_KEYS is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_XSCALE=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5T=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_OUTER_CACHE is not set
+# CONFIG_IWMMXT is not set
+CONFIG_XSCALE_PMU=y
+CONFIG_SHARP_PARAM=y
+CONFIG_SHARP_SCOOP=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_PXA2XX=y
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 dyntick=enable debug"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+CONFIG_CPU_FREQ_PXA25x=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=m
+# CONFIG_CPU_FREQ_STAT_DETAILS is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=m
+CONFIG_CPU_FREQ_GOV_ONDEMAND=m
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND_UP_POSSIBLE=y
+CONFIG_SUSPEND=y
+CONFIG_APM_EMULATION=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_IPRANGE=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_MATCH_ADDRTYPE=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES 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_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRNET=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# Old SIR device drivers
+#
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Old Serial dongle support
+#
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+CONFIG_PXA_FICP=m
+# CONFIG_MCS_FIR is not set
+CONFIG_BT=m
+CONFIG_BT_L2CAP=m
+CONFIG_BT_SCO=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+# CONFIG_BT_HCIUSB_SCO is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
+CONFIG_BT_HCIVHCI=m
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=m
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=m
+CONFIG_IEEE80211_CRYPT_CCMP=m
+CONFIG_IEEE80211_CRYPT_TKIP=m
+# CONFIG_IEEE80211_SOFTMAC 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_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_SHARP_SL=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_VERIFY_WRITE=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_H1900 is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_SHARPSL is not set
+CONFIG_MTD_NAND_TMIO=y
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_IDE_GENERIC is not set
+# CONFIG_BLK_DEV_PLATFORM is not set
+# CONFIG_IDE_ARM is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+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=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_EMC=m
+# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
+# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_AX8817X=m
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_POWER is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_CORGI is not set
+# CONFIG_KEYBOARD_SPITZ is not set
+CONFIG_KEYBOARD_TOSA=y
+# CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_CORGI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+CONFIG_TOUCHSCREEN_WM97XX=y
+# CONFIG_TOUCHSCREEN_WM9705 is not set
+CONFIG_TOUCHSCREEN_WM9712=y
+# CONFIG_TOUCHSCREEN_WM9713 is not set
+# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
+CONFIG_TOUCHSCREEN_WM97XX_TOSA=y
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=m
+CONFIG_SERIAL_8250_CS=m
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_PXA=y
+CONFIG_SERIAL_PXA_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=m
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 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 is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_GPIO is not set
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 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
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+CONFIG_HAVE_GPIO_LIB=y
+
+#
+# GPIO Support
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+CONFIG_PDA_POWER=y
+CONFIG_APM_POWER=y
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_BATTERY_TOSA=y
+# CONFIG_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=y
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+CONFIG_MFD_TC6393XB=y
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_ASIC3 is not set
+# CONFIG_HTC_ASIC3_DS1WM is not set
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+CONFIG_RADIO_ADAPTERS=y
+CONFIG_USB_DSBR=m
+# CONFIG_DVB_CORE is not set
+CONFIG_DAB=y
+CONFIG_USB_DABUSB=m
+
+#
+# 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=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# 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_SYS_FOPS is not set
+# CONFIG_FB_DEFERRED_IO 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_PXA is not set
+# CONFIG_FB_MBX is not set
+# CONFIG_FB_W100 is not set
+CONFIG_FB_TMIO=y
+CONFIG_FB_TMIO_ACCELL=y
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_TOSA=y
+
+#
+# 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=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_DUMMY=m
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_PXA2XX_AC97 is not set
+
+#
+# USB devices
+#
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC=y
+CONFIG_SND_PXA2XX_SOC=y
+CONFIG_SND_PXA2XX_SOC_AC97=y
+CONFIG_SND_PXA2XX_SOC_TOSA=y
+
+#
+# SoC Audio support for SuperH
+#
+CONFIG_SND_SOC_WM9712=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_PERSIST is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_SL811_HCD=m
+CONFIG_USB_SL811_CS=m
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+CONFIG_USB_SERIAL_BELKIN=m
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+# CONFIG_USB_SERIAL_CP2101 is not set
+CONFIG_USB_SERIAL_CYPRESS_M8=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+CONFIG_USB_SERIAL_VISOR=m
+CONFIG_USB_SERIAL_IPAQ=m
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_EDGEPORT_TI=m
+CONFIG_USB_SERIAL_GARMIN=m
+CONFIG_USB_SERIAL_IPW=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_MPR is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49WLC is not set
+CONFIG_USB_SERIAL_KLSI=m
+CONFIG_USB_SERIAL_KOBIL_SCT=m
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+CONFIG_USB_SERIAL_SAFE=m
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+CONFIG_USB_SERIAL_TI=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+# CONFIG_USB_SERIAL_OPTION is not set
+CONFIG_USB_SERIAL_OMNINET=m
+# CONFIG_USB_SERIAL_DEBUG is not set
+CONFIG_USB_EZUSB=y
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+CONFIG_USB_CYTHERM=m
+# CONFIG_USB_PHIDGET is not set
+CONFIG_USB_IDMOUSE=m
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+CONFIG_USB_GADGET_PXA2XX=y
+CONFIG_USB_PXA2XX=m
+# CONFIG_USB_PXA2XX_SMALL is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+CONFIG_MMC_PXA=y
+# CONFIG_MMC_TMIO is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_TOSA=y
+# CONFIG_LEDS_GPIO is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_SA1100=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=m
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS 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_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_SYSFS is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_BIND34 is not set
+CONFIG_RPCSEC_GSS_KRB5=m
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMB_NLS_REMOTE="cp437"
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+# CONFIG_INSTRUMENTATION is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
+CONFIG_CRYPTO_TEST=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/packages/linux/linux-rp-2.6.24/htcuni.patch b/packages/linux/linux-rp-2.6.24/htcuni.patch
index f462650566..aa08ca4691 100644
--- a/packages/linux/linux-rp-2.6.24/htcuni.patch
+++ b/packages/linux/linux-rp-2.6.24/htcuni.patch
@@ -57,10 +57,10 @@
include/linux/soc/tmio_mmc.h | 17
56 files changed, 7469 insertions(+), 1 deletion(-)
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/Makefile
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/Makefile 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/Makefile 2008-02-24 02:40:56.640036018 +0300
@@ -0,0 +1,19 @@
+#
+# Makefile for HTC Universal
@@ -81,10 +81,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/Makefile
+obj-$(CONFIG_HTCUNIVERSAL_UDC) += htcuniversal_udc.o
+
+obj-$(CONFIG_HTCUNIVERSAL_AK4641) += htcuniversal_ak4641.o
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,468 @@
+/*
+ * Hardware definitions for HTC Universal
@@ -554,10 +554,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal.c
+ .init_machine = htcuniversal_init,
+ .timer = &pxa_timer,
+MACHINE_END
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,917 @@
+/*
+ * Audio support for codec Asahi Kasei AK4641
@@ -1476,10 +1476,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c
+MODULE_LICENSE("GPL");
+
+/* end {{ Module }} */
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,65 @@
+/*
+ * Audio support for codec Asahi Kasei AK4641
@@ -1546,10 +1546,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h
+void snd_ak4641_hp_detected(struct snd_ak4641 *ak, int detected); /* atomic context */
+
+#endif /* __SOUND_AK4641_H */
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,143 @@
+/*
+ * LEDs support for the HP iPaq hx4700
@@ -1694,10 +1694,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c
+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
+MODULE_DESCRIPTION("htcuniversal LEDs driver");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,61 @@
+/*
+ * Use consistent with the GNU GPL is permitted,
@@ -1760,10 +1760,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c
+MODULE_AUTHOR("Paul Sokolovsky <pmiscml@gmail.com>");
+MODULE_DESCRIPTION("Backlight driver for HTC Universal");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,135 @@
+/* Bluetooth interface driver for TI BRF6150 on HX4700
+ *
@@ -1900,10 +1900,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c
+
+/* vim600: set noexpandtab sw=8 ts=8 :*/
+
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,17 @@
+/*
+ * Bluetooth support file for calling bluetooth configuration functions
@@ -1922,10 +1922,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h
+
+
+#endif
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c 2008-02-24 02:40:56.644036684 +0300
@@ -0,0 +1,87 @@
+/*
+ * Buttons driver for HTC Universal
@@ -2014,10 +2014,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c
+MODULE_AUTHOR ("Joshua Wise, Pawel Kolodziejski, Paul Sokolosvky");
+MODULE_DESCRIPTION ("Buttons support for HTC Universal");
+MODULE_LICENSE ("GPL");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,226 @@
+/* Core Hardware driver for Hx4700 (Serial, ASIC3, EGPIOs)
+ *
@@ -2245,10 +2245,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c
+MODULE_LICENSE("GPL");
+
+/* vim600: set noexpandtab sw=8 ts=8 :*/
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,212 @@
+/*
+ * Use consistent with the GNU GPL is permitted,
@@ -2462,10 +2462,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c
+MODULE_DESCRIPTION("Framebuffer driver for HTC Universal");
+MODULE_LICENSE("GPL");
+
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,167 @@
+
+/* Phone interface driver for Qualcomm MSM6250 on HTC Universal
@@ -2634,10 +2634,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c
+MODULE_LICENSE("GPL");
+
+/* vim600: set noexpandtab sw=8 ts=8 :*/
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,16 @@
+/*
+ * Bluetooth support file for calling bluetooth configuration functions
@@ -2655,10 +2655,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h
+};
+
+#endif
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,69 @@
+/*
+ * MyPal 716 power management support for the original HTC IPL in DoC G3
@@ -2729,10 +2729,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c
+ pxa_pm_set_ll_ops(&htcuniversal_ll_pm_ops);
+}
+#endif /* CONFIG_PM */
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,97 @@
+/*
+ * pda_power driver for HTC Universal
@@ -2831,10 +2831,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c
+
+MODULE_DESCRIPTION("Power driver for HTC Universal");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,490 @@
+/* Touch screen driver for the TI something-or-other
+ *
@@ -3326,10 +3326,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
+MODULE_DESCRIPTION("HTC Universal Touch Screen Driver");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,71 @@
+
+/*
@@ -3402,10 +3402,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c
+
+module_init(htcuniversal_udc_init);
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h
+Index: linux-2.6.24/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h 2008-02-24 02:40:56.648035744 +0300
@@ -0,0 +1,20 @@
+/*
+ * temporary TSC2046 touchscreen hack
@@ -3427,13 +3427,13 @@ Index: linux-2.6.23/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h
+#define TSC2046_SAMPLE_Y 0x90
+
+#endif
-Index: linux-2.6.23/arch/arm/mach-pxa/Kconfig
+Index: linux-2.6.24/arch/arm/mach-pxa/Kconfig
===================================================================
---- linux-2.6.23.orig/arch/arm/mach-pxa/Kconfig 2008-01-20 18:59:41.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/Kconfig 2008-01-20 18:59:46.000000000 +0000
-@@ -92,6 +92,14 @@ config MACH_HX2750
- help
- This enables support for the HP iPAQ HX2750 handheld.
+--- linux-2.6.24.orig/arch/arm/mach-pxa/Kconfig 2008-02-24 02:40:23.789035215 +0300
++++ linux-2.6.24/arch/arm/mach-pxa/Kconfig 2008-02-24 02:40:56.652035294 +0300
+@@ -92,6 +92,14 @@ config PXA_SHARPSL_27x
+ bool "Sharp PXA270 models (SL-Cxx00)"
+ select PXA27x
+config MACH_HTCUNIVERSAL
+ bool "HTC Universal"
@@ -3538,22 +3538,22 @@ Index: linux-2.6.23/arch/arm/mach-pxa/Kconfig
endif
-
-Index: linux-2.6.23/arch/arm/mach-pxa/Makefile
+Index: linux-2.6.24/arch/arm/mach-pxa/Makefile
===================================================================
---- linux-2.6.23.orig/arch/arm/mach-pxa/Makefile 2008-01-20 18:59:41.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/Makefile 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/arch/arm/mach-pxa/Makefile 2008-02-24 02:40:23.797034872 +0300
++++ linux-2.6.24/arch/arm/mach-pxa/Makefile 2008-02-24 02:40:56.652035294 +0300
@@ -23,6 +23,7 @@ obj-$(CONFIG_MACH_POODLE) += poodle.o co
- obj-$(CONFIG_MACH_TOSA) += tosa.o
+ obj-$(CONFIG_MACH_TOSA) += tosa.o tosa_power.o
obj-$(CONFIG_MACH_EM_X270) += em-x270.o
obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
+obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal/
ifeq ($(CONFIG_MACH_ZYLONITE),y)
obj-y += zylonite.o
-Index: linux-2.6.23/drivers/leds/Kconfig
+Index: linux-2.6.24/drivers/leds/Kconfig
===================================================================
---- linux-2.6.23.orig/drivers/leds/Kconfig 2008-01-20 18:59:17.000000000 +0000
-+++ linux-2.6.23/drivers/leds/Kconfig 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/drivers/leds/Kconfig 2008-02-24 02:40:23.817034852 +0300
++++ linux-2.6.24/drivers/leds/Kconfig 2008-02-24 02:40:56.652035294 +0300
@@ -114,6 +114,13 @@ config LEDS_CM_X270
help
This option enables support for the CM-X270 LEDs.
@@ -3568,10 +3568,10 @@ Index: linux-2.6.23/drivers/leds/Kconfig
comment "LED Triggers"
config LEDS_TRIGGERS
-Index: linux-2.6.23/drivers/leds/leds-asic3.c
+Index: linux-2.6.24/drivers/leds/leds-asic3.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/leds/leds-asic3.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/leds/leds-asic3.c 2008-02-24 02:40:56.652035294 +0300
@@ -0,0 +1,189 @@
+/*
+ * LEDs support for HTC ASIC3 devices.
@@ -3762,11 +3762,11 @@ Index: linux-2.6.23/drivers/leds/leds-asic3.c
+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
+MODULE_DESCRIPTION("HTC ASIC3 LEDs driver");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/drivers/mfd/Kconfig
+Index: linux-2.6.24/drivers/mfd/Kconfig
===================================================================
---- linux-2.6.23.orig/drivers/mfd/Kconfig 2008-01-20 18:59:38.000000000 +0000
-+++ linux-2.6.23/drivers/mfd/Kconfig 2008-01-20 18:59:46.000000000 +0000
-@@ -21,6 +21,16 @@ config MFD_TSC2101
+--- linux-2.6.24.orig/drivers/mfd/Kconfig 2008-02-24 02:40:23.841034801 +0300
++++ linux-2.6.24/drivers/mfd/Kconfig 2008-02-24 02:40:56.652035294 +0300
+@@ -43,6 +43,16 @@ config MFD_TSC2101
help
Support for TI TSC2101 Touchscreen and Audio Codec
@@ -3783,10 +3783,10 @@ Index: linux-2.6.23/drivers/mfd/Kconfig
endmenu
menu "Multimedia Capabilities Port drivers"
-Index: linux-2.6.23/drivers/mfd/Makefile
+Index: linux-2.6.24/drivers/mfd/Makefile
===================================================================
---- linux-2.6.23.orig/drivers/mfd/Makefile 2008-01-20 18:59:38.000000000 +0000
-+++ linux-2.6.23/drivers/mfd/Makefile 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/drivers/mfd/Makefile 2008-02-24 02:40:23.849034737 +0300
++++ linux-2.6.24/drivers/mfd/Makefile 2008-02-24 02:40:56.652035294 +0300
@@ -2,6 +2,8 @@
# Makefile for multifunction miscellaneous devices
#
@@ -3795,11 +3795,11 @@ Index: linux-2.6.23/drivers/mfd/Makefile
+
obj-$(CONFIG_MFD_SM501) += sm501.o
- obj-$(CONFIG_MCP) += mcp-core.o
-Index: linux-2.6.23/drivers/mfd/asic3_base.c
+ obj-$(CONFIG_MFD_CORE) += mfd-core.o
+Index: linux-2.6.24/drivers/mfd/asic3_base.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/mfd/asic3_base.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/mfd/asic3_base.c 2008-02-24 02:40:56.652035294 +0300
@@ -0,0 +1,1208 @@
+/*
+ * Driver interface to HTC "ASIC3"
@@ -5009,10 +5009,10 @@ Index: linux-2.6.23/drivers/mfd/asic3_base.c
+MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
+MODULE_DESCRIPTION("Core driver for HTC ASIC3");
+MODULE_SUPPORTED_DEVICE("asic3");
-Index: linux-2.6.23/drivers/mfd/soc-core.c
+Index: linux-2.6.24/drivers/mfd/soc-core.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/mfd/soc-core.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/mfd/soc-core.c 2008-02-24 02:40:56.652035294 +0300
@@ -0,0 +1,106 @@
+/*
+ * drivers/soc/soc-core.c
@@ -5089,7 +5089,7 @@ Index: linux-2.6.23/drivers/mfd/soc-core.c
+ if (blk->res[r].flags & IORESOURCE_MEM) {
+ base = mem->start;
+ } else if ((blk->res[r].flags & IORESOURCE_IRQ) &&
-+ (blk->res[r].flags & IORESOURCE_IRQ_SOC_SUBDEVICE)) {
++ (blk->res[r].flags & IORESOURCE_IRQ_MFD_SUBDEVICE)) {
+ base = irq_base;
+ }
+
@@ -5120,10 +5120,10 @@ Index: linux-2.6.23/drivers/mfd/soc-core.c
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(soc_add_devices);
-Index: linux-2.6.23/drivers/mfd/soc-core.h
+Index: linux-2.6.24/drivers/mfd/soc-core.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/mfd/soc-core.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/mfd/soc-core.h 2008-02-24 02:40:56.652035294 +0300
@@ -0,0 +1,30 @@
+/*
+ * drivers/soc/soc-core.h
@@ -5155,10 +5155,10 @@ Index: linux-2.6.23/drivers/mfd/soc-core.h
+
+void soc_free_devices(struct platform_device *devices, int nr_devs);
+
-Index: linux-2.6.23/include/asm-arm/arch-pxa/clock.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/clock.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/clock.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/clock.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,27 @@
+/*
+ * linux/include/asm-arm/arch-pxa/clock.h
@@ -5187,10 +5187,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/clock.h
+
+extern int clk_register(struct clk *clk);
+extern void clk_unregister(struct clk *clk);
-Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-asic.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-asic.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-asic.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-asic.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,213 @@
+/*
+ * include/asm/arm/arch-pxa/htcuniversal-asic.h
@@ -5405,10 +5405,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-asic.h
+
+#endif /* _HTCUNIVERSAL_ASIC_H_ */
+
-Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-gpio.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-gpio.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-gpio.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-gpio.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,220 @@
+/*
+ * include/asm-arm/arch-pxa/htcuniversal-gpio.h
@@ -5630,10 +5630,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-gpio.h
+#define GPIO_NR_HTCUNIVERSAL_I2C_SDA_MD (118 | GPIO_ALT_FN_1_OUT)
+
+#endif /* _HTCUNIVERSAL_GPIO_H */
-Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-init.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-init.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-init.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal-init.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,14 @@
+/*
+ * include/asm/arm/arch-pxa/htcuniversal-init.h
@@ -5649,18 +5649,18 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal-init.h
+
+#endif /* _HTCUNIVERSAL_INIT_H_ */
+
-Index: linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/htcuniversal.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/htcuniversal.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,3 @@
+#include <asm/arch/irqs.h>
+
+#define HTCUNIVERSAL_ASIC3_IRQ_BASE IRQ_BOARD_START
-Index: linux-2.6.23/include/asm-arm/arch-pxa/pxa-pm_ll.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/pxa-pm_ll.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/pxa-pm_ll.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/pxa-pm_ll.h 2008-02-24 02:40:56.656035541 +0300
@@ -0,0 +1,6 @@
+struct pxa_ll_pm_ops {
+ void (*suspend)(unsigned long);
@@ -5668,10 +5668,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/pxa-pm_ll.h
+};
+
+extern struct pxa_ll_pm_ops *pxa_pm_set_ll_ops(struct pxa_ll_pm_ops *new_ops);
-Index: linux-2.6.23/include/asm-arm/hardware/asic3_keys.h
+Index: linux-2.6.24/include/asm-arm/hardware/asic3_keys.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/hardware/asic3_keys.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/hardware/asic3_keys.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,18 @@
+#include <linux/input.h>
+
@@ -5691,10 +5691,10 @@ Index: linux-2.6.23/include/asm-arm/hardware/asic3_keys.h
+ struct input_dev *input;
+ struct device *asic3_dev;
+};
-Index: linux-2.6.23/include/asm-arm/hardware/asic3_leds.h
+Index: linux-2.6.24/include/asm-arm/hardware/asic3_leds.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/hardware/asic3_leds.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/hardware/asic3_leds.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,34 @@
+/*
+ * LEDs support for HTC ASIC3 devices.
@@ -5730,10 +5730,10 @@ Index: linux-2.6.23/include/asm-arm/hardware/asic3_leds.h
+extern int asic3_leds_register(void);
+extern void asic3_leds_unregister(void);
+
-Index: linux-2.6.23/include/asm-arm/hardware/ipaq-asic3.h
+Index: linux-2.6.24/include/asm-arm/hardware/ipaq-asic3.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/hardware/ipaq-asic3.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/hardware/ipaq-asic3.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,602 @@
+/*
+ *
@@ -6337,10 +6337,10 @@ Index: linux-2.6.23/include/asm-arm/hardware/ipaq-asic3.h
+#define IPAQ_ASIC3_MAP_SIZE 0x2000
+
+#endif
-Index: linux-2.6.23/include/linux/gpiodev.h
+Index: linux-2.6.24/include/linux/gpiodev.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/linux/gpiodev.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/linux/gpiodev.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,44 @@
+#ifndef __GPIODEV_H
+#define __GPIODEV_H
@@ -6386,10 +6386,10 @@ Index: linux-2.6.23/include/linux/gpiodev.h
+}
+
+#endif /* __GPIODEV_H */
-Index: linux-2.6.23/include/linux/input_pda.h
+Index: linux-2.6.24/include/linux/input_pda.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/linux/input_pda.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/linux/input_pda.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,47 @@
+#ifndef _INPUT_PDA_H
+#define _INPUT_PDA_H
@@ -6438,10 +6438,10 @@ Index: linux-2.6.23/include/linux/input_pda.h
+#define _KEY_HOMEPAGE _KEY_APP4
+
+#endif
-Index: linux-2.6.23/include/linux/soc/asic3_base.h
+Index: linux-2.6.24/include/linux/soc/asic3_base.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/linux/soc/asic3_base.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/linux/soc/asic3_base.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,104 @@
+#include <asm/types.h>
+#include <linux/gpiodev.h>
@@ -6547,10 +6547,10 @@ Index: linux-2.6.23/include/linux/soc/asic3_base.h
+
+ struct tmio_mmc_hwconfig *tmio_mmc_hwconfig;
+};
-Index: linux-2.6.23/include/linux/soc/tmio_mmc.h
+Index: linux-2.6.24/include/linux/soc/tmio_mmc.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/linux/soc/tmio_mmc.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/linux/soc/tmio_mmc.h 2008-02-24 02:40:56.660035858 +0300
@@ -0,0 +1,17 @@
+#include <linux/platform_device.h>
+
@@ -6569,10 +6569,10 @@ Index: linux-2.6.23/include/linux/soc/tmio_mmc.h
+ int (*mmc_get_ro)(struct platform_device *pdev);
+ short address_shift;
+};
-Index: linux-2.6.23/include/asm-arm/arch-pxa/pxa-regs.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h
===================================================================
---- linux-2.6.23.orig/include/asm-arm/arch-pxa/pxa-regs.h 2008-01-20 18:59:40.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/pxa-regs.h 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/include/asm-arm/arch-pxa/pxa-regs.h 2008-02-24 02:40:23.965046594 +0300
++++ linux-2.6.24/include/asm-arm/arch-pxa/pxa-regs.h 2008-02-24 02:40:56.664035757 +0300
@@ -2058,6 +2058,8 @@
#define LDCMD_SOFINT (1 << 22)
#define LDCMD_EOFINT (1 << 21)
@@ -6582,24 +6582,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/pxa-regs.h
#define LCCR5_SOFM1 (1<<0) /* Start Of Frame Mask for Overlay 1 (channel 1) */
#define LCCR5_SOFM2 (1<<1) /* Start Of Frame Mask for Overlay 2 (channel 2) */
-Index: linux-2.6.23/drivers/mmc/host/Kconfig
+Index: linux-2.6.24/drivers/mmc/host/Makefile
===================================================================
---- linux-2.6.23.orig/drivers/mmc/host/Kconfig 2008-01-20 18:59:18.000000000 +0000
-+++ linux-2.6.23/drivers/mmc/host/Kconfig 2008-01-20 18:59:46.000000000 +0000
-@@ -130,3 +130,9 @@ config MMC_SPI
-
- If unsure, or if your system has no SPI master driver, say N.
-
-+config MMC_ASIC3
-+ tristate "HTC ASIC3 SD/MMC support"
-+ depends on MMC && HTC_ASIC3
-+ help
-+ This provides support for the ASIC3 SD/MMC controller, used
-+ in the iPAQ hx4700 and others.
-Index: linux-2.6.23/drivers/mmc/host/Makefile
-===================================================================
---- linux-2.6.23.orig/drivers/mmc/host/Makefile 2008-01-20 18:59:18.000000000 +0000
-+++ linux-2.6.23/drivers/mmc/host/Makefile 2008-01-20 21:12:10.000000000 +0000
+--- linux-2.6.24.orig/drivers/mmc/host/Makefile 2008-02-24 02:40:23.885035847 +0300
++++ linux-2.6.24/drivers/mmc/host/Makefile 2008-02-24 02:40:56.664035757 +0300
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
@@ -6608,10 +6594,10 @@ Index: linux-2.6.23/drivers/mmc/host/Makefile
obj-$(CONFIG_MMC_OMAP) += omap.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
-Index: linux-2.6.23/drivers/mmc/host/asic3_mmc.c
+Index: linux-2.6.24/drivers/mmc/host/asic3_mmc.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/mmc/host/asic3_mmc.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/mmc/host/asic3_mmc.c 2008-02-24 02:40:56.664035757 +0300
@@ -0,0 +1,900 @@
+/* Note that this driver can likely be merged into the tmio driver, so
+ * consider this code temporary. It works, though.
@@ -7513,10 +7499,10 @@ Index: linux-2.6.23/drivers/mmc/host/asic3_mmc.c
+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
+MODULE_LICENSE("GPL");
+
-Index: linux-2.6.23/drivers/mmc/host/asic3_mmc.h
+Index: linux-2.6.24/drivers/mmc/host/asic3_mmc.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/mmc/host/asic3_mmc.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/mmc/host/asic3_mmc.h 2008-02-24 02:40:56.664035757 +0300
@@ -0,0 +1,25 @@
+#ifndef __ASIC3_MMC_H
+#define __ASIC3_MMC_H
@@ -7543,22 +7529,22 @@ Index: linux-2.6.23/drivers/mmc/host/asic3_mmc.h
+#define DONT_CARE_BUFFER_BITS ( SD_CTRL_INTMASKBUFFER_UNK7 | SD_CTRL_INTMASKBUFFER_CMD_BUSY )
+
+#endif // __ASIC3_MMC_H
-Index: linux-2.6.23/drivers/input/keyboard/Makefile
+Index: linux-2.6.24/drivers/input/keyboard/Makefile
===================================================================
---- linux-2.6.23.orig/drivers/input/keyboard/Makefile 2008-01-20 18:59:16.000000000 +0000
-+++ linux-2.6.23/drivers/input/keyboard/Makefile 2008-01-20 21:11:40.000000000 +0000
-@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_NEWTON) += newton
- obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+--- linux-2.6.24.orig/drivers/input/keyboard/Makefile 2008-02-24 02:40:23.905037294 +0300
++++ linux-2.6.24/drivers/input/keyboard/Makefile 2008-02-24 02:40:56.664035757 +0300
+@@ -16,6 +16,7 @@ obj-$(CONFIG_KEYBOARD_STOWAWAY) += stow
obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
+ obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
+obj-$(CONFIG_KEYBOARD_ASIC3) += asic3_keys.o
obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
-Index: linux-2.6.23/drivers/input/keyboard/asic3_keys.c
+Index: linux-2.6.24/drivers/input/keyboard/asic3_keys.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/drivers/input/keyboard/asic3_keys.c 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/drivers/input/keyboard/asic3_keys.c 2008-02-24 02:40:56.668036144 +0300
@@ -0,0 +1,131 @@
+/*
+ * Generic buttons driver for ASIC3 SoC.
@@ -7691,12 +7677,12 @@ Index: linux-2.6.23/drivers/input/keyboard/asic3_keys.c
+MODULE_AUTHOR("Joshua Wise, Pawel Kolodziejski, Paul Sokolovsky");
+MODULE_DESCRIPTION("Buttons driver for HTC ASIC3 SoC");
+MODULE_LICENSE("GPL");
-Index: linux-2.6.23/include/asm-arm/arch-pxa/irqs.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/irqs.h
===================================================================
---- linux-2.6.23.orig/include/asm-arm/arch-pxa/irqs.h 2008-01-20 18:59:28.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/irqs.h 2008-01-20 18:59:46.000000000 +0000
-@@ -182,6 +182,8 @@
- defined(CONFIG_MACH_LOGICPD_PXA270) || \
+--- linux-2.6.24.orig/include/asm-arm/arch-pxa/irqs.h 2008-02-24 02:40:23.973034657 +0300
++++ linux-2.6.24/include/asm-arm/arch-pxa/irqs.h 2008-02-24 02:40:56.668036144 +0300
+@@ -183,6 +183,8 @@
+ defined(CONFIG_MACH_TOSA) || \
defined(CONFIG_MACH_MAINSTONE)
#define NR_IRQS (IRQ_BOARD_END)
+#elif defined(CONFIG_MACH_HTCUNIVERSAL)
@@ -7704,22 +7690,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/irqs.h
#else
#define NR_IRQS (IRQ_BOARD_START)
#endif
-Index: linux-2.6.23/include/linux/ioport.h
-===================================================================
---- linux-2.6.23.orig/include/linux/ioport.h 2008-01-20 18:59:31.000000000 +0000
-+++ linux-2.6.23/include/linux/ioport.h 2008-01-20 18:59:46.000000000 +0000
-@@ -56,6 +56,7 @@ struct resource_list {
- #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
- #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
- #define IORESOURCE_IRQ_SHAREABLE (1<<4)
-+#define IORESOURCE_IRQ_SOC_SUBDEVICE (1<<5)
-
- /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
- #define IORESOURCE_DMA_TYPE_MASK (3<<0)
-Index: linux-2.6.23/include/asm-arm/arch-pxa/serial.h
+Index: linux-2.6.24/include/asm-arm/arch-pxa/serial.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.23/include/asm-arm/arch-pxa/serial.h 2008-01-20 18:59:46.000000000 +0000
++++ linux-2.6.24/include/asm-arm/arch-pxa/serial.h 2008-02-24 02:40:56.668036144 +0300
@@ -0,0 +1,78 @@
+/*
+ * linux/include/asm-arm/arch-pxa/serial.h
@@ -7799,10 +7773,10 @@ Index: linux-2.6.23/include/asm-arm/arch-pxa/serial.h
+void pxa_set_btuart_info(struct platform_pxa_serial_funcs *btuart_funcs);
+void pxa_set_stuart_info(struct platform_pxa_serial_funcs *stuart_funcs);
+void pxa_set_hwuart_info(struct platform_pxa_serial_funcs *hwuart_funcs);
-Index: linux-2.6.23/drivers/serial/pxa.c
+Index: linux-2.6.24/drivers/serial/pxa.c
===================================================================
---- linux-2.6.23.orig/drivers/serial/pxa.c 2008-01-20 18:59:23.000000000 +0000
-+++ linux-2.6.23/drivers/serial/pxa.c 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/drivers/serial/pxa.c 2008-02-24 02:40:23.925046354 +0300
++++ linux-2.6.24/drivers/serial/pxa.c 2008-02-24 02:40:56.668036144 +0300
@@ -47,6 +47,7 @@
#include <asm/io.h>
#include <asm/hardware.h>
@@ -7867,10 +7841,10 @@ Index: linux-2.6.23/drivers/serial/pxa.c
}
static void
-Index: linux-2.6.23/arch/arm/mach-pxa/generic.c
+Index: linux-2.6.24/arch/arm/mach-pxa/generic.c
===================================================================
---- linux-2.6.23.orig/arch/arm/mach-pxa/generic.c 2008-01-20 18:59:09.000000000 +0000
-+++ linux-2.6.23/arch/arm/mach-pxa/generic.c 2008-01-20 18:59:46.000000000 +0000
+--- linux-2.6.24.orig/arch/arm/mach-pxa/generic.c 2008-02-24 02:40:23.809034497 +0300
++++ linux-2.6.24/arch/arm/mach-pxa/generic.c 2008-02-24 02:40:56.668036144 +0300
@@ -38,6 +38,7 @@
#include <asm/arch/mmc.h>
#include <asm/arch/irda.h>
@@ -7898,10 +7872,10 @@ Index: linux-2.6.23/arch/arm/mach-pxa/generic.c
static struct resource pxai2c_resources[] = {
{
.start = 0x40301680,
-Index: linux-2.6.23/drivers/leds/Makefile
+Index: linux-2.6.24/drivers/leds/Makefile
===================================================================
---- linux-2.6.23.orig/drivers/leds/Makefile 2008-01-20 18:59:17.000000000 +0000
-+++ linux-2.6.23/drivers/leds/Makefile 2008-01-20 21:10:45.000000000 +0000
+--- linux-2.6.24.orig/drivers/leds/Makefile 2008-02-24 02:40:23.833034725 +0300
++++ linux-2.6.24/drivers/leds/Makefile 2008-02-24 02:40:56.668036144 +0300
@@ -15,6 +15,7 @@ obj-$(CONFIG_LEDS_AMS_DELTA) += leds-am
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
@@ -7910,11 +7884,11 @@ Index: linux-2.6.23/drivers/leds/Makefile
obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
-Index: linux-2.6.23/drivers/input/keyboard/Kconfig
+Index: linux-2.6.24/drivers/input/keyboard/Kconfig
===================================================================
---- linux-2.6.23.orig/drivers/input/keyboard/Kconfig 2008-01-20 18:59:16.000000000 +0000
-+++ linux-2.6.23/drivers/input/keyboard/Kconfig 2008-01-20 18:59:46.000000000 +0000
-@@ -293,4 +293,11 @@ config KEYBOARD_BFIN
+--- linux-2.6.24.orig/drivers/input/keyboard/Kconfig 2008-02-24 02:40:23.917037268 +0300
++++ linux-2.6.24/drivers/input/keyboard/Kconfig 2008-02-24 02:40:56.676035032 +0300
+@@ -314,4 +314,11 @@ config KEYBOARD_BFIN
To compile this driver as a module, choose M here: the
module will be called bf54x-keys.
@@ -7926,3 +7900,18 @@ Index: linux-2.6.23/drivers/input/keyboard/Kconfig
+ HTC ASIC3 peripheral controller.
+
endif
+Index: linux-2.6.24/drivers/mmc/host/Kconfig
+===================================================================
+--- linux-2.6.24.orig/drivers/mmc/host/Kconfig 2008-02-24 02:41:04.868035778 +0300
++++ linux-2.6.24/drivers/mmc/host/Kconfig 2008-02-24 02:41:46.328053402 +0300
+@@ -136,3 +136,10 @@ config MMC_TMIO
+ help
+ This provides support for the SD/MMC cell found in TC6393XB,
+ T7L66XB and also ipaq ASIC3
++
++config MMC_ASIC3
++ tristate "HTC ASIC3 SD/MMC support"
++ depends on MMC && HTC_ASIC3
++ help
++ This provides support for the ASIC3 SD/MMC controller, used
++ in the iPAQ hx4700 and others.
diff --git a/packages/linux/linux-rp-2.6.24/tosa/.mtn2git_empty b/packages/linux/linux-rp-2.6.24/tosa/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/.mtn2git_empty
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch b/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch
new file mode 100644
index 0000000000..ba79b4a470
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch
@@ -0,0 +1,201 @@
+From d48a09b301d9a460d5ce027433e8cb8872e7b5c3 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Fri, 4 Jan 2008 18:26:38 +0000
+Subject: [PATCH 01/64] Allow runtime registration of regions of memory that require dma bouncing.
+
+---
+ arch/arm/common/Kconfig | 4 ++
+ arch/arm/common/dmabounce.c | 82 ++++++++++++++++++++++++++++++++++++-
+ arch/arm/common/sa1111.c | 2 +-
+ arch/arm/mach-ixp4xx/Kconfig | 1 +
+ arch/arm/mach-ixp4xx/common-pci.c | 2 +-
+ 5 files changed, 87 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
+index 3e07346..5f357fb 100644
+--- a/arch/arm/common/Kconfig
++++ b/arch/arm/common/Kconfig
+@@ -13,10 +13,14 @@ config ICST307
+ config SA1111
+ bool
+ select DMABOUNCE
++ select PLATFORM_DMABOUNCE
+
+ config DMABOUNCE
+ bool
+
++config PLATFORM_DMABOUNCE
++ bool
++
+ config TIMER_ACORN
+ bool
+
+diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
+index 52fc6a8..ed80abe 100644
+--- a/arch/arm/common/dmabounce.c
++++ b/arch/arm/common/dmabounce.c
+@@ -16,6 +16,7 @@
+ *
+ * Copyright (C) 2002 Hewlett Packard Company.
+ * Copyright (C) 2004 MontaVista Software, Inc.
++ * Copyright (C) 2007 Dmitry Baryshkov <dbaryshkov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+@@ -24,6 +25,7 @@
+
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/rwsem.h>
+ #include <linux/slab.h>
+ #include <linux/device.h>
+ #include <linux/dma-mapping.h>
+@@ -80,6 +82,80 @@ struct dmabounce_device_info {
+ rwlock_t lock;
+ };
+
++struct dmabounce_check_entry {
++ struct list_head list;
++ dmabounce_check checker;
++ void *data;
++};
++
++static struct list_head checkers = LIST_HEAD_INIT(checkers);
++static rwlock_t checkers_lock = RW_LOCK_UNLOCKED;
++
++int
++dmabounce_register_checker(dmabounce_check function, void *data)
++{
++ unsigned long flags;
++ struct dmabounce_check_entry *entry =
++ kzalloc(sizeof(struct dmabounce_check_entry), GFP_ATOMIC);
++
++ if (!entry)
++ return ENOMEM;
++
++ INIT_LIST_HEAD(&entry->list);
++ entry->checker = function;
++ entry->data = data;
++
++ write_lock_irqsave(&checkers_lock, flags);
++ list_add(&entry->list, &checkers);
++ write_unlock_irqrestore(&checkers_lock, flags);
++
++ return 0;
++}
++
++void
++dmabounce_remove_checker(dmabounce_check function, void *data)
++{
++ unsigned long flags;
++ struct list_head *pos;
++
++ write_lock_irqsave(&checkers_lock, flags);
++ __list_for_each(pos, &checkers) {
++ struct dmabounce_check_entry *entry = container_of(pos,
++ struct dmabounce_check_entry, list);
++ if (entry->checker == function && entry->data == data) {
++ list_del(pos);
++ write_unlock_irqrestore(&checkers_lock, flags);
++ kfree(entry);
++ return;
++ }
++ }
++
++ write_unlock_irqrestore(&checkers_lock, flags);
++ printk(KERN_WARNING "dmabounce checker not found: %p\n", function);
++}
++
++static int dma_needs_bounce(struct device *dev, dma_addr_t dma, size_t size)
++{
++ unsigned long flags;
++ struct list_head *pos;
++
++ read_lock_irqsave(&checkers_lock, flags);
++ __list_for_each(pos, &checkers) {
++ struct dmabounce_check_entry *entry = container_of(pos,
++ struct dmabounce_check_entry, list);
++ if (entry->checker(dev, dma, size, entry->data)) {
++ read_unlock_irqrestore(&checkers_lock, flags);
++ return 1;
++ }
++ }
++
++ read_unlock_irqrestore(&checkers_lock, flags);
++#ifdef CONFIG_PLATFORM_DMABOUNCE
++ return platform_dma_needs_bounce(dev, dma, size);
++#else
++ return 0;
++#endif
++}
+ #ifdef STATS
+ static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+@@ -239,7 +315,7 @@ map_single(struct device *dev, void *ptr, size_t size,
+ struct safe_buffer *buf;
+
+ buf = alloc_safe_buffer(device_info, ptr, size, dir);
+- if (buf == 0) {
++ if (buf == NULL) {
+ dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
+ __func__, ptr);
+ return 0;
+@@ -643,7 +719,6 @@ dmabounce_unregister_dev(struct device *dev)
+ dev->bus_id, dev->bus->name);
+ }
+
+-
+ EXPORT_SYMBOL(dma_map_single);
+ EXPORT_SYMBOL(dma_unmap_single);
+ EXPORT_SYMBOL(dma_map_sg);
+@@ -653,6 +728,9 @@ EXPORT_SYMBOL(dma_sync_single_for_device);
+ EXPORT_SYMBOL(dma_sync_sg);
+ EXPORT_SYMBOL(dmabounce_register_dev);
+ EXPORT_SYMBOL(dmabounce_unregister_dev);
++EXPORT_SYMBOL(dmabounce_register_checker);
++EXPORT_SYMBOL(dmabounce_remove_checker);
++
+
+ MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>, Deepak Saxena <dsaxena@plexity.net>");
+ MODULE_DESCRIPTION("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows");
+diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
+index eb06d0b..3b8fbdd 100644
+--- a/arch/arm/common/sa1111.c
++++ b/arch/arm/common/sa1111.c
+@@ -778,7 +778,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
+ * This should only get called for sa1111_device types due to the
+ * way we configure our device dma_masks.
+ */
+-int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
++int platform_dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
+ {
+ /*
+ * Section 4.6 of the "Intel StrongARM SA-1111 Development Module
+diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
+index 61b2dfc..5870371 100644
+--- a/arch/arm/mach-ixp4xx/Kconfig
++++ b/arch/arm/mach-ixp4xx/Kconfig
+@@ -161,6 +161,7 @@ comment "IXP4xx Options"
+ config DMABOUNCE
+ bool
+ default y
++ select PLATFORM_DMABOUNCE
+ depends on PCI
+
+ config IXP4XX_INDIRECT_PCI
+diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
+index bf04121..ac46492 100644
+--- a/arch/arm/mach-ixp4xx/common-pci.c
++++ b/arch/arm/mach-ixp4xx/common-pci.c
+@@ -336,7 +336,7 @@ static int ixp4xx_pci_platform_notify_remove(struct device *dev)
+ return 0;
+ }
+
+-int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
++int platform_dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
+ {
+ return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
+ }
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch b/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch
new file mode 100644
index 0000000000..a562ef921b
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch
@@ -0,0 +1,260 @@
+From 8e95f90487d2fb46fd862744ddb34f47c30b0c5a Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Fri, 4 Jan 2008 18:27:50 +0000
+Subject: [PATCH 02/64] Modify dma_alloc_coherent on ARM so that it supports device local DMA.
+
+---
+ arch/arm/mm/consistent.c | 125 +++++++++++++++++++++++++++++++++++++++++
+ include/asm-arm/dma-mapping.h | 37 +++++++------
+ 2 files changed, 145 insertions(+), 17 deletions(-)
+
+diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
+index 333a82a..3da0f94 100644
+--- a/arch/arm/mm/consistent.c
++++ b/arch/arm/mm/consistent.c
+@@ -3,6 +3,8 @@
+ *
+ * Copyright (C) 2000-2004 Russell King
+ *
++ * Device local coherent memory support added by Ian Molton (spyro@f2s.com)
++ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+@@ -20,6 +22,7 @@
+
+ #include <asm/memory.h>
+ #include <asm/cacheflush.h>
++#include <asm/io.h>
+ #include <asm/tlbflush.h>
+ #include <asm/sizes.h>
+
+@@ -35,6 +38,13 @@
+ #define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT)
+ #define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT)
+
++struct dma_coherent_mem {
++ void *virt_base;
++ u32 device_base;
++ int size;
++ int flags;
++ unsigned long *bitmap;
++};
+
+ /*
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+@@ -153,6 +163,13 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+ unsigned long order;
+ u64 mask = ISA_DMA_THRESHOLD, limit;
+
++ /* Following is a work-around (a.k.a. hack) to prevent pages
++ * with __GFP_COMP being passed to split_page() which cannot
++ * handle them. The real problem is that this flag probably
++ * should be 0 on ARM as it is not supported on this
++ * platform--see CONFIG_HUGETLB_PAGE. */
++ gfp &= ~(__GFP_COMP);
++
+ if (!consistent_pte[0]) {
+ printk(KERN_ERR "%s: not initialised\n", __func__);
+ dump_stack();
+@@ -160,6 +177,26 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+ }
+
+ if (dev) {
++
++ if (dev->dma_mem) {
++ unsigned long flags;
++ int pgnum;
++ void *ret;
++
++ spin_lock_irqsave(&consistent_lock, flags);
++ pgnum = bitmap_find_free_region(dev->dma_mem->bitmap,
++ dev->dma_mem->size,
++ get_order(size));
++ spin_unlock_irqrestore(&consistent_lock, flags);
++
++ if (pgnum >= 0) {
++ *handle = dev->dma_mem->device_base + (pgnum << PAGE_SHIFT);
++ ret = dev->dma_mem->virt_base + (pgnum << PAGE_SHIFT);
++ memset(ret, 0, size);
++ return ret;
++ }
++ }
++
+ mask = dev->coherent_dma_mask;
+
+ /*
+@@ -177,6 +214,9 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
+ mask, (unsigned long long)ISA_DMA_THRESHOLD);
+ goto no_page;
+ }
++
++ if (dev->dma_mem && dev->dma_mem->flags & DMA_MEMORY_EXCLUSIVE)
++ return NULL;
+ }
+
+ /*
+@@ -359,6 +399,8 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
+ pte_t *ptep;
+ int idx;
+ u32 off;
++ struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
++ unsigned long order;
+
+ WARN_ON(irqs_disabled());
+
+@@ -368,6 +410,15 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
+ }
+
+ size = PAGE_ALIGN(size);
++ order = get_order(size);
++
++ /* What if mem is valid and the range is not? */
++ if (mem && cpu_addr >= mem->virt_base && cpu_addr < (mem->virt_base + (mem->size << PAGE_SHIFT))) {
++ int page = (cpu_addr - mem->virt_base) >> PAGE_SHIFT;
++
++ bitmap_release_region(mem->bitmap, page, order);
++ return;
++ }
+
+ spin_lock_irqsave(&consistent_lock, flags);
+ c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
+@@ -437,6 +488,80 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr
+ }
+ EXPORT_SYMBOL(dma_free_coherent);
+
++int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
++ dma_addr_t device_addr, size_t size, int flags)
++{
++ void __iomem *mem_base;
++ int pages = size >> PAGE_SHIFT;
++ int bitmap_size = (pages + 31)/32;
++
++ if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
++ goto out;
++ if (!size)
++ goto out;
++ if (dev->dma_mem)
++ goto out;
++
++ /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
++ mem_base = ioremap_nocache(bus_addr, size);
++ if (!mem_base)
++ goto out;
++
++ dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
++ if (!dev->dma_mem)
++ goto out;
++ memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem));
++ dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
++ if (!dev->dma_mem->bitmap)
++ goto free1_out;
++
++ dev->dma_mem->virt_base = mem_base;
++ dev->dma_mem->device_base = device_addr;
++ dev->dma_mem->size = pages;
++ dev->dma_mem->flags = flags;
++
++ if (flags & DMA_MEMORY_MAP)
++ return DMA_MEMORY_MAP;
++
++ return DMA_MEMORY_IO;
++
++ free1_out:
++ kfree(dev->dma_mem->bitmap);
++ out:
++ return 0;
++}
++EXPORT_SYMBOL(dma_declare_coherent_memory);
++
++void dma_release_declared_memory(struct device *dev)
++{
++ struct dma_coherent_mem *mem = dev->dma_mem;
++
++ if (!mem)
++ return;
++ dev->dma_mem = NULL;
++ kfree(mem->bitmap);
++ kfree(mem);
++}
++EXPORT_SYMBOL(dma_release_declared_memory);
++
++void *dma_mark_declared_memory_occupied(struct device *dev,
++ dma_addr_t device_addr, size_t size)
++{
++ struct dma_coherent_mem *mem = dev->dma_mem;
++ int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
++ int pos, err;
++
++ if (!mem)
++ return ERR_PTR(-EINVAL);
++
++ pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
++ err = bitmap_allocate_region(mem->bitmap, pos, get_order(pages));
++ if (err != 0)
++ return ERR_PTR(err);
++ return mem->virt_base + (pos << PAGE_SHIFT);
++}
++EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
++
+ /*
+ * Initialise the consistent memory allocation.
+ */
+diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
+index e99406a..f18ba05 100644
+--- a/include/asm-arm/dma-mapping.h
++++ b/include/asm-arm/dma-mapping.h
+@@ -7,6 +7,19 @@
+
+ #include <linux/scatterlist.h>
+
++#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
++extern int
++dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
++ dma_addr_t device_addr, size_t size, int flags);
++
++extern void
++dma_release_declared_memory(struct device *dev);
++
++extern void *
++dma_mark_declared_memory_occupied(struct device *dev,
++ dma_addr_t device_addr, size_t size);
++
++
+ /*
+ * DMA-consistent mapping functions. These allocate/free a region of
+ * uncached, unwrite-buffered mapped memory space for use with DMA
+@@ -433,23 +446,13 @@ extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long)
+ */
+ extern void dmabounce_unregister_dev(struct device *);
+
+-/**
+- * dma_needs_bounce
+- *
+- * @dev: valid struct device pointer
+- * @dma_handle: dma_handle of unbounced buffer
+- * @size: size of region being mapped
+- *
+- * Platforms that utilize the dmabounce mechanism must implement
+- * this function.
+- *
+- * The dmabounce routines call this function whenever a dma-mapping
+- * is requested to determine whether a given buffer needs to be bounced
+- * or not. The function must return 0 if the buffer is OK for
+- * DMA access and 1 if the buffer needs to be bounced.
+- *
+- */
+-extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
++typedef int (*dmabounce_check)(struct device *dev, dma_addr_t dma, size_t size, void *data);
++extern int dmabounce_register_checker(dmabounce_check, void *data);
++extern void dmabounce_remove_checker(dmabounce_check, void *data);
++#ifdef CONFIG_PLATFORM_DMABOUNCE
++extern int platform_dma_needs_bounce(struct device *dev, dma_addr_t dma, size_t size, void *data);
++#endif
++
+ #endif /* CONFIG_DMABOUNCE */
+
+ #endif /* __KERNEL__ */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch
new file mode 100644
index 0000000000..d84a4f7835
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0003-Core-MFD-support.patch
@@ -0,0 +1,243 @@
+From a07910753f9965842b6647f0561db125b538f5ed Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Fri, 4 Jan 2008 18:32:44 +0000
+Subject: [PATCH 03/64] Core MFD support
+
+This patch provides a common subdevice registration system for MFD type
+chips, using platfrom device.
+
+It also provides a new resource type for IRQs such that a subdevices IRQ may
+be computed based on the MFD cores IRQ handler, since many MFDs provide an IRQ
+multiplex.
+---
+ drivers/mfd/Kconfig | 4 ++
+ drivers/mfd/Makefile | 2 +
+ drivers/mfd/mfd-core.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/ioport.h | 1 +
+ include/linux/mfd-core.h | 51 ++++++++++++++++++++
+ 5 files changed, 174 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mfd/mfd-core.c
+ create mode 100644 include/linux/mfd-core.h
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 2571619..1205c89 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -5,6 +5,10 @@
+ menu "Multifunction device drivers"
+ depends on HAS_IOMEM
+
++config MFD_CORE
++ tristate
++ default n
++
+ config MFD_SM501
+ tristate "Support for Silicon Motion SM501"
+ ---help---
+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
+index 5143209..6c20064 100644
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -4,6 +4,8 @@
+
+ obj-$(CONFIG_MFD_SM501) += sm501.o
+
++obj-$(CONFIG_MFD_CORE) += mfd-core.o
++
+ obj-$(CONFIG_MCP) += mcp-core.o
+ obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
+new file mode 100644
+index 0000000..88874e1
+--- /dev/null
++++ b/drivers/mfd/mfd-core.c
+@@ -0,0 +1,116 @@
++/*
++ * drivers/mfd/mfd-core.c
++ *
++ * core MFD support
++ * Copyright (c) 2006 Ian Molton
++ * Copyright (c) 2007 Dmitry Baryshkov
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/platform_device.h>
++#include <linux/mfd-core.h>
++
++#define SIGNED_SHIFT(val, shift) ((shift) >= 0 ? \
++ ((val) << (shift)) : \
++ ((val) >> -(shift)))
++
++int mfd_add_devices(
++ struct platform_device *parent,
++ const struct mfd_cell *cells, int n_devs,
++ struct resource *mem,
++ int relative_addr_shift,
++ int irq_base)
++{
++ int i;
++
++ for (i = 0; i < n_devs; i++) {
++ struct resource *res = NULL;
++ const struct mfd_cell *cell = cells + i;
++ struct platform_device *pdev;
++ int ret = -ENOMEM;
++ int r;
++
++ pdev = platform_device_alloc(cell->name, -1);
++ if (!pdev)
++ goto fail_alloc;
++
++ pdev->dev.uevent_suppress = 0;
++ pdev->dev.parent = &parent->dev;
++
++ ret = platform_device_add_data(pdev, &cell, sizeof(struct mfd_cell *));
++ if (ret)
++ goto fail_device;
++
++ res = kzalloc(cell->num_resources * sizeof(struct resource),
++ GFP_KERNEL);
++ if (!res)
++ goto fail_device;
++
++ for (r = 0; r < cell->num_resources; r++) {
++ res[r].name = cell->resources[r].name;
++
++ /* Find out base to use */
++ if (cell->resources[r].flags & IORESOURCE_MEM) {
++ res[r].parent = mem;
++ res[r].start = mem->start +
++ SIGNED_SHIFT(cell->resources[r].start,
++ relative_addr_shift);
++ res[r].end = mem->start +
++ SIGNED_SHIFT(cell->resources[r].end,
++ relative_addr_shift);
++ } else if ((cell->resources[r].flags & IORESOURCE_IRQ) &&
++ (cell->resources[r].flags & IORESOURCE_IRQ_MFD_SUBDEVICE)) {
++ res[r].start = irq_base +
++ cell->resources[r].start;
++ res[r].end = irq_base +
++ cell->resources[r].end;
++ } else {
++ res[r].start = cell->resources[r].start;
++ res[r].end = cell->resources[r].end;
++ }
++
++ res[r].flags = cell->resources[r].flags;
++ }
++
++ ret = platform_device_add_resources(pdev,
++ res,
++ cell->num_resources);
++ kfree(res);
++
++ if (ret)
++ goto fail_device;
++
++ ret = platform_device_add(pdev);
++
++ if (ret) {
++ platform_device_del(pdev);
++fail_device:
++ platform_device_put(pdev);
++fail_alloc:
++ mfd_remove_devices(parent);
++ return ret;
++ }
++ }
++ return 0;
++}
++EXPORT_SYMBOL(mfd_add_devices);
++
++static int mfd_remove_devices_fn(struct device *dev, void *unused)
++{
++ platform_device_unregister(container_of(dev, struct platform_device, dev));
++ return 0;
++}
++
++void mfd_remove_devices(struct platform_device *parent)
++{
++ device_for_each_child(&parent->dev, NULL, mfd_remove_devices_fn);
++}
++EXPORT_SYMBOL(mfd_remove_devices);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
+diff --git a/include/linux/ioport.h b/include/linux/ioport.h
+index 6187a85..0348c71 100644
+--- a/include/linux/ioport.h
++++ b/include/linux/ioport.h
+@@ -56,6 +56,7 @@ struct resource_list {
+ #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
+ #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
+ #define IORESOURCE_IRQ_SHAREABLE (1<<4)
++#define IORESOURCE_IRQ_MFD_SUBDEVICE (1<<5)
+
+ /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
+ #define IORESOURCE_DMA_TYPE_MASK (3<<0)
+diff --git a/include/linux/mfd-core.h b/include/linux/mfd-core.h
+new file mode 100644
+index 0000000..0e9de78
+--- /dev/null
++++ b/include/linux/mfd-core.h
+@@ -0,0 +1,51 @@
++#ifndef MFD_CORE_H
++#define MFD_CORE_H
++/*
++ * drivers/mfd/mfd-core.h
++ *
++ * core MFD support
++ * Copyright (c) 2006 Ian Molton
++ * Copyright (c) 2007 Dmitry Baryshkov
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/platform_device.h>
++
++struct mfd_cell {
++ const char *name;
++
++ int (*enable)(struct platform_device *dev);
++ int (*disable)(struct platform_device *dev);
++ int (*suspend)(struct platform_device *dev);
++ int (*resume)(struct platform_device *dev);
++
++ void *driver_data; /* data passed to drivers */
++
++ /*
++ * This resources can be specified relatievly to the parent device.
++ * For accessing device you should use resources from device
++ */
++ int num_resources;
++ const struct resource *resources;
++};
++
++static inline __maybe_unused struct mfd_cell *
++mfd_get_cell(struct platform_device *pdev)
++{
++ return *((struct mfd_cell **)(pdev->dev.platform_data));
++}
++
++extern int mfd_add_devices(
++ struct platform_device *parent,
++ const struct mfd_cell *cells, int n_devs,
++ struct resource *mem,
++ int relative_addr_shift,
++ int irq_base);
++
++extern void mfd_remove_devices(struct platform_device *parent);
++
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch
new file mode 100644
index 0000000000..a78c0f37f3
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0004-Add-support-for-tc6393xb-MFD-core.patch
@@ -0,0 +1,907 @@
+From 3f56cac281fb407b7d8e574d18ee7d72aa7e7c28 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sat, 29 Dec 2007 15:02:30 +0000
+Subject: [PATCH 04/64] Add support for tc6393xb MFD core
+
+---
+ drivers/mfd/Kconfig | 6 +
+ drivers/mfd/Makefile | 2 +
+ drivers/mfd/tc6393xb.c | 740 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/mfd/tc6393xb.h | 108 ++++++
+ 4 files changed, 856 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mfd/tc6393xb.c
+ create mode 100644 include/linux/mfd/tc6393xb.h
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 1205c89..9903d0a 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -9,6 +9,12 @@ config MFD_CORE
+ tristate
+ default n
+
++config MFD_TC6393XB
++ bool "Support Toshiba TC6393XB"
++ select MFD_CORE
++ help
++ Support for Toshiba Mobile IO Controller TC6393XB
++
+ config MFD_SM501
+ tristate "Support for Silicon Motion SM501"
+ ---help---
+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
+index 6c20064..ffd342e 100644
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -6,6 +6,8 @@ obj-$(CONFIG_MFD_SM501) += sm501.o
+
+ obj-$(CONFIG_MFD_CORE) += mfd-core.o
+
++obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o
++
+ obj-$(CONFIG_MCP) += mcp-core.o
+ obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
+ obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+new file mode 100644
+index 0000000..9439f39
+--- /dev/null
++++ b/drivers/mfd/tc6393xb.c
+@@ -0,0 +1,740 @@
++/*
++ * Toshiba TC6393XB SoC support
++ *
++ * Copyright(c) 2005-2006 Chris Humbert
++ * Copyright(c) 2005 Dirk Opfer
++ * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
++ * Copyright(c) 2007 Dmitry Baryshkov
++ *
++ * Based on code written by Sharp/Lineo for 2.4 kernels
++ * Based on locomo.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++#include <linux/mfd/tc6393xb.h>
++
++struct tc6393xb_scr {
++ u8 x00[8];
++ u8 revid; /* 0x08 Revision ID */
++ u8 x01[0x47];
++ u8 isr; /* 0x50 Interrupt Status */
++ u8 x02;
++ u8 imr; /* 0x52 Interrupt Mask */
++ u8 x03;
++ u8 irr; /* 0x54 Interrupt Routing */
++ u8 x04[0x0b];
++ u16 gper; /* 0x60 GP Enable */
++ u8 x05[2];
++ u16 gpi_sr[2]; /* 0x64 GPI Status */
++ u16 gpi_imr[2]; /* 0x68 GPI INT Mask */
++ u16 gpi_eder[2]; /* 0x6c GPI Edge Detect Enable */
++ u16 gpi_lir[4]; /* 0x70 GPI Level Invert */
++ u16 gpo_dsr[2]; /* 0x78 GPO Data Set */
++ u16 gpo_doecr[2]; /* 0x7c GPO Data OE Control */
++ u16 gp_iarcr[2]; /* 0x80 GP Internal Active Reg Control */
++ u16 gp_iarlcr[2]; /* 0x84 GP Internal Active Reg Level Con*/
++ u8 gpi_bcr[4]; /* 0x88 GPI Buffer Control */
++ u16 gpa_iarcr; /* 0x8c GPa Internal Active Reg Control */
++ u8 x06[2];
++ u16 gpa_iarlcr; /* 0x90 GPa Internal Active Reg Level Co*/
++ u8 x07[2];
++ u16 gpa_bcr; /* 0x94 GPa Buffer Control */
++ u8 x08[2];
++ u16 ccr; /* 0x98 Clock Control */
++ u16 pll2cr; /* 0x9a PLL2 Control */
++ u16 pll1cr[2]; /* 0x9c PLL1 Control */
++ u8 diarcr; /* 0xa0 Device Internal Active Reg Contr*/
++ u8 dbocr; /* 0xa1 Device Buffer Off Control */
++ u8 x09[0x3e];
++ u8 fer; /* 0xe0 Function Enable */
++ u8 x10[3];
++ u16 mcr; /* 0xe4 Mode Control */
++ u8 x11[0x14];
++ u8 config; /* 0xfc Configuration Control */
++ u8 x12[2];
++ u8 debug; /* 0xff Debug */
++} __attribute__ ((packed));
++
++/*--------------------------------------------------------------------------*/
++
++struct tc6393xb {
++ struct tc6393xb_scr __iomem *scr;
++
++ spinlock_t lock; /* protects RMW cycles */
++
++ struct {
++ union tc6393xb_scr_fer fer;
++ union tc6393xb_scr_ccr ccr;
++ u8 gpi_bcr[4];
++ } suspend_state;
++
++ struct resource rscr;
++ struct resource *iomem;
++ int irq;
++};
++
++/*--------------------------------------------------------------------------*/
++
++static int tc6393xb_mmc_enable(struct platform_device *mmc) {
++ struct platform_device *dev = to_platform_device(mmc->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.ck32ken = 1;
++ iowrite16(ccr.raw, &scr->ccr);
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_mmc_disable(struct platform_device *mmc) {
++ struct platform_device *dev = to_platform_device(mmc->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.ck32ken = 0;
++ iowrite16(ccr.raw, &scr->ccr);
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++/*--------------------------------------------------------------------------*/
++
++static int tc6393xb_nand_disable(struct platform_device *nand)
++{
++ return 0;
++}
++
++static int tc6393xb_nand_enable(struct platform_device *nand)
++{
++ struct platform_device *dev = to_platform_device(nand->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ /* SMD buffer on */
++ dev_dbg(&dev->dev, "SMD buffer on\n");
++ iowrite8(0xff, scr->gpi_bcr + 1);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
++{
++ struct platform_device *dev = to_platform_device(fb->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_fer fer;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ fer.raw = ioread8(&scr->fer);
++ fer.bits.slcden = on ? 1 : 0;
++ iowrite8(fer.raw, &scr->fer);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++EXPORT_SYMBOL(tc6393xb_lcd_set_power);
++
++int tc6393xb_lcd_mode(struct platform_device *fb_dev,
++ struct fb_videomode *mode) {
++ struct tc6393xb *tc6393xb =
++ platform_get_drvdata(to_platform_device(fb_dev->dev.parent));
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++
++ iowrite16(mode->pixclock, scr->pll1cr + 0);
++ iowrite16(mode->pixclock >> 16, scr->pll1cr + 1);
++
++ return 0;
++}
++EXPORT_SYMBOL(tc6393xb_lcd_mode);
++
++static int tc6393xb_ohci_disable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ union tc6393xb_scr_fer fer;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ fer.raw = ioread8(&scr->fer);
++ fer.bits.usben = 0;
++ iowrite8(fer.raw, &scr->fer);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.usbcken = 0;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_ohci_enable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ union tc6393xb_scr_fer fer;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.usbcken = 1;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ fer.raw = ioread8(&scr->fer);
++ fer.bits.usben = 1;
++ iowrite8(fer.raw, &scr->fer);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_fb_disable(struct platform_device *fb)
++{
++ struct platform_device *dev = to_platform_device(fb->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ union tc6393xb_scr_fer fer;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ /*
++ * FIXME: is this correct or it should be moved to other _disable?
++ */
++ fer.raw = ioread8(&scr->fer);
++ fer.bits.slcden = 0;
++/* fer.bits.lcdcven = 0; */
++ iowrite8(fer.raw, &scr->fer);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.mclksel = disable;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_fb_enable(struct platform_device *fb)
++{
++ struct platform_device *dev = to_platform_device(fb->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.mclksel = m48MHz;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_fb_suspend(struct platform_device *fb)
++{
++ struct platform_device *dev = to_platform_device(fb->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.mclksel = disable;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_fb_resume(struct platform_device *fb)
++{
++ struct platform_device *dev = to_platform_device(fb->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.mclksel = m48MHz;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static struct resource tc6393xb_mmc_resources[] = {
++ {
++ .name = TMIO_MMC_CONTROL,
++ .start = 0x800,
++ .end = 0x9ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_CONFIG,
++ .start = 0x200,
++ .end = 0x2ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_IRQ,
++ .start = IRQ_TC6393_MMC,
++ .end = IRQ_TC6393_MMC,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++const static struct resource tc6393xb_nand_resources[] = {
++ {
++ .name = TMIO_NAND_CONFIG,
++ .start = 0x0100,
++ .end = 0x01ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_NAND_CONTROL,
++ .start = 0x1000,
++ .end = 0x1007,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_NAND_IRQ,
++ .start = IRQ_TC6393_NAND,
++ .end = IRQ_TC6393_NAND,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++const static struct resource tc6393xb_ohci_resources[] = {
++ {
++ .name = TMIO_OHCI_CONFIG,
++ .start = 0x0300,
++ .end = 0x03ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_CONTROL,
++ .start = 0x3000,
++ .end = 0x31ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_SRAM,
++ .start = 0x010000,
++ .end = 0x017fff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_SRAM_ALIAS,
++ .start = 0x018000,
++ .end = 0x01ffff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_IRQ,
++ .start = IRQ_TC6393_OHCI,
++ .end = IRQ_TC6393_OHCI,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++const static struct resource tc6393xb_fb_resources[] = {
++ {
++ .name = TMIO_FB_CONFIG,
++ .start = 0x0500,
++ .end = 0x05ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_FB_CONTROL,
++ .start = 0x5000,
++ .end = 0x51ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_FB_VRAM,
++ .start = 0x100000,
++ .end = 0x1fffff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_FB_IRQ,
++ .start = IRQ_TC6393_FB,
++ .end = IRQ_TC6393_FB,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++static struct mfd_cell tc6393xb_cells[] = {
++ {
++ .name = "tmio-nand",
++ .enable = tc6393xb_nand_enable,
++ .disable = tc6393xb_nand_disable,
++ .num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
++ .resources = tc6393xb_nand_resources,
++ },
++ {
++ .name = "tmio-ohci",
++ .enable = tc6393xb_ohci_enable,
++ .disable = tc6393xb_ohci_disable,
++ .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
++ .resources = tc6393xb_ohci_resources,
++ },
++ {
++ .name = "tmio-fb",
++ .enable = tc6393xb_fb_enable,
++ .disable = tc6393xb_fb_disable,
++ .suspend = tc6393xb_fb_suspend,
++ .resume = tc6393xb_fb_resume,
++ .num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
++ .resources = tc6393xb_fb_resources,
++ },
++ {
++ .name = "tmio-mmc",
++ .enable = tc6393xb_mmc_enable,
++ .disable = tc6393xb_mmc_disable,
++ .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
++ .resources = tc6393xb_mmc_resources,
++ },
++};
++
++/*--------------------------------------------------------------------------*/
++
++static void
++tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned int isr;
++ unsigned int i;
++
++ desc->chip->ack(irq);
++
++ while ((isr = ioread8(&scr->isr) & ~ioread8(&scr->imr)))
++ for (i = 0; i < TC6393XB_NR_IRQS; i++) {
++ if (isr & (1 << i))
++ desc_handle_irq(tcpd->irq_base + i,
++ irq_desc + tcpd->irq_base + i);
++ }
++}
++
++static void tc6393xb_irq_ack(unsigned int irq)
++{
++}
++
++static void tc6393xb_irq_mask(unsigned int irq)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++ iowrite8(ioread8(&scr->imr) | (1 << (irq - tcpd->irq_base)),
++ &scr->imr);
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++}
++
++static void tc6393xb_irq_unmask(unsigned int irq)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++ iowrite8(ioread8(&scr->imr) & ~(1 << (irq - tcpd->irq_base)),
++ &scr->imr);
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++}
++
++static struct irq_chip tc6393xb_chip = {
++ .name = "tc6393xb",
++ .ack = tc6393xb_irq_ack,
++ .mask = tc6393xb_irq_mask,
++ .unmask = tc6393xb_irq_unmask,
++};
++
++static void tc6393xb_attach_irq(struct platform_device *dev)
++{
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ unsigned int irq;
++
++ for (
++ irq = tcpd->irq_base;
++ irq <= tcpd->irq_base + TC6393XB_NR_IRQS;
++ irq++) {
++ set_irq_chip(irq, &tc6393xb_chip);
++ set_irq_chip_data(irq, dev);
++ set_irq_handler(irq, handle_edge_irq);
++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++ }
++
++ set_irq_type(tc6393xb->irq, IRQT_FALLING);
++ set_irq_chip_data(tc6393xb->irq, dev);
++ set_irq_chained_handler(tc6393xb->irq, tc6393xb_irq);
++}
++
++static void tc6393xb_detach_irq(struct platform_device *dev)
++{
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ unsigned int irq;
++
++ set_irq_chained_handler(tc6393xb->irq, NULL);
++ set_irq_chip_data(tc6393xb->irq, NULL);
++
++ for (
++ irq = tcpd->irq_base;
++ irq <= tcpd->irq_base + TC6393XB_NR_IRQS;
++ irq++) {
++ set_irq_flags(irq, 0);
++ set_irq_chip(irq, NULL);
++ set_irq_chip_data(irq, NULL);
++ }
++}
++
++static int tc6393xb_hw_init(struct platform_device *dev, int resume)
++{
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ int ret;
++ int i;
++
++ if (resume)
++ ret = tcpd->resume(dev);
++ else
++ ret = tcpd->enable(dev);
++ if (ret)
++ return ret;
++
++ iowrite8(resume ?
++ tc6393xb->suspend_state.fer.raw :
++ 0, &scr->fer);
++ iowrite16(tcpd->scr_pll2cr, &scr->pll2cr);
++ iowrite16(resume?
++ tc6393xb->suspend_state.ccr.raw :
++ tcpd->scr_ccr.raw, &scr->ccr);
++ iowrite16(tcpd->scr_mcr.raw, &scr->mcr);
++ iowrite16(tcpd->scr_gper, &scr->gper);
++ iowrite8(0, &scr->irr);
++ iowrite8(0xbf, &scr->imr);
++ iowrite16(tcpd->scr_gpo_dsr, scr->gpo_dsr + 0);
++ iowrite16(tcpd->scr_gpo_dsr >> 16, scr->gpo_dsr + 1);
++ iowrite16(tcpd->scr_gpo_doecr, scr->gpo_doecr + 0);
++ iowrite16(tcpd->scr_gpo_doecr >> 16, scr->gpo_doecr + 1);
++
++ if (resume)
++ for (i = 0; i < 4; i++)
++ iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
++ scr->gpi_bcr + i);
++
++ return 0;
++}
++
++static int __devinit tc6393xb_probe(struct platform_device *dev)
++{
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb;
++ struct resource *iomem;
++ struct resource *rscr;
++ int retval;
++
++ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
++ if (!iomem)
++ return -EINVAL;
++
++ tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
++ if (!tc6393xb) {
++ retval = -ENOMEM;
++ goto err_kzalloc;
++ }
++
++ spin_lock_init(&tc6393xb->lock);
++
++ platform_set_drvdata(dev, tc6393xb);
++ tc6393xb->iomem = iomem;
++ tc6393xb->irq = platform_get_irq(dev, 0);
++
++ rscr = &tc6393xb->rscr;
++ rscr->name = "tc6393xb-core";
++ rscr->start = iomem->start;
++ rscr->end = iomem->start + 0xff;
++ rscr->flags = IORESOURCE_MEM;
++
++ retval = request_resource(iomem, rscr);
++ if (retval)
++ goto err_request_scr;
++
++ tc6393xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
++ if (!tc6393xb->scr) {
++ retval = -ENOMEM;
++ goto err_ioremap;
++ }
++
++ retval = tc6393xb_hw_init(dev, 0);
++ if (retval)
++ goto err_hw_init;
++
++ printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
++ ioread8(&tc6393xb->scr->revid),
++ (unsigned long) iomem->start, tc6393xb->irq);
++
++ if (tc6393xb->irq)
++ tc6393xb_attach_irq(dev);
++
++ tc6393xb_cells[0].driver_data = tcpd->nand_data;
++ tc6393xb_cells[1].driver_data = NULL; /* tcpd->ohci_data; */
++ tc6393xb_cells[2].driver_data = tcpd->fb_data;
++
++ retval = mfd_add_devices(dev,
++ tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
++ iomem, 0, tcpd->irq_base);
++
++ if (retval == 0)
++ return 0;
++
++ if (tc6393xb->irq)
++ tc6393xb_detach_irq(dev);
++
++err_hw_init:
++ iounmap(tc6393xb->scr);
++err_ioremap:
++ release_resource(rscr);
++err_request_scr:
++ kfree(tc6393xb);
++err_kzalloc:
++ release_resource(iomem);
++ return retval;
++}
++
++static int __devexit tc6393xb_remove(struct platform_device *dev) {
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ int ret;
++
++ if (tc6393xb->irq)
++ tc6393xb_detach_irq(dev);
++
++ ret = tcpd->disable(dev);
++
++ iounmap(tc6393xb->scr);
++ release_resource(&tc6393xb->rscr);
++ release_resource(tc6393xb->iomem);
++
++ mfd_remove_devices(dev);
++
++ platform_set_drvdata(dev, NULL);
++
++ kfree(tc6393xb);
++
++ return ret;
++}
++
++#ifdef CONFIG_PM
++static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ int i;
++
++
++ tc6393xb->suspend_state.ccr.raw = ioread16(&scr->ccr);
++ tc6393xb->suspend_state.fer.raw = ioread8(&scr->fer);
++ for (i = 0; i < 4; i++)
++ tc6393xb->suspend_state.gpi_bcr[i] =
++ ioread8(scr->gpi_bcr + i);
++
++ return tcpd->suspend(dev);
++}
++
++static int tc6393xb_resume(struct platform_device *dev)
++{
++ return tc6393xb_hw_init(dev, 1);
++}
++#else
++#define tc6393xb_suspend NULL
++#define tc6393xb_resume NULL
++#endif
++
++static struct platform_driver tc6393xb_driver = {
++ .probe = tc6393xb_probe,
++ .remove = __devexit_p(tc6393xb_remove),
++ .suspend = tc6393xb_suspend,
++ .resume = tc6393xb_resume,
++
++ .driver = {
++ .name = "tc6393xb",
++ .owner = THIS_MODULE,
++ },
++};
++
++static int __init tc6393xb_init(void)
++{
++ return platform_driver_register(&tc6393xb_driver);
++}
++
++static void __exit tc6393xb_exit(void)
++{
++ platform_driver_unregister(&tc6393xb_driver);
++}
++
++module_init(tc6393xb_init);
++module_exit(tc6393xb_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
++MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
+diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
+new file mode 100644
+index 0000000..e699294
+--- /dev/null
++++ b/include/linux/mfd/tc6393xb.h
+@@ -0,0 +1,108 @@
++/*
++ * Toshiba TC6393XB SoC support
++ *
++ * Copyright(c) 2005-2006 Chris Humbert
++ * Copyright(c) 2005 Dirk Opfer
++ * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
++ * Copyright(c) 2007 Dmitry Baryshkov
++ *
++ * Based on code written by Sharp/Lineo for 2.4 kernels
++ * Based on locomo.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef TC6393XB_H
++#define TC6393XB_H
++
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++
++union tc6393xb_scr_fer {
++ u8 raw;
++struct {
++ unsigned usben:1; /* D0 USB enable */
++ unsigned lcdcven:1; /* D1 polysylicon TFT enable */
++ unsigned slcden:1; /* D2 SLCD enable */
++} __attribute__ ((packed)) bits;
++} __attribute__ ((packed));
++
++union tc6393xb_scr_ccr {
++ u16 raw;
++struct {
++ unsigned ck32ken:1; /* D0 SD host clock enable */
++ unsigned usbcken:1; /* D1 USB host clock enable */
++ unsigned x00:2;
++ unsigned sharp:1; /* D4 ??? set in Sharp's code */
++ unsigned x01:3;
++ enum { disable = 0,
++ m12MHz = 1,
++ m24MHz = 2,
++ m48MHz = 3,
++ } mclksel:3; /* D10-D8 LCD controller clock */
++ unsigned x02:1;
++ enum { h24MHz = 0,
++ h48MHz = 1,
++ } hclksel:2; /* D13-D12 host bus clock */
++ unsigned x03:2;
++} __attribute__ ((packed)) bits;
++} __attribute__ ((packed));
++
++enum pincontrol {
++ opendrain = 0,
++ tristate = 1,
++ pushpull = 2,
++ /* reserved = 3, */
++};
++
++union tc6393xb_scr_mcr {
++ u16 raw;
++struct {
++ enum pincontrol rdyst:2; /* D1-D0 HRDY control */
++ unsigned x00:1;
++ unsigned aren:1; /* D3 HRDY pull up resistance cut off */
++ enum pincontrol intst:2; /* D5-D4 #HINT control */
++ unsigned x01:1;
++ unsigned aien:1; /* D7 #HINT pull up resitance cut off */
++ unsigned x02:8;
++} __attribute__ ((packed)) bits;
++} __attribute__ ((packed));
++
++struct tc6393xb_platform_data {
++ u16 scr_pll2cr; /* PLL2 Control */
++ union tc6393xb_scr_ccr scr_ccr; /* Clock Control */
++ union tc6393xb_scr_mcr scr_mcr; /* Mode Control */
++ u16 scr_gper; /* GP Enable */
++ u32 scr_gpo_doecr; /* GPO Data OE Control */
++ u32 scr_gpo_dsr; /* GPO Data Set */
++
++ int (*enable)(struct platform_device *dev);
++ int (*disable)(struct platform_device *dev);
++ int (*suspend)(struct platform_device *dev);
++ int (*resume)(struct platform_device *dev);
++
++ int irq_base; /* a base for cascaded irq */
++
++ struct tmio_nand_data *nand_data;
++ struct tmio_fb_data *fb_data;
++};
++
++extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on);
++extern int tc6393xb_lcd_mode(struct platform_device *fb_dev,
++ struct fb_videomode *mode);
++
++
++/*
++ * Relative to irq_base
++ */
++#define IRQ_TC6393_NAND 0
++#define IRQ_TC6393_MMC 1
++#define IRQ_TC6393_OHCI 2
++#define IRQ_TC6393_SERIAL 3
++#define IRQ_TC6393_FB 4
++
++#define TC6393XB_NR_IRQS 8
++
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch
new file mode 100644
index 0000000000..7183e3af6d
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0005-Add-support-for-tc6387xb-MFD-core.patch
@@ -0,0 +1,249 @@
+From a6a6faf1dbb90c950fe55a1719720457bfb5830a Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sun, 16 Dec 2007 02:19:49 +0000
+Subject: [PATCH 05/64] Add support for tc6387xb MFD core
+
+---
+ drivers/mfd/Kconfig | 6 ++
+ drivers/mfd/Makefile | 1 +
+ drivers/mfd/tc6387xb.c | 163 ++++++++++++++++++++++++++++++++++++++++++
+ include/linux/mfd/tc6387xb.h | 28 +++++++
+ 4 files changed, 198 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mfd/tc6387xb.c
+ create mode 100644 include/linux/mfd/tc6387xb.h
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 9903d0a..1575323 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -9,6 +9,12 @@ config MFD_CORE
+ tristate
+ default n
+
++config MFD_TC6387XB
++ bool "Support Toshiba TC6387XB"
++ select MFD_CORE
++ help
++ Support for Toshiba Mobile IO Controller TC6387XB
++
+ config MFD_TC6393XB
+ bool "Support Toshiba TC6393XB"
+ select MFD_CORE
+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
+index ffd342e..41b2190 100644
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o
+
+ obj-$(CONFIG_MFD_CORE) += mfd-core.o
+
++obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o
+ obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o
+
+ obj-$(CONFIG_MCP) += mcp-core.o
+diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
+new file mode 100644
+index 0000000..c81fca2
+--- /dev/null
++++ b/drivers/mfd/tc6387xb.c
+@@ -0,0 +1,163 @@
++/*
++ * Toshiba TC6387XB support
++ * Copyright (c) 2005 Ian Molton
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * This file contains TC6387XB base support.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <asm/hardware.h>
++#include <asm/mach-types.h>
++
++#include <linux/mfd-core.h>
++#include <linux/mfd/tc6387xb.h>
++
++#ifdef CONFIG_PM
++static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
++
++ if (pdata && pdata->suspend)
++ pdata->suspend(dev);
++
++ return 0;
++}
++
++static int tc6387xb_resume(struct platform_device *dev)
++{
++ struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
++
++ if (pdata && pdata->resume)
++ pdata->resume(dev);
++
++ return 0;
++}
++#else
++#define tc6387xb_suspend NULL
++#define tc6387xb_resume NULL
++#endif
++
++/*--------------------------------------------------------------------------*/
++
++static int tc6387xb_mmc_enable(struct platform_device *mmc) {
++ struct platform_device *dev = to_platform_device(mmc->dev.parent);
++ struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
++
++ if(tc6387xb->enable_mmc_clock)
++ tc6387xb->enable_mmc_clock(dev);
++
++ return 0;
++}
++
++static int tc6387xb_mmc_disable(struct platform_device *mmc) {
++ struct platform_device *dev = to_platform_device(mmc->dev.parent);
++ struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
++
++ if(tc6387xb->disable_mmc_clock)
++ tc6387xb->disable_mmc_clock(dev);
++
++ return 0;
++}
++
++
++/*--------------------------------------------------------------------------*/
++
++static struct resource tc6387xb_mmc_resources[] = {
++ {
++ .name = TMIO_MMC_CONTROL,
++ .start = 0x800,
++ .end = 0x9ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_CONFIG,
++ .start = 0x200,
++ .end = 0x2ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_IRQ,
++ .start = 0,
++ .end = 0,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++static struct mfd_cell tc6387xb_cells[] = {
++ {
++ .name = "tmio-mmc",
++ .enable = tc6387xb_mmc_enable,
++ .disable = tc6387xb_mmc_disable,
++ .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
++ .resources = tc6387xb_mmc_resources,
++ },
++};
++
++static int tc6387xb_probe(struct platform_device *dev)
++{
++ struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
++ struct resource *iomem;
++ int irq;
++
++ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
++ if (!iomem)
++ return -EINVAL;
++
++ irq = platform_get_irq(dev, 0);
++
++ if(data && data->enable)
++ data->enable(dev);
++
++ printk(KERN_INFO "Toshiba tc6393xb initialised\n");
++
++ return mfd_add_devices(dev, tc6387xb_cells, ARRAY_SIZE(tc6387xb_cells),
++ iomem, 0, irq);
++}
++
++static int tc6387xb_remove(struct platform_device *dev)
++{
++ struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
++
++ if(data && data->disable)
++ data->disable(dev);
++
++ return 0;
++}
++
++
++static struct platform_driver tc6387xb_platform_driver = {
++ .driver = {
++ .name = "tc6387xb",
++ },
++ .probe = tc6387xb_probe,
++ .remove = tc6387xb_remove,
++ .suspend = tc6387xb_suspend,
++ .resume = tc6387xb_resume,
++};
++
++
++static int __init tc6387xb_init(void)
++{
++ return platform_driver_register (&tc6387xb_platform_driver);
++}
++
++static void __exit tc6387xb_exit(void)
++{
++ platform_driver_unregister(&tc6387xb_platform_driver);
++}
++
++module_init(tc6387xb_init);
++module_exit(tc6387xb_exit);
++
++MODULE_DESCRIPTION("Toshiba TC6387XB core driver");
++MODULE_LICENSE("GPLv2");
++MODULE_AUTHOR("Ian Molton");
+diff --git a/include/linux/mfd/tc6387xb.h b/include/linux/mfd/tc6387xb.h
+new file mode 100644
+index 0000000..496770b
+--- /dev/null
++++ b/include/linux/mfd/tc6387xb.h
+@@ -0,0 +1,28 @@
++/*
++ * linux/include/asm-arm/hardware/tc6387xb.h
++ *
++ * This file contains the definitions for the TC6393XB
++ *
++ * (C) Copyright 2005 Ian Molton <spyro@f2s.com>
++ *
++ * May be copied or modified under the terms of the GNU General Public
++ * License. See linux/COPYING for more information.
++ *
++ */
++#ifndef MFD_T7L66XB_H
++#define MFD_T7L66XB_H
++
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++
++struct tc6387xb_platform_data
++{
++ int (*enable_mmc_clock)(struct platform_device *dev);
++ int (*disable_mmc_clock)(struct platform_device *dev);
++ int (*enable)(struct platform_device *dev);
++ int (*disable)(struct platform_device *dev);
++ int (*suspend)(struct platform_device *dev);
++ int (*resume)(struct platform_device *dev);
++};
++
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch b/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch
new file mode 100644
index 0000000000..e7aff2455b
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0006-Add-support-for-t7l66xb-MFD-core.patch
@@ -0,0 +1,653 @@
+From 2e31fea352ca97988452f1f2c94809de2977ce40 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sat, 29 Dec 2007 15:08:52 +0000
+Subject: [PATCH 06/64] Add support for t7l66xb MFD core
+
+---
+ drivers/mfd/Kconfig | 6 +
+ drivers/mfd/Makefile | 1 +
+ drivers/mfd/t7l66xb.c | 550 +++++++++++++++++++++++++++++++++++++++++++
+ include/linux/mfd/t7l66xb.h | 45 ++++
+ 4 files changed, 602 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mfd/t7l66xb.c
+ create mode 100644 include/linux/mfd/t7l66xb.h
+
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 1575323..f79a969 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -9,6 +9,12 @@ config MFD_CORE
+ tristate
+ default n
+
++config MFD_T7L66XB
++ bool "Support Toshiba T7L66XB"
++ select MFD_CORE
++ help
++ Support for Toshiba Mobile IO Controller T7L66XB
++
+ config MFD_TC6387XB
+ bool "Support Toshiba TC6387XB"
+ select MFD_CORE
+diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
+index 41b2190..b2037ae 100644
+--- a/drivers/mfd/Makefile
++++ b/drivers/mfd/Makefile
+@@ -6,6 +6,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o
+
+ obj-$(CONFIG_MFD_CORE) += mfd-core.o
+
++obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o
+ obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o
+ obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o
+
+diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
+new file mode 100644
+index 0000000..308776a
+--- /dev/null
++++ b/drivers/mfd/t7l66xb.c
+@@ -0,0 +1,550 @@
++/*
++ *
++ * Toshiba T7L66XB core mfd support
++ *
++ * Copyright (c) 2005 Ian Molton
++ * Copyright (c) 2007 Ian Molton
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * T7L66 features:
++ *
++ * Supported in this driver:
++ * SD/MMC
++ * SM/NAND flash controller
++ * OHCI controller
++ *
++ * As yet not supported
++ * GPIO interface (on NAND pins)
++ * Serial interface
++ * TFT 'interface converter'
++ * PCMCIA interface logic
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <linux/fb.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++#include <linux/mfd/t7l66xb.h>
++
++union t7l66xb_dev_ctl {
++ u8 raw;
++struct {
++ unsigned usb_en:1; /* D0 USB enable */
++ unsigned mmc_en:1; /* D1 MMC enable */
++} __attribute__ ((packed));
++} __attribute__ ((packed));
++
++
++struct t7l66xb_scr {
++ u8 x00[8];
++ u8 revid; /* 0x08 Revision ID */
++ u8 x01[57];
++ u8 imr; /* 0x42 Interrupt Mask */
++ u8 x03[157];
++ union t7l66xb_dev_ctl dev_ctl; /* 0xe0 Device control */
++ u8 isr; /* 0xe1 Interrupt Status */
++ u8 x04[14];
++ u8 gpio_output_ctl; /* 0xf0 */
++ u8 gpio_output_status; /* 0xf1 */
++ u16 gpio_input_status; /* 0xf2 */
++ u8 x05[4];
++ u8 active_pullup_down_ctl; /* 0xf8 */
++ u8 x06[7];
++} __attribute__ ((packed));
++
++
++/*--------------------------------------------------------------------------*/
++
++struct t7l66xb
++{
++ struct t7l66xb_scr __iomem *scr;
++ spinlock_t lock;
++
++ struct resource rscr;
++ struct resource *iomem;
++ int irq;
++};
++
++/*--------------------------------------------------------------------------*/
++
++static int t7l66xb_ohci_enable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ dev_ctl.raw = readb(&scr->dev_ctl);
++ dev_ctl.usb_en = 1;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++static int t7l66xb_ohci_disable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ dev_ctl.raw = readb(&scr->dev_ctl);
++ dev_ctl.usb_en = 0;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++/*--------------------------------------------------------------------------*/
++
++static int t7l66xb_mmc_enable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ if(pdata->enable_clk32k)
++ pdata->enable_clk32k(dev);
++ dev_ctl.raw = readb(&scr->dev_ctl);
++ dev_ctl.mmc_en = 1;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++static int t7l66xb_mmc_disable(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ dev_ctl.raw = readb(&scr->dev_ctl);
++ dev_ctl.mmc_en = 0;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++ if(pdata->disable_clk32k)
++ pdata->disable_clk32k(dev);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++/*--------------------------------------------------------------------------*/
++
++static int t7l66xb_nand_disable(struct platform_device *nand)
++{
++ struct platform_device *dev = to_platform_device(nand->dev.parent);
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ dev_ctl.raw = readb(&scr->dev_ctl);
++// dev_ctl.nand_en = 0;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++static int t7l66xb_nand_enable(struct platform_device *nand)
++{
++ struct platform_device *dev = to_platform_device(nand->dev.parent);
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++ union t7l66xb_dev_ctl dev_ctl;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++
++ dev_ctl.raw = readb(&scr->dev_ctl);
++ // dev_ctl.nand_en = 1;
++ writeb(dev_ctl.raw, &scr->dev_ctl);
++
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++
++ return 0;
++}
++
++/*--------------------------------------------------------------------------*/
++
++const static struct resource t7l66xb_mmc_resources[] = {
++ {
++ .name = TMIO_MMC_CONTROL,
++ .start = 0x800,
++ .end = 0x9ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_CONFIG,
++ .start = 0x200,
++ .end = 0x2ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_MMC_IRQ,
++ .start = IRQ_T7L66XB_MMC,
++ .end = IRQ_T7L66XB_MMC,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++const static struct resource t7l66xb_ohci_resources[] = {
++ {
++ .name = TMIO_OHCI_CONFIG,
++ .start = 0x0300,
++ .end = 0x03ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_CONTROL,
++ .start = 0xa00,
++ .end = 0xbff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_SRAM,
++ .start = 0x01000,
++ .end = 0x02fff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_OHCI_IRQ,
++ .start = IRQ_T7L66XB_OHCI,
++ .end = IRQ_T7L66XB_OHCI,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++const static struct resource t7l66xb_nand_resources[] = {
++ {
++ .name = TMIO_NAND_CONFIG,
++ .start = 0x0100,
++ .end = 0x01ff,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_NAND_CONTROL,
++ .start = 0xc00,
++ .end = 0xc07,
++ .flags = IORESOURCE_MEM,
++ },
++ {
++ .name = TMIO_NAND_IRQ,
++ .start = IRQ_T7L66XB_NAND,
++ .end = IRQ_T7L66XB_NAND,
++ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_MFD_SUBDEVICE,
++ },
++};
++
++static struct mfd_cell t7l66xb_cells[] = {
++ {
++ .name = "tmio-mmc",
++ .enable = t7l66xb_mmc_enable,
++ .disable = t7l66xb_mmc_disable,
++ .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
++ .resources = t7l66xb_mmc_resources,
++ },
++ {
++ .name = "tmio-ohci",
++ .enable = t7l66xb_ohci_enable,
++ .disable = t7l66xb_ohci_disable,
++ .num_resources = ARRAY_SIZE(t7l66xb_ohci_resources),
++ .resources = t7l66xb_ohci_resources,
++ },
++ {
++ .name = "tmio-nand",
++ .enable = t7l66xb_nand_enable,
++ .disable = t7l66xb_nand_disable,
++ .num_resources = ARRAY_SIZE(t7l66xb_nand_resources),
++ .resources = t7l66xb_nand_resources,
++ },
++};
++
++/*--------------------------------------------------------------------------*/
++
++/* Handle the T7L66XB interrupt mux */
++static void t7l66xb_irq(unsigned int irq, struct irq_desc *desc)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned int isr;
++ unsigned int i;
++
++ desc->chip->ack(irq);
++ while ((isr = readb(&scr->isr) & ~readb(&scr->imr)))
++ for (i = 0; i < T7L66XB_NR_IRQS; i++)
++ if (isr & (1 << i))
++ desc_handle_irq(tcpd->irq_base + i,
++ irq_desc + tcpd->irq_base + i);
++}
++
++static void t7l66xb_irq_mask(unsigned int irq)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++ iowrite8(ioread8(&scr->imr) | (1 << (irq - tcpd->irq_base)),
++ &scr->imr);
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++}
++
++static void t7l66xb_irq_unmask(unsigned int irq)
++{
++ struct platform_device *dev = get_irq_chip_data(irq);
++ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ struct t7l66xb_scr __iomem *scr = t7l66xb->scr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&t7l66xb->lock, flags);
++ iowrite8(ioread8(&scr->imr) & ~(1 << (irq - tcpd->irq_base)),
++ &scr->imr);
++ spin_unlock_irqrestore(&t7l66xb->lock, flags);
++}
++
++static struct irq_chip t7l66xb_chip = {
++ .name = "t7l66xb",
++ .ack = t7l66xb_irq_mask,
++ .mask = t7l66xb_irq_mask,
++ .unmask = t7l66xb_irq_unmask,
++};
++
++/*--------------------------------------------------------------------------*/
++
++/* Install the IRQ handler */
++static void t7l66xb_attach_irq(struct platform_device *dev)
++{
++ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ unsigned int irq;
++
++ for (
++ irq = tcpd->irq_base;
++ irq <= tcpd->irq_base + T7L66XB_NR_IRQS;
++ irq++) {
++ set_irq_chip (irq, &t7l66xb_chip);
++ set_irq_chip_data (irq, dev);
++ set_irq_handler(irq, handle_level_irq);
++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
++ }
++
++ set_irq_type (t7l66xb->irq, IRQT_FALLING);
++ set_irq_chip_data (t7l66xb->irq, dev);
++ set_irq_chained_handler (t7l66xb->irq, t7l66xb_irq);
++}
++
++static void t7l66xb_detach_irq(struct platform_device *dev)
++{
++ struct t7l66xb_platform_data *tcpd = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ unsigned int irq;
++
++ set_irq_chained_handler(t7l66xb->irq, NULL);
++ set_irq_chip_data(t7l66xb->irq, NULL);
++
++ for (
++ irq = tcpd->irq_base;
++ irq <= tcpd->irq_base + T7L66XB_NR_IRQS;
++ irq++) {
++ set_irq_flags(irq, 0);
++ set_irq_chip(irq, NULL);
++ set_irq_chip_data(irq, NULL);
++ }
++}
++
++/*--------------------------------------------------------------------------*/
++
++#ifdef CONFIG_PM
++static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++
++
++ if (pdata && pdata->suspend)
++ pdata->suspend(dev);
++
++ return 0;
++}
++
++static int t7l66xb_resume(struct platform_device *dev)
++{
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++
++ if (pdata && pdata->resume)
++ pdata->resume(dev);
++
++ return 0;
++}
++#else
++#define t7l66xb_suspend NULL
++#define t7l66xb_resume NULL
++#endif
++
++/*--------------------------------------------------------------------------*/
++
++static int t7l66xb_probe(struct platform_device *dev)
++{
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb;
++ struct resource *iomem;
++ struct resource *rscr;
++ int retval = -ENOMEM;
++
++ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
++ if (!iomem)
++ return -EINVAL;
++
++ t7l66xb = kzalloc (sizeof *t7l66xb, GFP_KERNEL);
++ if (!t7l66xb)
++ goto err_kzalloc;
++
++ spin_lock_init(&t7l66xb->lock);
++
++ platform_set_drvdata(dev, t7l66xb);
++ t7l66xb->iomem = iomem;
++ t7l66xb->irq = platform_get_irq(dev, 0);
++
++ rscr = &t7l66xb->rscr;
++ rscr->name = "t7l66xb-core";
++ rscr->start = iomem->start;
++ rscr->end = iomem->start + 0xff;
++ rscr->flags = IORESOURCE_MEM;
++
++ if((retval = request_resource(iomem, rscr)))
++ goto err_request_scr;
++
++ t7l66xb->scr = ioremap(rscr->start, rscr->end - rscr->start + 1);
++ if (!t7l66xb->scr) {
++ retval = -ENOMEM;
++ goto err_ioremap;
++ }
++
++ if (pdata && pdata->enable)
++ pdata->enable(dev);
++
++ writeb(0xbf, &t7l66xb->scr->imr); /* Mask all interrupts */
++
++ printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n",
++ dev->name, readb(&t7l66xb->scr->revid),
++ (unsigned long)t7l66xb->scr, t7l66xb->irq);
++
++ if(t7l66xb->irq)
++ t7l66xb_attach_irq(dev);
++
++ t7l66xb_cells[2].driver_data = pdata->nand_data;
++
++ if(!(retval = mfd_add_devices(dev, t7l66xb_cells,
++ ARRAY_SIZE(t7l66xb_cells),
++ iomem, 0, pdata->irq_base)))
++ return 0;
++
++ if(t7l66xb->irq)
++ t7l66xb_detach_irq(dev);
++
++ iounmap(t7l66xb->scr);
++err_ioremap:
++ release_resource(rscr);
++err_request_scr:
++ kfree(t7l66xb);
++err_kzalloc:
++ release_resource(iomem);
++ return retval;
++}
++
++static int t7l66xb_remove(struct platform_device *dev)
++{
++ struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
++ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
++ int ret;
++
++ if (t7l66xb->irq)
++ t7l66xb_detach_irq(dev);
++
++ ret = pdata->disable(dev);
++
++ iounmap(t7l66xb->scr);
++ release_resource(&t7l66xb->rscr);
++ release_resource(t7l66xb->iomem);
++
++ mfd_remove_devices(dev);
++
++ platform_set_drvdata(dev, NULL);
++
++ kfree(t7l66xb);
++
++ return ret;
++
++}
++
++static struct platform_driver t7l66xb_platform_driver = {
++ .driver = {
++ .name = "t7l66xb",
++ .owner = THIS_MODULE,
++ },
++ .suspend = t7l66xb_suspend,
++ .resume = t7l66xb_resume,
++ .probe = t7l66xb_probe,
++ .remove = t7l66xb_remove,
++};
++
++/*--------------------------------------------------------------------------*/
++
++static int __init t7l66xb_init(void)
++{
++ int retval = 0;
++
++ retval = platform_driver_register (&t7l66xb_platform_driver);
++ return retval;
++}
++
++static void __exit t7l66xb_exit(void)
++{
++ platform_driver_unregister(&t7l66xb_platform_driver);
++}
++
++module_init(t7l66xb_init);
++module_exit(t7l66xb_exit);
++
++MODULE_DESCRIPTION("Toshiba T7L66XB core driver");
++MODULE_LICENSE("GPLv2");
++MODULE_AUTHOR("Ian Molton");
++
+diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h
+new file mode 100644
+index 0000000..06b8de5
+--- /dev/null
++++ b/include/linux/mfd/t7l66xb.h
+@@ -0,0 +1,45 @@
++/*
++ * linux/include/asm-arm/hardware/t7l66xb.h
++ *
++ * This file contains the definitions for the T7L66XB
++ *
++ * (C) Copyright 2005 Ian Molton <spyro@f2s.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++#ifndef _ASM_ARCH_T7L66XB_SOC
++#define _ASM_ARCH_T7L66XB_SOC
++
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++
++
++struct t7l66xb_platform_data
++{
++ int (*enable_clk32k)(struct platform_device *dev);
++ int (*disable_clk32k)(struct platform_device *dev);
++
++ int (*enable)(struct platform_device *dev);
++ int (*disable)(struct platform_device *dev);
++ int (*suspend)(struct platform_device *dev);
++ int (*resume)(struct platform_device *dev);
++
++ int irq_base; /* a base for cascaded irq */
++
++ struct tmio_nand_data *nand_data;
++};
++
++
++#define T7L66XB_NAND_CNF_BASE (0x000100)
++#define T7L66XB_NAND_CTL_BASE (0x001000)
++
++#define IRQ_T7L66XB_NAND (3)
++#define IRQ_T7L66XB_MMC (1)
++#define IRQ_T7L66XB_OHCI (2)
++
++#define T7L66XB_NR_IRQS 8
++
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch b/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch
new file mode 100644
index 0000000000..2f5f11400c
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch
@@ -0,0 +1,81 @@
+From d6e8b347dbcce9e0e8d2204b774c1c33cfcb483e Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sat, 29 Dec 2007 15:27:43 +0000
+Subject: [PATCH 07/64] Common headers for TMIO MFD subdevices
+
+---
+ include/linux/mfd/tmio.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 62 insertions(+), 0 deletions(-)
+ create mode 100644 include/linux/mfd/tmio.h
+
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+new file mode 100644
+index 0000000..b42a4c3
+--- /dev/null
++++ b/include/linux/mfd/tmio.h
+@@ -0,0 +1,62 @@
++#ifndef MFD_TMIO_H
++#define MFD_TMIO_H
++
++#include <linux/io.h>
++#include <linux/platform_device.h>
++
++struct fb_videomode;
++
++/*
++ * data for the NAND controller
++ */
++struct tmio_nand_data {
++ struct nand_bbt_descr *badblock_pattern;
++ struct mtd_partition *partition;
++ unsigned int num_partitions;
++};
++
++struct tmio_fb_data {
++ int (*lcd_set_power)(struct platform_device *fb_dev,
++ bool on);
++ int (*lcd_mode)(struct platform_device *fb_dev,
++ struct fb_videomode *mode);
++ int num_modes;
++ struct fb_videomode *modes;
++};
++
++static u32 __maybe_unused tmio_ioread32(const void __iomem *addr)
++{
++ return ((u32) ioread16(addr)) | (((u32) ioread16(addr + 2)) << 16);
++}
++
++static u32 __maybe_unused tmio_iowrite32(u32 val, const void __iomem *addr)
++{
++ iowrite16(val, addr);
++ iowrite16(val >> 16, addr + 2);
++ return val;
++}
++
++#define FBIO_TMIO_ACC_WRITE 0x7C639300
++#define FBIO_TMIO_ACC_SYNC 0x7C639301
++
++#define TMIO_MMC_CONFIG "tmio-mmc-config"
++#define TMIO_MMC_CONTROL "tmio-mmc-control"
++#define TMIO_MMC_IRQ "tmio-mmc"
++
++#define TMIO_NAND_CONFIG "tmio-nand-config"
++#define TMIO_NAND_CONTROL "tmio-nand-control"
++#define TMIO_NAND_IRQ "tmio-nand"
++
++#define TMIO_FB_CONFIG "tmio-fb-config"
++#define TMIO_FB_CONTROL "tmio-fb-control"
++#define TMIO_FB_VRAM "tmio-fb-vram"
++#define TMIO_FB_IRQ "tmio-fb"
++
++#define TMIO_OHCI_CONFIG "tmio-ohci-config"
++#define TMIO_OHCI_CONTROL "tmio-ohci-control"
++#define TMIO_OHCI_SRAM "tmio-ohci-sram"
++#define TMIO_OHCI_SRAM_ALIAS "tmio-ohci-sram-alias"
++#define TMIO_OHCI_IRQ "tmio-ohci"
++
++#endif
++
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch
new file mode 100644
index 0000000000..48b8000ab7
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0008-Nand-driver-for-TMIO-devices.patch
@@ -0,0 +1,608 @@
+From 917b3997a39396f5f51418930de7b933ad053bad Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sat, 29 Dec 2007 15:14:23 +0000
+Subject: [PATCH 08/64] Nand driver for TMIO devices
+
+---
+ drivers/mtd/nand/Kconfig | 7 +
+ drivers/mtd/nand/Makefile | 1 +
+ drivers/mtd/nand/tmio_nand.c | 557 ++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 565 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mtd/nand/tmio_nand.c
+
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 246d451..43e489a 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -284,6 +284,13 @@ config MTD_NAND_CM_X270
+ depends on MTD_NAND && MACH_ARMCORE
+
+
++config MTD_NAND_TMIO
++ tristate "NAND Flash device on Toshiba Mobile IO Controller"
++ depends on MTD_NAND && MFD_CORE
++ help
++ Support for NAND flash connected to a Toshiba Mobile IO
++ Controller in some PDAs, including the Sharp SL6000x.
++
+ config MTD_NAND_NANDSIM
+ tristate "Support for NAND Flash Simulator"
+ depends on MTD_PARTITIONS
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 3ad6c01..d839ebd 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -27,6 +27,7 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
+ obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o
+ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
+ obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
++obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
+ obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
+ obj-$(CONFIG_MTD_ALAUDA) += alauda.o
+
+diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
+new file mode 100644
+index 0000000..450b4ec
+--- /dev/null
++++ b/drivers/mtd/nand/tmio_nand.c
+@@ -0,0 +1,557 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/ioport.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/nand_ecc.h>
++#include <linux/mtd/partitions.h>
++
++/*--------------------------------------------------------------------------*/
++
++/* tmio_nfcr.mode Register Command List */
++#define FCR_MODE_DATA 0x94 /* Data Data_Mode */
++#define FCR_MODE_COMMAND 0x95 /* Data Command_Mode */
++#define FCR_MODE_ADDRESS 0x96 /* Data Address_Mode */
++
++#define FCR_MODE_HWECC_CALC 0xB4 /* HW-ECC Data */
++#define FCR_MODE_HWECC_RESULT 0xD4 /* HW-ECC Calculation Result Read_Mode */
++#define FCR_MODE_HWECC_RESET 0xF4 /* HW-ECC Reset */
++
++#define FCR_MODE_POWER_ON 0x0C /* Power Supply ON to SSFDC card */
++#define FCR_MODE_POWER_OFF 0x08 /* Power Supply OFF to SSFDC card */
++
++#define FCR_MODE_LED_OFF 0x00 /* LED OFF */
++#define FCR_MODE_LED_ON 0x04 /* LED ON */
++
++#define FCR_MODE_EJECT_ON 0x68 /* Ejection Demand from Penguin is Advanced */
++#define FCR_MODE_EJECT_OFF 0x08 /* Ejection Demand from Penguin is Not Advanced */
++
++#define FCR_MODE_LOCK 0x6C /* Operates By Lock_Mode. Ejection Switch is Invalid */
++#define FCR_MODE_UNLOCK 0x0C /* Operates By UnLock_Mode.Ejection Switch is Effective */
++
++#define FCR_MODE_CONTROLLER_ID 0x40 /* Controller ID Read */
++#define FCR_MODE_STANDBY 0x00 /* SSFDC card Changes Standby State */
++
++#define FCR_MODE_WE 0x80
++#define FCR_MODE_ECC1 0x40
++#define FCR_MODE_ECC0 0x20
++#define FCR_MODE_CE 0x10
++#define FCR_MODE_PCNT1 0x08
++#define FCR_MODE_PCNT0 0x04
++#define FCR_MODE_ALE 0x02
++#define FCR_MODE_CLE 0x01
++
++#define FCR_STATUS_BUSY 0x80
++
++/*
++ *NAND Flash Host Controller Configuration Register
++ */
++struct tmio_nfhccr {
++ u8 x00[4];
++ u16 command; /* 0x04 Command */
++ u8 x01[0x0a];
++ u16 base[2]; /* 0x10 NAND Flash Control Reg Base Addr*/
++ u8 x02[0x29];
++ u8 intp; /* 0x3d Interrupt Pin */
++ u8 x03[0x0a];
++ u8 inte; /* 0x48 Interrupt Enable */
++ u8 x04;
++ u8 ec; /* 0x4a Event Control */
++ u8 x05;
++ u8 icc; /* 0x4c Internal Clock Control */
++ u8 x06[0x0e];
++ u8 eccc; /* 0x5b ECC Control */
++ u8 x07[4];
++ u8 nftc; /* 0x60 NAND Flash Transaction Control */
++ u8 nfm; /* 0x61 NAND Flash Monitor */
++ u8 nfpsc; /* 0x62 NAND Flash Power Supply Control */
++ u8 nfdc; /* 0x63 NAND Flash Detect Control */
++ u8 x08[0x9c];
++} __attribute__ ((packed));
++
++/*
++ *NAND Flash Control Register
++ */
++struct tmio_nfcr {
++union {
++ u8 u8; /* 0x00 Data Register */
++ u16 u16;
++ u32 u32;
++} __attribute__ ((packed));
++ u8 mode; /* 0x04 Mode Register */
++ u8 status; /* 0x05 Status Register */
++ u8 isr; /* 0x06 Interrupt Status Register */
++ u8 imr; /* 0x07 Interrupt Mask Register */
++} __attribute__ ((packed));
++
++struct tmio_nand {
++ struct mtd_info mtd;
++ struct nand_chip chip;
++
++ struct platform_device *dev;
++
++ struct tmio_nfhccr __iomem *ccr;
++ struct tmio_nfcr __iomem *fcr;
++
++ unsigned int irq;
++
++ /* for tmio_nand_read_byte */
++ u8 read;
++ unsigned read_good:1;
++};
++
++#define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd)
++
++#ifdef CONFIG_MTD_CMDLINE_PARTS
++static const char *part_probes[] = { "cmdlinepart", NULL };
++#endif
++
++/*--------------------------------------------------------------------------*/
++
++static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd,
++ unsigned int ctrl)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ struct nand_chip *chip = mtd->priv;
++
++ if (ctrl & NAND_CTRL_CHANGE) {
++ u8 mode;
++
++ if (ctrl & NAND_NCE) {
++ mode = FCR_MODE_DATA;
++
++ if (ctrl & NAND_CLE)
++ mode |= FCR_MODE_CLE;
++ else
++ mode &= ~FCR_MODE_CLE;
++
++ if (ctrl & NAND_ALE)
++ mode |= FCR_MODE_ALE;
++ else
++ mode &= ~FCR_MODE_ALE;
++ } else {
++ mode = FCR_MODE_STANDBY;
++ }
++
++ iowrite8(mode, &fcr->mode);
++ tmio->read_good = 0;
++ }
++
++ if (cmd != NAND_CMD_NONE)
++ writeb(cmd, chip->IO_ADDR_W);
++}
++
++static int tmio_nand_dev_ready(struct mtd_info *mtd)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ return !(ioread8(&fcr->status) & FCR_STATUS_BUSY);
++}
++
++static irqreturn_t tmio_irq(int irq, void *__dev)
++{
++ struct platform_device *dev = __dev;
++ struct tmio_nand *tmio = platform_get_drvdata(dev);
++ struct nand_chip *nand_chip = &tmio->chip;
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ /* disable RDYREQ interrupt */
++ iowrite8(0x00, &fcr->imr);
++
++ if (unlikely(!waitqueue_active(&nand_chip->controller->wq)))
++ dev_warn(&dev->dev, "spurious interrupt\n");
++
++ wake_up(&nand_chip->controller->wq);
++ return IRQ_HANDLED;
++}
++
++/*
++ *The TMIO core has a RDYREQ interrupt on the posedge of #SMRB.
++ *This interrupt is normally disabled, but for long operations like
++ *erase and write, we enable it to wake us up. The irq handler
++ *disables the interrupt.
++ */
++static int
++tmio_nand_wait(struct mtd_info *mtd, struct nand_chip *nand_chip)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ long timeout;
++
++ /* enable RDYREQ interrupt */
++ iowrite8(0x0f, &fcr->isr);
++ iowrite8(0x81, &fcr->imr);
++
++ timeout = wait_event_timeout(nand_chip->controller->wq, tmio_nand_dev_ready(mtd),
++ msecs_to_jiffies(nand_chip->state == FL_ERASING ? 400 : 20));
++
++ if (unlikely(!tmio_nand_dev_ready(mtd))) {
++ iowrite8(0x00, &fcr->imr);
++ dev_warn(&tmio->dev->dev, "still busy with %s after %d ms\n",
++ nand_chip->state == FL_ERASING ? "erase" : "program",
++ nand_chip->state == FL_ERASING ? 400 : 20);
++
++ } else if (unlikely(!timeout)) {
++ iowrite8(0x00, &fcr->imr);
++ dev_warn(&tmio->dev->dev, "timeout waiting for interrupt\n");
++ }
++
++ nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
++ return nand_chip->read_byte(mtd);
++}
++
++/*
++ *The TMIO controller combines two 8-bit data bytes into one 16-bit
++ *word. This function separates them so nand_base.c works as expected,
++ *especially its NAND_CMD_READID routines.
++ *
++ *To prevent stale data from being read, tmio_nand_hwcontrol() clears
++ *tmio->read_good.
++ */
++static u_char tmio_nand_read_byte(struct mtd_info *mtd)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ unsigned int data;
++
++ if (tmio->read_good--)
++ return tmio->read;
++
++ data = ioread16(&fcr->u16);
++ tmio->read = data >> 8;
++ return data;
++}
++
++/*
++ *The TMIO controller converts an 8-bit NAND interface to a 16-bit
++ *bus interface, so all data reads and writes must be 16-bit wide.
++ *Thus, we implement 16-bit versions of the read, write, and verify
++ *buffer functions.
++ */
++static void
++tmio_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ iowrite16_rep(&fcr->u16, buf, len >> 1);
++}
++
++static void tmio_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ ioread16_rep(&fcr->u16, buf, len >> 1);
++}
++
++static int
++tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ u16 *p = (u16 *) buf;
++
++ for (len >>= 1; len; len--)
++ if (*(p++) != ioread16(&fcr->u16))
++ return -EFAULT;
++ return 0;
++}
++
++static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ iowrite8(FCR_MODE_HWECC_RESET, &fcr->mode);
++ ioread8(&fcr->u8); /* dummy read */
++ iowrite8(FCR_MODE_HWECC_CALC, &fcr->mode);
++}
++
++static int tmio_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
++ u_char *ecc_code)
++{
++ struct tmio_nand *tmio = mtd_to_tmio(mtd);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ unsigned int ecc;
++
++ iowrite8(FCR_MODE_HWECC_RESULT, &fcr->mode);
++
++ ecc = ioread16(&fcr->u16);
++ ecc_code[1] = ecc; /* 000-255 LP7-0 */
++ ecc_code[0] = ecc >> 8; /* 000-255 LP15-8 */
++ ecc = ioread16(&fcr->u16);
++ ecc_code[2] = ecc; /* 000-255 CP5-0,11b */
++ ecc_code[4] = ecc >> 8; /* 256-511 LP7-0 */
++ ecc = ioread16(&fcr->u16);
++ ecc_code[3] = ecc; /* 256-511 LP15-8 */
++ ecc_code[5] = ecc >> 8; /* 256-511 CP5-0,11b */
++
++ iowrite8(FCR_MODE_DATA, &fcr->mode);
++ return 0;
++}
++
++static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ const struct resource *nfcr = NULL;
++ struct tmio_nfhccr __iomem *ccr = tmio->ccr;
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++ unsigned long base;
++ int i;
++
++ for (i = 0; i < cell->num_resources; i++)
++ if (!strcmp((cell->resources+i)->name, TMIO_NAND_CONTROL))
++ nfcr = &cell->resources[i];
++
++ if (nfcr == NULL)
++ return -ENOMEM;
++
++ if (!cell->enable) {
++ printk(KERN_ERR "null cell enable!");
++ return -EINVAL;
++ }
++
++ cell->enable(dev);
++
++ /* (4Ch) CLKRUN Enable 1st spcrunc */
++ iowrite8(0x81, &ccr->icc);
++
++ /* (10h)BaseAddress 0x1000 spba.spba2 */
++ base = nfcr->start;
++ iowrite16(base, ccr->base + 0);
++ iowrite16(base >> 16, ccr->base + 1);
++
++ /* (04h)Command Register I/O spcmd */
++ iowrite8(0x02, &ccr->command);
++
++ /* (62h) Power Supply Control ssmpwc */
++ /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
++ iowrite8(0x02, &ccr->nfpsc);
++
++ /* (63h) Detect Control ssmdtc */
++ iowrite8(0x02, &ccr->nfdc);
++
++ /* Interrupt status register clear sintst */
++ iowrite8(0x0f, &fcr->isr);
++
++ /* After power supply, Media are reset smode */
++ iowrite8(FCR_MODE_POWER_ON, &fcr->mode);
++ iowrite8(FCR_MODE_COMMAND, &fcr->mode);
++ iowrite8(NAND_CMD_RESET, &fcr->u8);
++
++ /* Standby Mode smode */
++ iowrite8(FCR_MODE_STANDBY, &fcr->mode);
++
++ mdelay(5);
++
++ return 0;
++}
++
++static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_nfcr __iomem *fcr = tmio->fcr;
++
++ iowrite8(FCR_MODE_POWER_OFF, &fcr->mode);
++ cell->disable(dev);
++}
++
++static int tmio_probe(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_nand_data *data = cell->driver_data;
++ struct resource *ccr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONFIG);
++ struct resource *fcr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_NAND_CONTROL);
++ int irq = platform_get_irq(dev, 0);
++ struct tmio_nand *tmio;
++ struct mtd_info *mtd;
++ struct nand_chip *nand_chip;
++ struct mtd_partition *parts;
++ int nbparts = 0;
++ int retval;
++
++ if (data == NULL) {
++ dev_err(&dev->dev, "NULL platform data!\n");
++ return -EINVAL;
++ }
++
++ tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
++ if (!tmio) {
++ retval = -ENOMEM;
++ goto err_kzalloc;
++ }
++
++ tmio->dev = dev;
++
++ platform_set_drvdata(dev, tmio);
++ mtd = &tmio->mtd;
++ nand_chip = &tmio->chip;
++ mtd->priv = nand_chip;
++ mtd->name = "tmio-nand";
++
++ tmio->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
++ if (!tmio->ccr) {
++ retval = -EIO;
++ goto err_iomap_ccr;
++ }
++
++ tmio->fcr = ioremap(fcr->start, fcr->end - fcr->start + 1);
++ if (!tmio->fcr) {
++ retval = -EIO;
++ goto err_iomap_fcr;
++ }
++
++ retval = tmio_hw_init(dev, tmio);
++ if (retval)
++ goto err_hwinit;
++
++ /* Set address of NAND IO lines */
++ nand_chip->IO_ADDR_R = tmio->fcr;
++ nand_chip->IO_ADDR_W = tmio->fcr;
++
++ /* Set address of hardware control function */
++ nand_chip->cmd_ctrl = tmio_nand_hwcontrol;
++ nand_chip->dev_ready = tmio_nand_dev_ready;
++ nand_chip->read_byte = tmio_nand_read_byte;
++ nand_chip->write_buf = tmio_nand_write_buf;
++ nand_chip->read_buf = tmio_nand_read_buf;
++ nand_chip->verify_buf = tmio_nand_verify_buf;
++
++ /* set eccmode using hardware ECC */
++ nand_chip->ecc.mode = NAND_ECC_HW;
++ nand_chip->ecc.size = 512;
++ nand_chip->ecc.bytes = 6;
++ nand_chip->ecc.hwctl = tmio_nand_enable_hwecc;
++ nand_chip->ecc.calculate = tmio_nand_calculate_ecc;
++ nand_chip->ecc.correct = nand_correct_data;
++ nand_chip->badblock_pattern = data->badblock_pattern;
++
++ /* 15 us command delay time */
++ nand_chip->chip_delay = 15;
++
++ retval = request_irq(irq, &tmio_irq,
++ IRQF_DISABLED, dev->dev.bus_id, dev);
++ if (retval) {
++ dev_err(&dev->dev, "request_irq error %d\n", retval);
++ goto err_irq;
++ }
++
++ tmio->irq = irq;
++ nand_chip->waitfunc = tmio_nand_wait;
++
++ /* Scan to find existence of the device */
++ if (nand_scan(mtd, 1)) {
++ retval = -ENODEV;
++ goto err_scan;
++ }
++ /* Register the partitions */
++#ifdef CONFIG_MTD_PARTITIONS
++#ifdef CONFIG_MTD_CMDLINE_PARTS
++ nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
++#endif
++ if (nbparts <= 0) {
++ parts = data->partition;
++ nbparts = data->num_partitions;
++ }
++
++ retval = add_mtd_partitions(mtd, parts, nbparts);
++#else
++ retval = add_mtd_device(mtd);
++#endif
++
++ if (!retval)
++ return retval;
++
++ nand_release(mtd);
++
++err_scan:
++ if (tmio->irq)
++ free_irq(tmio->irq, dev);
++err_irq:
++ tmio_hw_stop(dev, tmio);
++err_hwinit:
++ iounmap(tmio->fcr);
++err_iomap_fcr:
++ iounmap(tmio->ccr);
++err_iomap_ccr:
++ kfree(tmio);
++err_kzalloc:
++ return retval;
++}
++
++static int tmio_remove(struct platform_device *dev)
++{
++ struct tmio_nand *tmio = platform_get_drvdata(dev);
++
++ nand_release(&tmio->mtd);
++ if (tmio->irq)
++ free_irq(tmio->irq, tmio);
++ tmio_hw_stop(dev, tmio);
++ iounmap(tmio->fcr);
++ iounmap(tmio->ccr);
++ kfree(tmio);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int tmio_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++
++ if (cell->suspend)
++ cell->suspend(dev);
++
++ tmio_hw_stop(dev, platform_get_drvdata(dev));
++ return 0;
++}
++
++static int tmio_resume(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++
++ tmio_hw_init(dev, platform_get_drvdata(dev));
++
++ if (cell->resume)
++ cell->resume(dev);
++
++ return 0;
++}
++#endif
++
++static struct platform_driver tmio_driver = {
++ .driver.name = "tmio-nand",
++ .driver.owner = THIS_MODULE,
++ .probe = tmio_probe,
++ .remove = tmio_remove,
++#ifdef CONFIG_PM
++ .suspend = tmio_suspend,
++ .resume = tmio_resume,
++#endif
++};
++
++static int __init tmio_init(void)
++{
++ return platform_driver_register(&tmio_driver);
++}
++
++static void __exit tmio_exit(void)
++{
++ platform_driver_unregister(&tmio_driver);
++}
++
++module_init(tmio_init);
++module_exit(tmio_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Dirk Opfer, Chris Humbert, Dmitry Baryshkov");
++MODULE_DESCRIPTION("NAND flash driver on Toshiba Mobile IO controller");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch
new file mode 100644
index 0000000000..5fc96f8973
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0009-FB-driver-for-TMIO-devices.patch
@@ -0,0 +1,1128 @@
+From 519d015892ab0a7cad1f6b26fcd38117171384ce Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Tue, 1 Jan 2008 21:22:23 +0000
+Subject: [PATCH 09/64] FB driver for TMIO devices
+
+---
+ drivers/video/Kconfig | 22 +
+ drivers/video/Makefile | 1 +
+ drivers/video/tmiofb.c | 1062 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 1085 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/video/tmiofb.c
+
+diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
+index 5b3dbcf..6d0df58 100644
+--- a/drivers/video/Kconfig
++++ b/drivers/video/Kconfig
+@@ -1782,6 +1782,28 @@ config FB_W100
+
+ If unsure, say N.
+
++config FB_TMIO
++ tristate "Toshiba Mobice IO FrameBuffer support"
++ depends on FB && MFD_CORE
++ select FB_CFB_FILLRECT
++ select FB_CFB_COPYAREA
++ select FB_CFB_IMAGEBLIT
++ ---help---
++ Frame buffer driver for the Toshiba Mobile IO integrated as found
++ on the Sharp SL-6000 series
++
++ This driver is also available as a module ( = code which can be
++ inserted and removed from the running kernel whenever you want). The
++ module will be called tmiofb. If you want to compile it as a module,
++ say M here and read <file:Documentation/kbuild/modules.txt>.
++
++ If unsure, say N.
++
++config FB_TMIO_ACCELL
++ bool "tmiofb acceleration"
++ depends on FB_TMIO
++ default y
++
+ config FB_S3C2410
+ tristate "S3C2410 LCD framebuffer support"
+ depends on FB && ARCH_S3C2410
+diff --git a/drivers/video/Makefile b/drivers/video/Makefile
+index 83e02b3..74e9384 100644
+--- a/drivers/video/Makefile
++++ b/drivers/video/Makefile
+@@ -97,6 +97,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
+ obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
+ obj-$(CONFIG_FB_PXA) += pxafb.o
+ obj-$(CONFIG_FB_W100) += w100fb.o
++obj-$(CONFIG_FB_TMIO) += tmiofb.o
+ obj-$(CONFIG_FB_AU1100) += au1100fb.o
+ obj-$(CONFIG_FB_AU1200) += au1200fb.o
+ obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
+diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
+new file mode 100644
+index 0000000..6b963a1
+--- /dev/null
++++ b/drivers/video/tmiofb.c
+@@ -0,0 +1,1062 @@
++/*
++ * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
++ *
++ * Copyright(C) 2005-2006 Chris Humbert
++ * Copyright(C) 2005 Dirk Opfer
++ *
++ * Based on:
++ * drivers/video/w100fb.c
++ * code written by Sharp/Lineo for 2.4 kernels
++ *
++ * 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.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++#include <linux/fb.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++/* Why should fb driver call console functions? because acquire_console_sem() */
++#include <linux/console.h>
++#include <linux/uaccess.h>
++#include <linux/vmalloc.h>
++
++/*
++ * accelerator commands
++ */
++#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe))
++#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe))
++#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe))
++#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff))
++#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe))
++#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe))
++#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff))
++#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff))
++#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff))
++
++#define TMIOFB_ACC_CMGO 0x20000000
++#define TMIOFB_ACC_CMGO_CEND 0x00000001
++#define TMIOFB_ACC_CMGO_INT 0x00000002
++#define TMIOFB_ACC_CMGO_CMOD 0x00000010
++#define TMIOFB_ACC_CMGO_CDVRV 0x00000020
++#define TMIOFB_ACC_CMGO_CDHRV 0x00000040
++#define TMIOFB_ACC_CMGO_RUND 0x00008000
++#define TMIOFB_ACC_SCGO 0x21000000
++#define TMIOFB_ACC_SCGO_CEND 0x00000001
++#define TMIOFB_ACC_SCGO_INT 0x00000002
++#define TMIOFB_ACC_SCGO_ROP3 0x00000004
++#define TMIOFB_ACC_SCGO_TRNS 0x00000008
++#define TMIOFB_ACC_SCGO_DVRV 0x00000010
++#define TMIOFB_ACC_SCGO_DHRV 0x00000020
++#define TMIOFB_ACC_SCGO_SVRV 0x00000040
++#define TMIOFB_ACC_SCGO_SHRV 0x00000080
++#define TMIOFB_ACC_SCGO_DSTXY 0x00008000
++#define TMIOFB_ACC_SBGO 0x22000000
++#define TMIOFB_ACC_SBGO_CEND 0x00000001
++#define TMIOFB_ACC_SBGO_INT 0x00000002
++#define TMIOFB_ACC_SBGO_DVRV 0x00000010
++#define TMIOFB_ACC_SBGO_DHRV 0x00000020
++#define TMIOFB_ACC_SBGO_SVRV 0x00000040
++#define TMIOFB_ACC_SBGO_SHRV 0x00000080
++#define TMIOFB_ACC_SBGO_SBMD 0x00000100
++#define TMIOFB_ACC_FLGO 0x23000000
++#define TMIOFB_ACC_FLGO_CEND 0x00000001
++#define TMIOFB_ACC_FLGO_INT 0x00000002
++#define TMIOFB_ACC_FLGO_ROP3 0x00000004
++#define TMIOFB_ACC_LDGO 0x24000000
++#define TMIOFB_ACC_LDGO_CEND 0x00000001
++#define TMIOFB_ACC_LDGO_INT 0x00000002
++#define TMIOFB_ACC_LDGO_ROP3 0x00000004
++#define TMIOFB_ACC_LDGO_ENDPX 0x00000008
++#define TMIOFB_ACC_LDGO_LVRV 0x00000010
++#define TMIOFB_ACC_LDGO_LHRV 0x00000020
++#define TMIOFB_ACC_LDGO_LDMOD 0x00000040
++
++/* a FIFO is always allocated, even if acceleration is not used */
++#define TMIOFB_FIFO_SIZE 512
++
++/*
++ * LCD Host Controller Configuration Register
++ *
++ * This iomem area supports only 16-bit IO.
++ */
++struct tmio_lhccr {
++ u16 x00[2];
++ u16 cmd; /* 0x04 Command */
++ u16 x01;
++ u16 revid; /* 0x08 Revision ID */
++ u16 x02[3];
++ u16 basel; /* 0x10 LCD Control Reg Base Addr Low */
++ u16 baseh; /* 0x12 LCD Control Reg Base Addr High */
++ u16 x03[0x16];
++ u16 ugcc; /* 0x40 Unified Gated Clock Control */
++ u16 gcc; /* 0x42 Gated Clock Control */
++ u16 x04[6];
++ u16 usc; /* 0x50 Unified Software Clear */
++ u16 x05[7];
++ u16 vramrtc; /* 0x60 VRAM Timing Control */
++ /* 0x61 VRAM Refresh Control */
++ u16 vramsac; /* 0x62 VRAM Access Control */
++ /* 0x63 VRAM Status */
++ u16 vrambc; /* 0x64 VRAM Block Control */
++ u16 x06[0x4d];
++};
++
++/*
++ * LCD Control Register
++ *
++ * This iomem area supports only 16-bit IO.
++ */
++struct tmio_lcr {
++ u16 uis; /* 0x000 Unified Interrupt Status */
++ u16 x00[3];
++ u16 vhpn; /* 0x008 VRAM Horizontal Pixel Number */
++ u16 cfsal; /* 0x00a Command FIFO Start Address Low */
++ u16 cfsah; /* 0x00c Command FIFO Start Address High */
++ u16 cfs; /* 0x00e Command FIFO Size */
++ u16 cfws; /* 0x010 Command FIFO Writeable Size */
++ u16 bbie; /* 0x012 BitBLT Interrupt Enable */
++ u16 bbisc; /* 0x014 BitBLT Interrupt Status and Clear */
++ u16 ccs; /* 0x016 Command Count Status */
++ u16 bbes; /* 0x018 BitBLT Execution Status */
++ u16 x01;
++ u16 cmdl; /* 0x01c Command Low */
++ u16 cmdh; /* 0x01e Command High */
++ u16 x02;
++ u16 cfc; /* 0x022 Command FIFO Clear */
++ u16 ccifc; /* 0x024 CMOS Camera IF Control */
++ u16 hwt; /* 0x026 Hardware Test */
++ u16 x03[0x6c];
++ u16 lcdccrc;/* 0x100 LCDC Clock and Reset Control */
++ u16 lcdcc; /* 0x102 LCDC Control */
++ u16 lcdcopc;/* 0x104 LCDC Output Pin Control */
++ u16 x04;
++ u16 lcdis; /* 0x108 LCD Interrupt Status */
++ u16 lcdim; /* 0x10a LCD Interrupt Mask */
++ u16 lcdie; /* 0x10c LCD Interrupt Enable */
++ u16 x05[10];
++ u16 gdsal; /* 0x122 Graphics Display Start Address Low */
++ u16 gdsah; /* 0x124 Graphics Display Start Address High */
++ u16 x06[2];
++ u16 vhpcl; /* 0x12a VRAM Horizontal Pixel Count Low */
++ u16 vhpch; /* 0x12c VRAM Horizontal Pixel Count High */
++ u16 gm; /* 0x12e Graphic Mode(VRAM access enable) */
++ u16 x07[8];
++ u16 ht; /* 0x140 Horizontal Total */
++ u16 hds; /* 0x142 Horizontal Display Start */
++ u16 hss; /* 0x144 H-Sync Start */
++ u16 hse; /* 0x146 H-Sync End */
++ u16 x08[2];
++ u16 hnp; /* 0x14c Horizontal Number of Pixels */
++ u16 x09;
++ u16 vt; /* 0x150 Vertical Total */
++ u16 vds; /* 0x152 Vertical Display Start */
++ u16 vss; /* 0x154 V-Sync Start */
++ u16 vse; /* 0x156 V-Sync End */
++ u16 x0a[4];
++ u16 cdln; /* 0x160 Current Display Line Number */
++ u16 iln; /* 0x162 Interrupt Line Number */
++ u16 sp; /* 0x164 Sync Polarity */
++ u16 misc; /* 0x166 MISC(RGB565 mode) */
++ u16 x0b;
++ u16 vihss; /* 0x16a Video Interface H-Sync Start */
++ u16 vivs; /* 0x16c Video Interface Vertical Start */
++ u16 vive; /* 0x16e Video Interface Vertical End */
++ u16 vivss; /* 0x170 Video Interface V-Sync Start */
++ u16 x0c[6];
++ u16 vccis; /* 0x17e Video / CMOS Camera Interface Select */
++ u16 vidwsal;/* 0x180 VI Data Write Start Address Low */
++ u16 vidwsah;/* 0x182 VI Data Write Start Address High */
++ u16 vidrsal;/* 0x184 VI Data Read Start Address Low */
++ u16 vidrsah;/* 0x186 VI Data Read Start Address High */
++ u16 vipddst;/* 0x188 VI Picture Data Display Start Timing */
++ u16 vipddet;/* 0x186 VI Picture Data Display End Timing */
++ u16 vie; /* 0x18c Video Interface Enable */
++ u16 vcs; /* 0x18e Video/Camera Select */
++ u16 x0d[2];
++ u16 vphwc; /* 0x194 Video Picture Horizontal Wait Count */
++ u16 vphs; /* 0x196 Video Picture Horizontal Size */
++ u16 vpvwc; /* 0x198 Video Picture Vertical Wait Count */
++ u16 vpvs; /* 0x19a Video Picture Vertical Size */
++ u16 x0e[2];
++ u16 plhpix; /* 0x1a0 PLHPIX */
++ u16 xs; /* 0x1a2 XStart */
++ u16 xckhw; /* 0x1a4 XCK High Width */
++ u16 x0f;
++ u16 sths; /* 0x1a8 STH Start */
++ u16 vt2; /* 0x1aa Vertical Total */
++ u16 ycksw; /* 0x1ac YCK Start Wait */
++ u16 ysts; /* 0x1ae YST Start */
++ u16 ppols; /* 0x1b0 #PPOL Start */
++ u16 precw; /* 0x1b2 PREC Width */
++ u16 vclkhw; /* 0x1b4 VCLK High Width */
++ u16 oc; /* 0x1b6 Output Control */
++ u16 x10[0x24];
++};
++static char *mode_option __devinitdata;
++
++struct tmiofb_par {
++ u32 pseudo_palette[16];
++
++#ifdef CONFIG_FB_TMIO_ACCELL
++ wait_queue_head_t wait_acc;
++ bool use_polling;
++#endif
++
++ struct tmio_lhccr __iomem *ccr;
++ struct tmio_lcr __iomem *lcr;
++ void __iomem *vram;
++};
++
++/*--------------------------------------------------------------------------*/
++
++static irqreturn_t tmiofb_irq(int irq, void *__info);
++
++/*--------------------------------------------------------------------------*/
++
++
++/*
++ * Turns off the LCD controller and LCD host controller.
++ */
++static int tmiofb_hw_stop(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_fb_data *data = cell->driver_data;
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct tmiofb_par *par = info->par;
++ struct tmio_lhccr __iomem *ccr = par->ccr;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++
++ iowrite16(0, &ccr->ugcc);
++ iowrite16(0, &lcr->gm);
++ data->lcd_set_power(dev, 0);
++ iowrite16(0x0010, &lcr->lcdccrc);
++
++ return 0;
++}
++
++/*
++ * Initializes the LCD host controller.
++ */
++static int tmiofb_hw_init(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_fb_data *data = cell->driver_data;
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct tmiofb_par *par = info->par;
++ struct tmio_lhccr __iomem *ccr = par->ccr;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++ const struct resource *nlcr = NULL;
++ const struct resource *vram = NULL;
++ unsigned long base;
++ int i;
++
++ for (i = 0; i < cell->num_resources; i++) {
++ if (!strcmp((cell->resources+i)->name, TMIO_FB_CONTROL))
++ nlcr = &cell->resources[i];
++ if (!strcmp((cell->resources+i)->name, TMIO_FB_VRAM))
++ vram = &cell->resources[i];
++ }
++
++ if (nlcr == NULL || vram == NULL)
++ return -EINVAL;
++
++ base = nlcr->start;
++
++ if (info->mode == NULL) {
++ printk(KERN_ERR "tmio-fb: null info->mode\n");
++ info->mode = data->modes;
++ }
++
++ data->lcd_mode(dev, info->mode);
++
++ iowrite16(0x003a, &ccr->ugcc);
++ iowrite16(0x003a, &ccr->gcc);
++ iowrite16(0x3f00, &ccr->usc);
++
++ data->lcd_set_power(dev, 1);
++ mdelay(2);
++
++ iowrite16(0x0000, &ccr->usc);
++ iowrite16(base >> 16, &ccr->baseh);
++ iowrite16(base, &ccr->basel);
++ iowrite16(0x0002, &ccr->cmd); /* base address enable */
++ iowrite16(0x40a8, &ccr->vramrtc); /* VRAMRC, VRAMTC */
++ iowrite16(0x0018, &ccr->vramsac); /* VRAMSTS, VRAMAC */
++ iowrite16(0x0002, &ccr->vrambc);
++ mdelay(2);
++ iowrite16(0x000b, &ccr->vrambc);
++
++ base = vram->start + info->screen_size;
++ iowrite16(base >> 16, &lcr->cfsah);
++ iowrite16(base, &lcr->cfsal);
++ iowrite16(TMIOFB_FIFO_SIZE - 1, &lcr->cfs);
++ iowrite16(1, &lcr->cfc);
++ iowrite16(1, &lcr->bbie);
++ iowrite16(0, &lcr->cfws);
++
++ return 0;
++}
++
++/*
++ * Sets the LCD controller's output resolution and pixel clock
++ */
++static void tmiofb_hw_mode(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_fb_data *data = cell->driver_data;
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct fb_videomode *mode = info->mode;
++ struct tmiofb_par *par = info->par;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++ unsigned int i;
++
++ iowrite16(0, &lcr->gm);
++ data->lcd_set_power(dev, 0);
++ iowrite16(0x0010, &lcr->lcdccrc);
++ data->lcd_mode(dev, mode);
++ data->lcd_set_power(dev, 1);
++
++ iowrite16(i = mode->xres * 2, &lcr->vhpn);
++ iowrite16(0, &lcr->gdsah);
++ iowrite16(0, &lcr->gdsal);
++ iowrite16(i >> 16, &lcr->vhpch);
++ iowrite16(i, &lcr->vhpcl);
++ iowrite16(i = 0, &lcr->hss);
++ iowrite16(i += mode->hsync_len, &lcr->hse);
++ iowrite16(i += mode->left_margin, &lcr->hds);
++ iowrite16(i += mode->xres + mode->right_margin, &lcr->ht);
++ iowrite16(mode->xres, &lcr->hnp);
++ iowrite16(i = 0, &lcr->vss);
++ iowrite16(i += mode->vsync_len, &lcr->vse);
++ iowrite16(i += mode->upper_margin, &lcr->vds);
++ iowrite16(i += mode->yres, &lcr->iln);
++ iowrite16(i += mode->lower_margin, &lcr->vt);
++ iowrite16(3, /* RGB565 mode */ &lcr->misc);
++ iowrite16(1, /* VRAM enable */ &lcr->gm);
++ iowrite16(0x4007, &lcr->lcdcc);
++ iowrite16(3, /* sync polarity */ &lcr->sp);
++
++ iowrite16(0x0010, &lcr->lcdccrc);
++ mdelay(5);
++ iowrite16(0x0014, &lcr->lcdccrc); /* STOP_CKP */
++ mdelay(5);
++ iowrite16(0x0015, &lcr->lcdccrc); /* STOP_CKP | SOFT_RESET */
++ iowrite16(0xfffa, &lcr->vcs);
++}
++
++/*--------------------------------------------------------------------------*/
++
++#ifdef CONFIG_FB_TMIO_ACCELL
++static int __must_check
++tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
++{
++ struct tmiofb_par *par = info->par;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++ if (in_atomic() || par->use_polling) {
++ int i = 0;
++ while (ioread16(&lcr->ccs) > ccs) {
++ udelay(1);
++ i++;
++ if (i > 10000) {
++ printk(KERN_ERR "tmiofb: timeout waiting for %d\n", ccs);
++ return -ETIMEDOUT;
++ }
++ tmiofb_irq(-1, info);
++ }
++ } else {
++ if (!wait_event_interruptible_timeout(par->wait_acc,
++ ioread16(&par->lcr->ccs) <= ccs, 1000)) {
++ printk(KERN_ERR "tmiofb: timeout waiting for %d\n", ccs);
++ return -ETIMEDOUT;
++ }
++ }
++
++ return 0;
++}
++
++/*
++ * Writes an accelerator command to the accelerator's FIFO.
++ */
++static int
++tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
++{
++ struct tmiofb_par *par = info->par;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++ int ret;
++
++ ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
++ if (ret)
++ return ret;
++
++ for (; count; count--, cmd++) {
++ iowrite16(*cmd >> 16, &lcr->cmdh);
++ iowrite16(*cmd, &lcr->cmdl);
++ }
++
++ return ret;
++}
++
++/*
++ * Wait for the accelerator to finish its operations before writing
++ * to the framebuffer for consistent display output.
++ */
++static int tmiofb_sync(struct fb_info *fbi)
++{
++ struct tmiofb_par *par = fbi->par;
++
++ int ret;
++ int i = 0;
++
++ ret = tmiofb_acc_wait(fbi, 0);
++
++ while (ioread16(&par->lcr->bbes) & 2) { /* blit active */
++ udelay(1);
++ i++ ;
++ if (i > 10000) {
++ printk(KERN_ERR "timeout waiting for blit to end!\n");
++ return -ETIMEDOUT;
++ }
++ }
++
++ return ret;
++}
++
++static void
++tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
++{
++ const u32 cmd [] = {
++ TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
++ TMIOFB_ACC_DHPIX(rect->width - 1),
++ TMIOFB_ACC_DVPIX(rect->height - 1),
++ TMIOFB_ACC_FILL(rect->color),
++ TMIOFB_ACC_FLGO,
++ };
++
++ if (fbi->state != FBINFO_STATE_RUNNING ||
++ fbi->flags & FBINFO_HWACCEL_DISABLED) {
++ cfb_fillrect(fbi, rect);
++ return;
++ }
++
++ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
++}
++
++static void
++tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
++{
++ const u32 cmd [] = {
++ TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
++ TMIOFB_ACC_DHPIX(area->width - 1),
++ TMIOFB_ACC_DVPIX(area->height - 1),
++ TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
++ TMIOFB_ACC_SCGO,
++ };
++
++ if (fbi->state != FBINFO_STATE_RUNNING ||
++ fbi->flags & FBINFO_HWACCEL_DISABLED) {
++ cfb_copyarea(fbi, area);
++ return;
++ }
++
++ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
++}
++#endif
++
++static void tmiofb_clearscreen(struct fb_info *info)
++{
++ const struct fb_fillrect rect = {
++ .dx = 0,
++ .dy = 0,
++ .width = info->mode->xres,
++ .height = info->mode->yres,
++ .color = 0,
++ };
++
++ info->fbops->fb_fillrect(info, &rect);
++}
++
++static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
++{
++ struct tmiofb_par *par = fbi->par;
++ struct fb_videomode *mode = fbi->mode;
++ unsigned int vcount = ioread16(&par->lcr->cdln);
++ unsigned int vds = mode->vsync_len + mode->upper_margin;
++
++ vblank->vcount = vcount;
++ vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
++ | FB_VBLANK_HAVE_VSYNC;
++
++ if (vcount < mode->vsync_len)
++ vblank->flags |= FB_VBLANK_VSYNCING;
++
++ if (vcount < vds || vcount > vds + mode->yres)
++ vblank->flags |= FB_VBLANK_VBLANKING;
++
++ return 0;
++}
++
++
++static int tmiofb_ioctl(struct fb_info *fbi,
++ unsigned int cmd, unsigned long arg)
++{
++ switch (cmd) {
++ case FBIOGET_VBLANK: {
++ struct fb_vblank vblank = {0};
++ void __user *argp = (void __user *) arg;
++
++ tmiofb_vblank(fbi, &vblank);
++ if (copy_to_user(argp, &vblank, sizeof vblank))
++ return -EFAULT;
++ return 0;
++ }
++
++#ifdef CONFIG_FB_TMIO_ACCELL
++ case FBIO_TMIO_ACC_SYNC:
++ tmiofb_sync(fbi);
++ return 0;
++
++ case FBIO_TMIO_ACC_WRITE: {
++ u32 __user *argp = (void __user *) arg;
++ u32 len;
++ u32 acc [16];
++
++ if (copy_from_user(&len, argp, sizeof(u32)))
++ return -EFAULT;
++ if (len > ARRAY_SIZE(acc))
++ return -EINVAL;
++ if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
++ return -EFAULT;
++
++ return tmiofb_acc_write(fbi, acc, len);
++ }
++#endif
++ }
++
++ return -EINVAL;
++}
++
++/*--------------------------------------------------------------------------*/
++
++/* Select the smallest mode that allows the desired resolution to be
++ * displayed. If desired, the x and y parameters can be rounded up to
++ * match the selected mode.
++ */
++static struct fb_videomode*
++tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
++{
++ struct mfd_cell *cell = mfd_get_cell(to_platform_device(info->device));
++ struct tmio_fb_data *data = cell->driver_data;
++ struct fb_videomode *best = NULL;
++ int i;
++
++ for (i = 0; i < data->num_modes; i++) {
++ struct fb_videomode *mode = data->modes + i;
++
++ if (mode->xres >= var->xres && mode->yres >= var->yres
++ && (!best || (mode->xres < best->xres
++ && mode->yres < best->yres)))
++ best = mode;
++ }
++
++ return best;
++}
++
++static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
++{
++
++ struct fb_videomode *mode;
++
++ mode = tmiofb_find_mode(info, var);
++ if (!mode || var->bits_per_pixel > 16)
++ return -EINVAL;
++
++ fb_videomode_to_var(var, mode);
++
++ var->xres_virtual = mode->xres;
++ var->yres_virtual = info->screen_size / (mode->xres * 2);
++ var->xoffset = 0;
++ var->yoffset = 0;
++ var->bits_per_pixel = 16;
++ var->grayscale = 0;
++ var->red.offset = 11; var->red.length = 5;
++ var->green.offset = 5; var->green.length = 6;
++ var->blue.offset = 0; var->blue.length = 5;
++ var->transp.offset = 0; var->transp.length = 0;
++ var->nonstd = 0;
++ var->height = 82; /* mm */
++ var->width = 60; /* mm */
++ var->rotate = 0;
++ return 0;
++}
++
++static int tmiofb_set_par(struct fb_info *info)
++{
++/* struct fb_var_screeninfo *var = &info->var;
++ struct fb_videomode *mode;
++
++ mode = tmiofb_find_mode(info, var);
++ if (!mode)
++ return -EINVAL;
++
++ if (info->mode == mode)
++ return 0;
++
++ info->mode = mode; */
++ info->fix.line_length = info->mode->xres * 2;
++
++ tmiofb_hw_mode(to_platform_device(info->device));
++ tmiofb_clearscreen(info);
++ return 0;
++}
++
++static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
++ unsigned blue, unsigned transp,
++ struct fb_info *info)
++{
++ struct tmiofb_par *par = info->par;
++
++ if (regno < ARRAY_SIZE(par->pseudo_palette)) {
++ par->pseudo_palette [regno] =
++ ((red & 0xf800)) |
++ ((green & 0xfc00) >> 5) |
++ ((blue & 0xf800) >> 11);
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct fb_ops tmiofb_ops = {
++ .owner = THIS_MODULE,
++
++ .fb_ioctl = tmiofb_ioctl,
++ .fb_check_var = tmiofb_check_var,
++ .fb_set_par = tmiofb_set_par,
++ .fb_setcolreg = tmiofb_setcolreg,
++ .fb_imageblit = cfb_imageblit,
++#ifdef CONFIG_FB_TMIO_ACCELL
++ .fb_sync = tmiofb_sync,
++ .fb_fillrect = tmiofb_fillrect,
++ .fb_copyarea = tmiofb_copyarea,
++#else
++ .fb_fillrect = cfb_fillrect,
++ .fb_copyarea = cfb_copyarea,
++#endif
++};
++
++/*--------------------------------------------------------------------------*/
++
++/*
++ * reasons for an interrupt:
++ * uis bbisc lcdis
++ * 0100 0001 accelerator command completed
++ * 2000 0001 vsync start
++ * 2000 0002 display start
++ * 2000 0004 line number match(0x1ff mask???)
++ */
++static irqreturn_t tmiofb_irq(int irq, void *__info)
++{
++ struct fb_info *info = __info;
++ struct tmiofb_par *par = info->par;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++ unsigned int bbisc = ioread16(&lcr->bbisc);
++
++
++ if (unlikely(par->use_polling && irq != -1)) {
++ printk(KERN_INFO "tmiofb: switching to waitq\n");
++ par->use_polling = false;
++ }
++
++ iowrite16(bbisc, &lcr->bbisc);
++
++#ifdef CONFIG_FB_TMIO_ACCELL
++ if (bbisc & 1)
++ wake_up(&par->wait_acc);
++#endif
++
++ return IRQ_HANDLED;
++}
++
++static int tmiofb_probe(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_fb_data *data = cell->driver_data;
++ struct resource *ccr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_CONFIG);
++ struct resource *lcr = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_CONTROL);
++ struct resource *vram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_FB_VRAM);
++ int irq = platform_get_irq(dev, 0);
++ struct fb_info *info;
++ struct tmiofb_par *par;
++ int retval;
++
++ if (data == NULL) {
++ dev_err(&dev->dev, "NULL platform data!\n");
++ return -EINVAL;
++ }
++
++ info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
++
++ if (!info) {
++ retval = -ENOMEM;
++ goto err_framebuffer_alloc;
++ }
++
++ par = info->par;
++ platform_set_drvdata(dev, info);
++
++#ifdef CONFIG_FB_TMIO_ACCELL
++ init_waitqueue_head(&par->wait_acc);
++
++ par->use_polling = true;
++
++ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
++ | FBINFO_HWACCEL_FILLRECT;
++#else
++ info->flags = FBINFO_DEFAULT;
++#endif
++
++ info->fbops = &tmiofb_ops;
++
++ strcpy(info->fix.id, "tmio-fb");
++ info->fix.smem_start = vram->start;
++ info->fix.smem_len = vram->end - vram->start + 1;
++ info->fix.type = FB_TYPE_PACKED_PIXELS;
++ info->fix.visual = FB_VISUAL_TRUECOLOR;
++ info->fix.mmio_start = lcr->start;
++ info->fix.mmio_len = lcr->end - lcr->start + 1;
++ info->fix.accel = FB_ACCEL_NONE;
++ info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
++ info->pseudo_palette = par->pseudo_palette;
++
++ par->ccr = ioremap(ccr->start, ccr->end - ccr->start + 1);
++ if (!par->ccr) {
++ retval = -ENOMEM;
++ goto err_ioremap_ccr;
++ }
++
++ par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
++ if (!par->lcr) {
++ retval = -ENOMEM;
++ goto err_ioremap_lcr;
++ }
++
++ par->vram = ioremap(info->fix.smem_start, info->fix.smem_len);
++ if (!par->vram) {
++ retval = -ENOMEM;
++ goto err_ioremap_vram;
++ }
++ info->screen_base = par->vram;
++
++ retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
++ dev->dev.bus_id, info);
++
++ if (retval)
++ goto err_request_irq;
++
++ retval = fb_find_mode(&info->var, info, mode_option,
++ data->modes, data->num_modes,
++ data->modes, 16);
++ if (!retval) {
++ retval = -EINVAL;
++ goto err_find_mode;
++ }
++
++ retval = cell->enable(dev);
++ if (retval)
++ goto err_enable;
++
++ retval = tmiofb_hw_init(dev);
++ if (retval)
++ goto err_hw_init;
++
++/* retval = tmiofb_set_par(info);
++ if (retval)
++ goto err_set_par;*/
++
++ retval = register_framebuffer(info);
++ if (retval < 0)
++ goto err_register_framebuffer;
++
++ printk(KERN_INFO "fb%d: %s frame buffer device\n",
++ info->node, info->fix.id);
++
++ return 0;
++
++err_register_framebuffer:
++/*err_set_par:*/
++ tmiofb_hw_stop(dev);
++err_hw_init:
++ cell->disable(dev);
++err_enable:
++err_find_mode:
++ free_irq(irq, info);
++err_request_irq:
++ iounmap(par->vram);
++err_ioremap_vram:
++ iounmap(par->lcr);
++err_ioremap_lcr:
++ iounmap(par->ccr);
++err_ioremap_ccr:
++ platform_set_drvdata(dev, NULL);
++ framebuffer_release(info);
++err_framebuffer_alloc:
++ return retval;
++}
++
++static int __devexit tmiofb_remove(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct fb_info *info = platform_get_drvdata(dev);
++ int irq = platform_get_irq(dev, 0);
++ struct tmiofb_par *par;
++
++ if (info) {
++ par = info->par;
++ unregister_framebuffer(info);
++
++ tmiofb_hw_stop(dev);
++
++ cell->disable(dev);
++
++ free_irq(irq, info);
++
++ iounmap(par->vram);
++ iounmap(par->lcr);
++ iounmap(par->ccr);
++
++ framebuffer_release(info);
++ platform_set_drvdata(dev, NULL);
++ }
++
++ return 0;
++}
++
++#if 0
++static void tmiofb_dump_regs(struct platform_device *dev)
++{
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct tmiofb_par *par = info->par;
++ struct tmio_lhccr __iomem *ccr = par->ccr;
++ struct tmio_lcr __iomem *lcr = par->lcr;
++
++ printk("lhccr:\n");
++#define CCR_PR(n) printk("\t" #n " = \t%04x\n", ioread16(&ccr->n));
++ CCR_PR(cmd);
++ CCR_PR(revid);
++ CCR_PR(basel);
++ CCR_PR(baseh);
++ CCR_PR(ugcc);
++ CCR_PR(gcc);
++ CCR_PR(usc);
++ CCR_PR(vramrtc);
++ CCR_PR(vramsac);
++ CCR_PR(vrambc);
++#undef CCR_PR
++
++ printk("lcr: \n");
++#define LCR_PR(n) printk("\t" #n " = \t%04x\n", ioread16(&lcr->n));
++ LCR_PR(uis);
++ LCR_PR(vhpn);
++ LCR_PR(cfsal);
++ LCR_PR(cfsah);
++ LCR_PR(cfs);
++ LCR_PR(cfws);
++ LCR_PR(bbie);
++ LCR_PR(bbisc);
++ LCR_PR(ccs);
++ LCR_PR(bbes);
++ LCR_PR(cmdl);
++ LCR_PR(cmdh);
++ LCR_PR(cfc);
++ LCR_PR(ccifc);
++ LCR_PR(hwt);
++ LCR_PR(lcdccrc);
++ LCR_PR(lcdcc);
++ LCR_PR(lcdcopc);
++ LCR_PR(lcdis);
++ LCR_PR(lcdim);
++ LCR_PR(lcdie);
++ LCR_PR(gdsal);
++ LCR_PR(gdsah);
++ LCR_PR(vhpcl);
++ LCR_PR(vhpch);
++ LCR_PR(gm);
++ LCR_PR(ht);
++ LCR_PR(hds);
++ LCR_PR(hss);
++ LCR_PR(hse);
++ LCR_PR(hnp);
++ LCR_PR(vt);
++ LCR_PR(vds);
++ LCR_PR(vss);
++ LCR_PR(vse);
++ LCR_PR(cdln);
++ LCR_PR(iln);
++ LCR_PR(sp);
++ LCR_PR(misc);
++ LCR_PR(vihss);
++ LCR_PR(vivs);
++ LCR_PR(vive);
++ LCR_PR(vivss);
++ LCR_PR(vccis);
++ LCR_PR(vidwsal);
++ LCR_PR(vidwsah);
++ LCR_PR(vidrsal);
++ LCR_PR(vidrsah);
++ LCR_PR(vipddst);
++ LCR_PR(vipddet);
++ LCR_PR(vie);
++ LCR_PR(vcs);
++ LCR_PR(vphwc);
++ LCR_PR(vphs);
++ LCR_PR(vpvwc);
++ LCR_PR(vpvs);
++ LCR_PR(plhpix);
++ LCR_PR(xs);
++ LCR_PR(xckhw);
++ LCR_PR(sths);
++ LCR_PR(vt2);
++ LCR_PR(ycksw);
++ LCR_PR(ysts);
++ LCR_PR(ppols);
++ LCR_PR(precw);
++ LCR_PR(vclkhw);
++ LCR_PR(oc);
++#undef LCR_PR
++}
++#endif
++
++#ifdef CONFIG_PM
++static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct tmiofb_par *par = info->par;
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ int retval = 0;
++
++ acquire_console_sem();
++
++ fb_set_suspend(info, 1);
++
++ if (info->fbops->fb_sync)
++ info->fbops->fb_sync(info);
++
++
++ printk(KERN_INFO "tmiofb: switching to polling\n");
++ par->use_polling = true;
++ tmiofb_hw_stop(dev);
++
++ if (cell->suspend)
++ retval = cell->suspend(dev);
++
++ release_console_sem();
++
++ return retval;
++}
++
++static int tmiofb_resume(struct platform_device *dev)
++{
++ struct fb_info *info = platform_get_drvdata(dev);
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ int retval;
++
++ acquire_console_sem();
++
++ if (cell->resume) {
++ retval = cell->resume(dev);
++ if (retval)
++ return retval;
++ }
++
++ tmiofb_irq(-1, info);
++
++ tmiofb_hw_init(dev);
++
++ tmiofb_hw_mode(dev);
++
++ fb_set_suspend(info, 0);
++ release_console_sem();
++ return 0;
++}
++#endif
++
++static struct platform_driver tmiofb_driver = {
++ .driver.name = "tmio-fb",
++ .driver.owner = THIS_MODULE,
++ .probe = tmiofb_probe,
++ .remove = __devexit_p(tmiofb_remove),
++#ifdef CONFIG_PM
++ .suspend = tmiofb_suspend,
++ .resume = tmiofb_resume,
++#endif
++};
++
++/*--------------------------------------------------------------------------*/
++
++#ifndef MODULE
++static void __init tmiofb_setup(char *options)
++{
++ char *this_opt;
++
++ if (!options || !*options)
++ return;
++
++ while ((this_opt = strsep(&options, ",")) != NULL) {
++ if (!*this_opt) continue;
++ /*
++ * FIXME
++ */
++ }
++}
++#endif
++
++static int __init tmiofb_init(void)
++{
++#ifndef MODULE
++ char *option = NULL;
++
++ if (fb_get_options("tmiofb", &option))
++ return -ENODEV;
++ tmiofb_setup(option);
++#endif
++ return platform_driver_register(&tmiofb_driver);
++}
++
++static void __exit tmiofb_cleanup(void)
++{
++ platform_driver_unregister(&tmiofb_driver);
++}
++
++module_init(tmiofb_init);
++module_exit(tmiofb_cleanup);
++
++MODULE_DESCRIPTION("TMIO framebuffer driver");
++MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
++MODULE_LICENSE("GPL");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch
new file mode 100644
index 0000000000..f358c069d0
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0010-OHCI-driver-for-TMIO-devices.patch
@@ -0,0 +1,431 @@
+From e5f06830bc8d3ef4792c9c0569825d0347b39852 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Fri, 4 Jan 2008 18:43:31 +0000
+Subject: [PATCH 10/64] OHCI driver for TMIO devices
+
+---
+ drivers/usb/Kconfig | 1 +
+ drivers/usb/host/Kconfig | 1 +
+ drivers/usb/host/ohci-hcd.c | 5 +
+ drivers/usb/host/ohci-tmio.c | 369 ++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 376 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/usb/host/ohci-tmio.c
+
+diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
+index 7580aa5..8912042 100644
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -36,6 +36,7 @@ config USB_ARCH_HAS_OHCI
+ default y if ARCH_EP93XX
+ default y if ARCH_AT91
+ default y if ARCH_PNX4008
++ default y if MFD_TC6393XB
+ # PPC:
+ default y if STB03xxx
+ default y if PPC_MPC52xx
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 49a91c5..5ae3589 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -101,6 +101,7 @@ config USB_OHCI_HCD
+ depends on USB && USB_ARCH_HAS_OHCI
+ select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+ select I2C if ARCH_PNX4008
++ select DMABOUNCE if MFD_TC6393XB
+ ---help---
+ The Open Host Controller Interface (OHCI) is a standard for accessing
+ USB 1.1 host controller hardware. It does more in hardware than Intel's
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index ecfe800..77abf3e 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -1043,6 +1043,11 @@ MODULE_LICENSE ("GPL");
+ #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver
+ #endif
+
++#ifdef CONFIG_MFD_TC6393XB
++#include "ohci-tmio.c"
++#define PLATFORM_DRIVER ohci_hcd_tmio_driver
++#endif
++
+ #ifdef CONFIG_USB_OHCI_HCD_SSB
+ #include "ohci-ssb.c"
+ #define SSB_OHCI_DRIVER ssb_ohci_driver
+diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
+new file mode 100644
+index 0000000..be609f3
+--- /dev/null
++++ b/drivers/usb/host/ohci-tmio.c
+@@ -0,0 +1,369 @@
++/*
++ * OHCI HCD(Host Controller Driver) for USB.
++ *
++ *(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
++ *(C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
++ *(C) Copyright 2002 Hewlett-Packard Company
++ *
++ * Bus glue for Toshiba Mobile IO(TMIO) Controller's OHCI core
++ *(C) Copyright 2005 Chris Humbert <mahadri-usb@drigon.com>
++ *
++ * This is known to work with the following variants:
++ * TC6393XB revision 3 (32kB SRAM)
++ *
++ * The TMIO's OHCI core DMAs through a small internal buffer that
++ * is directly addressable by the CPU. dma_declare_coherent_memory
++ * and DMA bounce buffers allow the higher-level OHCI host driver to
++ * work. However, the dma API doesn't handle dma mapping failures
++ * well(dma_sg_map() is a prime example), so it is unusable.
++ *
++ * This HC pretends be a PIO-ish controller and uses the kernel's
++ * generic allocator for the entire SRAM. Using the USB core's
++ * usb_operations, we provide hcd_buffer_alloc/free. Using the OHCI's
++ * ohci_ops, we provide memory management for OHCI's TDs and EDs. We
++ * internally queue a URB's TDs until enough dma memory is available
++ * to enqueue them with the HC.
++ *
++ * Written from sparse documentation from Toshiba and Sharp's driver
++ * for the 2.4 kernel,
++ * usb-ohci-tc6393.c(C) Copyright 2004 Lineo Solutions, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++/*#include <linux/fs.h>
++#include <linux/mount.h>
++#include <linux/pagemap.h>
++#include <linux/init.h>
++#include <linux/namei.h>
++#include <linux/sched.h>*/
++#include <linux/platform_device.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++#include <linux/dma-mapping.h>
++
++/*-------------------------------------------------------------------------*/
++
++/*
++ * USB Host Controller Configuration Register
++ */
++struct tmio_uhccr {
++ u8 x00[8];
++ u8 revid; /* 0x08 Revision ID */
++ u8 x01[7];
++ u16 basel; /* 0x10 USB Control Register Base Address Low */
++ u16 baseh; /* 0x12 USB Control Register Base Address High */
++ u8 x02[0x2c];
++ u8 ilme; /* 0x40 Internal Local Memory Enable */
++ u8 x03[0x0b];
++ u16 pm; /* 0x4c Power Management */
++ u8 x04[2];
++ u8 intc; /* 0x50 INT Control */
++ u8 x05[3];
++ u16 lmw1l; /* 0x54 Local Memory Window 1 LMADRS Low */
++ u16 lmw1h; /* 0x56 Local Memory Window 1 LMADRS High */
++ u16 lmw1bl; /* 0x58 Local Memory Window 1 Base Address Low */
++ u16 lmw1bh; /* 0x5A Local Memory Window 1 Base Address High */
++ u16 lmw2l; /* 0x5C Local Memory Window 2 LMADRS Low */
++ u16 lmw2h; /* 0x5E Local Memory Window 2 LMADRS High */
++ u16 lmw2bl; /* 0x60 Local Memory Window 2 Base Address Low */
++ u16 lmw2bh; /* 0x62 Local Memory Window 2 Base Address High */
++ u8 x06[0x98];
++ u8 misc; /* 0xFC MISC */
++ u8 x07[3];
++} __attribute__((packed));
++
++#define UHCCR_PM_GKEN 0x0001
++#define UHCCR_PM_CKRNEN 0x0002
++#define UHCCR_PM_USBPW1 0x0004
++#define UHCCR_PM_USBPW2 0x0008
++#define UHCCR_PM_PMEE 0x0100
++#define UHCCR_PM_PMES 0x8000
++
++/*-------------------------------------------------------------------------*/
++
++struct tmio_hcd {
++ struct tmio_uhccr __iomem *ccr;
++};
++
++#define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1))
++#define ohci_to_tmio(ohci) ((struct tmio_hcd *)(ohci + 1))
++
++/*-------------------------------------------------------------------------*/
++
++static void tmio_stop_hc(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ struct tmio_uhccr __iomem *ccr = tmio->ccr;
++ u16 pm;
++
++ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | UHCCR_PM_USBPW1 | UHCCR_PM_USBPW2;
++ iowrite8(0, &ccr->intc);
++ iowrite8(0, &ccr->ilme);
++ iowrite16(0, &ccr->basel);
++ iowrite16(0, &ccr->baseh);
++ iowrite16(pm, &ccr->pm);
++
++ cell->disable(dev);
++}
++
++static void tmio_start_hc(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ struct tmio_uhccr __iomem *ccr = tmio->ccr;
++ u16 pm;
++ unsigned long base = hcd->rsrc_start;
++
++ pm = UHCCR_PM_CKRNEN | UHCCR_PM_GKEN | UHCCR_PM_PMEE | UHCCR_PM_PMES;
++ cell->enable(dev);
++
++ iowrite16(pm, &ccr->pm);
++ iowrite16(base, &ccr->basel);
++ iowrite16(base >> 16, &ccr->baseh);
++ iowrite8(1, &ccr->ilme);
++ iowrite8(2, &ccr->intc);
++
++ dev_info(&dev->dev, "revision %d @ 0x%08llx, irq %d\n",
++ ioread8(&ccr->revid), hcd->rsrc_start, hcd->irq);
++}
++
++static int usb_hcd_tmio_probe(const struct hc_driver *driver,
++ struct platform_device *dev)
++{
++ struct resource *config = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONFIG);
++ struct resource *regs = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONTROL);
++ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM);
++ int irq = platform_get_irq(dev, 0);
++ struct tmio_hcd *tmio;
++ struct ohci_hcd *ohci;
++ struct usb_hcd *hcd;
++ int retval;
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ hcd = usb_create_hcd(driver, &dev->dev, dev->dev.bus_id);
++ if (!hcd) {
++ retval = -ENOMEM;
++ goto err_usb_create_hcd;
++ }
++
++ hcd->rsrc_start = regs->start;
++ hcd->rsrc_len = regs->end - regs->start + 1;
++
++ tmio = hcd_to_tmio(hcd);
++
++ tmio->ccr = ioremap(config->start, config->end - config->start + 1);
++ if (!tmio->ccr) {
++ retval = -ENOMEM;
++ goto err_ioremap_ccr;
++ }
++
++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
++ if (!hcd->regs) {
++ retval = -ENOMEM;
++ goto err_ioremap_regs;
++ }
++
++ if (dma_declare_coherent_memory(&dev->dev, sram->start,
++ sram->start,
++ sram->end - sram->start + 1,
++ DMA_MEMORY_MAP) != DMA_MEMORY_MAP) {
++ retval = -EBUSY;
++ goto err_dma_declare;
++ }
++
++ retval = dmabounce_register_dev(&dev->dev, 512, 4096);
++ if (retval)
++ goto err_dmabounce_register_dev;
++
++ tmio_start_hc(dev);
++ ohci = hcd_to_ohci(hcd);
++ ohci_hcd_init(ohci);
++
++ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
++
++ if (retval == 0)
++ return retval;
++
++ tmio_stop_hc(dev);
++
++ dmabounce_unregister_dev(&dev->dev);
++err_dmabounce_register_dev:
++ dma_release_declared_memory(&dev->dev);
++err_dma_declare:
++ iounmap(hcd->regs);
++err_ioremap_regs:
++ iounmap(tmio->ccr);
++err_ioremap_ccr:
++ usb_put_hcd(hcd);
++err_usb_create_hcd:
++
++ return retval;
++}
++
++static void usb_hcd_tmio_remove(struct usb_hcd *hcd, struct platform_device *dev)
++{
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++
++ usb_remove_hcd(hcd);
++ tmio_stop_hc(dev);
++ dmabounce_unregister_dev(&dev->dev);
++ dma_release_declared_memory(&dev->dev);
++ iounmap(hcd->regs);
++ iounmap(tmio->ccr);
++ usb_put_hcd(hcd);
++}
++
++static int __devinit
++ohci_tmio_start(struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++ int retval;
++
++ if ((retval = ohci_init(ohci)) < 0)
++ return retval;
++
++ if ((retval = ohci_run(ohci)) < 0) {
++ err("can't start %s", hcd->self.bus_name);
++ ohci_stop(hcd);
++ return retval;
++ }
++
++ return 0;
++}
++
++static const struct hc_driver ohci_tmio_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "TMIO OHCI USB Host Controller",
++ .hcd_priv_size = sizeof(struct ohci_hcd) + sizeof (struct tmio_hcd),
++
++ /* generic hardware linkage */
++ .irq = ohci_irq,
++ .flags = HCD_USB11 | HCD_MEMORY,
++
++ /* basic lifecycle operations */
++ .start = ohci_tmio_start,
++ .stop = ohci_stop,
++ .shutdown = ohci_shutdown,
++
++ /* managing i/o requests and associated device resources */
++ .urb_enqueue = ohci_urb_enqueue,
++ .urb_dequeue = ohci_urb_dequeue,
++ .endpoint_disable = ohci_endpoint_disable,
++
++ /* scheduling support */
++ .get_frame_number = ohci_get_frame,
++
++ /* root hub support */
++ .hub_status_data = ohci_hub_status_data,
++ .hub_control = ohci_hub_control,
++ .hub_irq_enable = ohci_rhsc_enable,
++#ifdef CONFIG_PM
++ .bus_suspend = ohci_bus_suspend,
++ .bus_resume = ohci_bus_resume,
++#endif
++ .start_port_reset = ohci_start_port_reset,
++};
++
++/*-------------------------------------------------------------------------*/
++static struct platform_driver ohci_hcd_tmio_driver;
++
++static int
++tmio_dmabounce_check(struct device *dev, dma_addr_t dma, size_t size, void *data)
++{
++ struct resource *sram = data;
++#ifdef DEBUG
++ printk(KERN_ERR "tmio_dmabounce_check: %08x %d\n", dma, size);
++#endif
++
++ if (dev->driver != &ohci_hcd_tmio_driver.driver)
++ return 0;
++
++ if (sram->start <= dma && dma + size <= sram->end)
++ return 0;
++
++ return 1;
++}
++
++static u64 dma_mask = DMA_32BIT_MASK;
++
++static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
++{
++ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM);
++
++ dev->dev.dma_mask = &dma_mask;
++ dev->dev.coherent_dma_mask = DMA_32BIT_MASK;
++
++ dmabounce_register_checker(tmio_dmabounce_check, sram);
++
++ return usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev);
++}
++
++static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM);
++
++ usb_hcd_tmio_remove(hcd, dev);
++
++ platform_set_drvdata(dev, NULL);
++
++ dmabounce_remove_checker(tmio_dmabounce_check, sram);
++
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++
++ tmio_stop_hc(dev);
++ hcd->state = HC_STATE_SUSPENDED;
++ dev->dev.power.power_state = PMSG_SUSPEND;
++
++ return 0;
++}
++
++static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++ if (time_before(jiffies, ohci->next_statechange))
++ msleep(5);
++ ohci->next_statechange = jiffies;
++
++ tmio_start_hc(dev);
++
++ dev->dev.power.power_state = PMSG_ON;
++ usb_hcd_resume_root_hub(hcd);
++
++ return 0;
++}
++#endif
++
++static struct platform_driver ohci_hcd_tmio_driver = {
++ .probe = ohci_hcd_tmio_drv_probe,
++ .remove = ohci_hcd_tmio_drv_remove,
++ .shutdown = usb_hcd_platform_shutdown,
++#ifdef CONFIG_PM
++ .suspend = ohci_hcd_tmio_drv_suspend,
++ .resume = ohci_hcd_tmio_drv_resume,
++#endif
++ .driver = {
++ .name = "tmio-ohci",
++ },
++};
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch b/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch
new file mode 100644
index 0000000000..6ff752d1ff
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0011-MMC-driver-for-TMIO-devices.patch
@@ -0,0 +1,891 @@
+From b358a64c1fdd1eb80da57f919c893d910db95e37 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Sat, 29 Dec 2007 15:26:19 +0000
+Subject: [PATCH 11/64] MMC driver for TMIO devices
+
+---
+ drivers/mmc/host/Kconfig | 6 +
+ drivers/mmc/host/Makefile | 1 +
+ drivers/mmc/host/tmio_mmc.c | 633 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/host/tmio_mmc.h | 205 ++++++++++++++
+ 4 files changed, 845 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/mmc/host/tmio_mmc.c
+ create mode 100644 drivers/mmc/host/tmio_mmc.h
+
+diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
+index 5fef678..f8f9b7e 100644
+--- a/drivers/mmc/host/Kconfig
++++ b/drivers/mmc/host/Kconfig
+@@ -130,3 +130,9 @@ config MMC_SPI
+
+ If unsure, or if your system has no SPI master driver, say N.
+
++config MMC_TMIO
++ tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
++ depends on MMC
++ help
++ This provides support for the SD/MMC cell found in TC6393XB,
++ T7L66XB and also ipaq ASIC3
+diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
+index 3877c87..7ac956b 100644
+--- a/drivers/mmc/host/Makefile
++++ b/drivers/mmc/host/Makefile
+@@ -17,4 +17,5 @@ obj-$(CONFIG_MMC_OMAP) += omap.o
+ obj-$(CONFIG_MMC_AT91) += at91_mci.o
+ obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
+ obj-$(CONFIG_MMC_SPI) += mmc_spi.o
++obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
+
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+new file mode 100644
+index 0000000..735c386
+--- /dev/null
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -0,0 +1,633 @@
++/*
++ * linux/drivers/mmc/tmio_mmc.c
++ *
++ * Copyright (C) 2004 Ian Molton
++ * Copyright (C) 2007 Ian Molton
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Driver for the MMC / SD / SDIO cell found in:
++ *
++ * TC6393XB TC6391XB TC6387XB T7L66XB
++ *
++ * This driver draws mainly on scattered spec sheets, Reverse engineering
++ * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
++ * support). (Further 4 bit support from a later datasheet).
++ *
++ * TODO:
++ * Investigate using a workqueue for PIO transfers
++ * Eliminate FIXMEs
++ * SDIO support
++ * Better Power management
++ * Handle MMC errors better
++ * double buffer support
++ *
++ */
++#include <linux/module.h>
++#include <linux/irq.h>
++#include <linux/device.h>
++#include <linux/delay.h>
++#include <linux/mmc/mmc.h>
++#include <linux/mmc/host.h>
++#include <linux/mfd-core.h>
++#include <linux/mfd/tmio.h>
++
++#include "tmio_mmc.h"
++
++/*
++ * Fixme - documentation conflicts on what the clock values are for the
++ * various dividers.
++ * One document I have says that its a divisor of a 24MHz clock, another 33.
++ * This probably depends on HCLK for a given platform, so we may need to
++ * require HCLK be passed to us from the MFD core.
++ *
++ */
++
++static void tmio_mmc_set_clock (struct tmio_mmc_host *host, int new_clock) {
++ struct tmio_mmc_cnf __iomem *cnf = host->cnf;
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ u32 clk = 0, clock;
++
++ if (new_clock) {
++ for(clock = 46875, clk = 0x100; new_clock >= (clock<<1); ){
++ clock <<= 1;
++ clk >>= 1;
++ }
++ if(clk & 0x1)
++ clk = 0x20000;
++
++ clk >>= 2;
++ if(clk & 0x8000) /* For full speed we disable the divider. */
++ writeb(0, &cnf->sd_clk_mode);
++ else
++ writeb(1, &cnf->sd_clk_mode);
++ clk |= 0x100;
++ }
++
++ writew(clk, &ctl->sd_card_clk_ctl);
++}
++
++static void tmio_mmc_clk_stop (struct tmio_mmc_host *host) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ writew(0x0000, &ctl->clk_and_wait_ctl);
++ msleep(10);
++ writew(readw(&ctl->sd_card_clk_ctl) & ~0x0100, &ctl->sd_card_clk_ctl);
++ msleep(10);
++}
++
++static void tmio_mmc_clk_start (struct tmio_mmc_host *host) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ writew(readw(&ctl->sd_card_clk_ctl) | 0x0100, &ctl->sd_card_clk_ctl);
++ msleep(10);
++ writew(0x0100, &ctl->clk_and_wait_ctl);
++ msleep(10);
++}
++
++static void reset(struct tmio_mmc_host *host) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ /* FIXME - should we set stop clock reg here */
++ writew(0x0000, &ctl->reset_sd);
++ writew(0x0000, &ctl->reset_sdio);
++ msleep(10);
++ writew(0x0001, &ctl->reset_sd);
++ writew(0x0001, &ctl->reset_sdio);
++ msleep(10);
++}
++
++static void
++tmio_mmc_finish_request(struct tmio_mmc_host *host)
++{
++ struct mmc_request *mrq = host->mrq;
++
++ host->mrq = NULL;
++ host->cmd = NULL;
++ host->data = NULL;
++
++ mmc_request_done(host->mmc, mrq);
++}
++
++/* These are the bitmasks the tmio chip requires to implement the MMC response
++ * types. Note that R1 and R6 are the same in this scheme. */
++#define APP_CMD 0x0040
++#define RESP_NONE 0x0300
++#define RESP_R1 0x0400
++#define RESP_R1B 0x0500
++#define RESP_R2 0x0600
++#define RESP_R3 0x0700
++#define DATA_PRESENT 0x0800
++#define TRANSFER_READ 0x1000
++#define TRANSFER_MULTI 0x2000
++#define SECURITY_CMD 0x4000
++
++static void
++tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
++{
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ struct mmc_data *data = host->data;
++ int c = cmd->opcode;
++
++ if(cmd->opcode == MMC_STOP_TRANSMISSION) {
++ writew(0x001, &ctl->stop_internal_action);
++ return;
++ }
++
++ switch(mmc_resp_type(cmd)) {
++ case MMC_RSP_NONE: c |= RESP_NONE; break;
++ case MMC_RSP_R1: c |= RESP_R1; break;
++ case MMC_RSP_R1B: c |= RESP_R1B; break;
++ case MMC_RSP_R2: c |= RESP_R2; break;
++ case MMC_RSP_R3: c |= RESP_R3; break;
++ default:
++ DBG("Unknown response type %d\n", mmc_resp_type(cmd));
++ }
++
++ host->cmd = cmd;
++
++/* FIXME - this seems to be ok comented out but the spec suggest this bit should
++ * be set when issuing app commands.
++ * if(cmd->flags & MMC_FLAG_ACMD)
++ * c |= APP_CMD;
++ */
++ if(data) {
++ c |= DATA_PRESENT;
++ if(data->blocks > 1) {
++ writew(0x100, &ctl->stop_internal_action);
++ c |= TRANSFER_MULTI;
++ }
++ if(data->flags & MMC_DATA_READ)
++ c |= TRANSFER_READ;
++ }
++
++ enable_mmc_irqs(ctl, TMIO_MASK_CMD);
++
++ /* Fire off the command */
++ tmio_iowrite32(cmd->arg, ctl->arg_reg);
++ writew(c, &ctl->sd_cmd);
++}
++
++/* This chip always returns (at least?) as much data as you ask for.
++ * Im unsure what happens if you ask for less than a block. This should be
++ * looked into to ensure that a funny length read doesnt hose the controller.
++ *
++ * FIXME - this chip cannot do 1 and 2 byte data requests in 4 bit mode
++ */
++static inline void tmio_mmc_pio_irq(struct tmio_mmc_host *host) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ struct mmc_data *data = host->data;
++ unsigned short *buf;
++ unsigned int count;
++ unsigned long flags;
++
++ if(!data){
++ DBG("Spurious PIO IRQ\n");
++ return;
++ }
++
++ buf = (unsigned short *)(tmio_mmc_kmap_atomic(host, &flags) +
++ host->sg_off);
++
++ /* Ensure we dont read more than one block. The chip will interrupt us
++ * When the next block is available.
++ * FIXME - this is probably not true now IRQ handling is fixed
++ */
++ count = host->sg_ptr->length - host->sg_off;
++ if(count > data->blksz)
++ count = data->blksz;
++
++ DBG("count: %08x offset: %08x flags %08x\n",
++ count, host->sg_off, data->flags);
++
++ /* Transfer the data */
++ if(data->flags & MMC_DATA_READ)
++ readsw(&ctl->sd_data_port[0], buf, count >> 1);
++ else
++ writesw(&ctl->sd_data_port[0], buf, count >> 1);
++
++ host->sg_off += count;
++
++ tmio_mmc_kunmap_atomic(host, &flags);
++
++ if(host->sg_off == host->sg_ptr->length)
++ tmio_mmc_next_sg(host);
++
++ return;
++}
++
++static inline void tmio_mmc_data_irq(struct tmio_mmc_host *host) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ struct mmc_data *data = host->data;
++
++ host->data = NULL;
++
++ if(!data){
++ DBG("Spurious data end IRQ\n");
++ return;
++ }
++
++ /* FIXME - return correct transfer count on errors */
++ if (!data->error)
++ data->bytes_xfered = data->blocks * data->blksz;
++ else
++ data->bytes_xfered = 0;
++
++ DBG("Completed data request\n");
++
++ /*FIXME - other drivers allow an optional stop command of any given type
++ * which we dont do, as the chip can auto generate them.
++ * Perhaps we can be smarter about when to use auto CMD12 and
++ * only issue the auto request when we know this is the desired
++ * stop command, allowing fallback to the stop command the
++ * upper layers expect. For now, we do what works.
++ */
++
++ writew(0x000, &ctl->stop_internal_action);
++
++ if(data->flags & MMC_DATA_READ)
++ disable_mmc_irqs(ctl, TMIO_MASK_READOP);
++ else
++ disable_mmc_irqs(ctl, TMIO_MASK_WRITEOP);
++
++ tmio_mmc_finish_request(host);
++}
++
++static inline void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat) {
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ struct mmc_command *cmd = host->cmd;
++
++ if(!host->cmd) {
++ DBG("Spurious CMD irq\n");
++ return;
++ }
++
++ host->cmd = NULL;
++
++ /* This controller is sicker than the PXA one. not only do we need to
++ * drop the top 8 bits of the first response word, we also need to
++ * modify the order of the response for short response command types.
++ */
++
++ /* FIXME - this works but readl is wrong and will break on asic3... */
++ cmd->resp[3] = tmio_ioread32(&ctl->response[0]);
++ cmd->resp[2] = tmio_ioread32(&ctl->response[2]);
++ cmd->resp[1] = tmio_ioread32(&ctl->response[4]);
++ cmd->resp[0] = tmio_ioread32(&ctl->response[6]);
++
++ if(cmd->flags & MMC_RSP_136) {
++ cmd->resp[0] = (cmd->resp[0] <<8) | (cmd->resp[1] >>24);
++ cmd->resp[1] = (cmd->resp[1] <<8) | (cmd->resp[2] >>24);
++ cmd->resp[2] = (cmd->resp[2] <<8) | (cmd->resp[3] >>24);
++ cmd->resp[3] <<= 8;
++ }
++ else if(cmd->flags & MMC_RSP_R3) {
++ cmd->resp[0] = cmd->resp[3];
++ }
++
++ if (stat & TMIO_STAT_CMDTIMEOUT)
++ cmd->error = -ETIMEDOUT;
++ else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC)
++ cmd->error = -EILSEQ;
++
++ /* If there is data to handle we enable data IRQs here, and
++ * we will ultimatley finish the request in the data_end handler.
++ * If theres no data or we encountered an error, finish now.
++ */
++ if(host->data && !cmd->error){
++ if(host->data->flags & MMC_DATA_READ)
++ enable_mmc_irqs(ctl, TMIO_MASK_READOP);
++ else
++ enable_mmc_irqs(ctl, TMIO_MASK_WRITEOP);
++ }
++ else {
++ tmio_mmc_finish_request(host);
++ }
++
++ return;
++}
++
++
++static irqreturn_t tmio_mmc_irq(int irq, void *devid)
++{
++ struct tmio_mmc_host *host = devid;
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++ unsigned int ireg, irq_mask, status;
++
++ DBG("MMC IRQ begin\n");
++
++ status = tmio_ioread32(ctl->status);
++ irq_mask = tmio_ioread32(ctl->irq_mask);
++ ireg = status & TMIO_MASK_IRQ & ~irq_mask;
++
++#ifdef CONFIG_MMC_DEBUG
++ debug_status(status);
++ debug_status(ireg);
++#endif
++ if (!ireg) {
++ disable_mmc_irqs(ctl, status & ~irq_mask);
++#ifdef CONFIG_MMC_DEBUG
++ WARN("tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
++ debug_status(status);
++#endif
++ goto out;
++ }
++
++ while (ireg) {
++ /* Card insert / remove attempts */
++ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)){
++ ack_mmc_irqs(ctl, TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE);
++ mmc_detect_change(host->mmc,0);
++ }
++
++ /* CRC and other errors */
++/* if (ireg & TMIO_STAT_ERR_IRQ)
++ * handled |= tmio_error_irq(host, irq, stat);
++ */
++
++ /* Command completion */
++ if (ireg & TMIO_MASK_CMD) {
++ tmio_mmc_cmd_irq(host, status);
++ ack_mmc_irqs(ctl, TMIO_MASK_CMD);
++ }
++
++ /* Data transfer */
++ if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
++ ack_mmc_irqs(ctl, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
++ tmio_mmc_pio_irq(host);
++ }
++
++ /* Data transfer completion */
++ if (ireg & TMIO_STAT_DATAEND) {
++ tmio_mmc_data_irq(host);
++ ack_mmc_irqs(ctl, TMIO_STAT_DATAEND);
++ }
++
++ /* Check status - keep going until we've handled it all */
++ status = tmio_ioread32(ctl->status);
++ irq_mask = tmio_ioread32(ctl->irq_mask);
++ ireg = status & TMIO_MASK_IRQ & ~irq_mask;
++
++#ifdef CONFIG_MMC_DEBUG
++ DBG("Status at end of loop: %08x\n", status);
++ debug_status(status);
++#endif
++ }
++ DBG("MMC IRQ end\n");
++
++out:
++ return IRQ_HANDLED;
++}
++
++static void tmio_mmc_start_data(struct tmio_mmc_host *host, struct mmc_data *data)
++{
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ DBG("setup data transfer: blocksize %08x nr_blocks %d\n",
++ data->blksz, data->blocks);
++
++ tmio_mmc_init_sg(host, data);
++ host->data = data;
++
++ /* Set transfer length / blocksize */
++ writew(data->blksz, &ctl->sd_xfer_len);
++ writew(data->blocks, &ctl->xfer_blk_count);
++}
++
++/* Process requests from the MMC layer */
++static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
++{
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++
++ WARN_ON(host->mrq != NULL);
++
++ host->mrq = mrq;
++
++ /* If we're performing a data request we need to setup some
++ extra information */
++ if (mrq->data)
++ tmio_mmc_start_data(host, mrq->data);
++
++ tmio_mmc_start_command(host, mrq->cmd);
++}
++
++/* Set MMC clock / power.
++ * Note: This controller uses a simple divider scheme therefore it cannot
++ * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
++ * MMC wont run that fast, it has to be clocked at 12MHz which is the next
++ * slowest setting.
++ */
++static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
++{
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct tmio_mmc_cnf __iomem *cnf = host->cnf;
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ if(ios->clock)
++ tmio_mmc_set_clock (host, ios->clock);
++
++ /* Power sequence - OFF -> ON -> UP */
++ switch (ios->power_mode) {
++ case MMC_POWER_OFF:
++ writeb(0x00, &cnf->pwr_ctl[1]); /* power down SD bus */
++ tmio_mmc_clk_stop(host);
++ break;
++ case MMC_POWER_ON:
++ writeb(0x02, &cnf->pwr_ctl[1]); /* power up SD bus */
++ break;
++ case MMC_POWER_UP:
++ tmio_mmc_clk_start(host); /* start bus clock */
++ break;
++ }
++
++ switch (ios->bus_width) {
++ case MMC_BUS_WIDTH_1:
++ writew(0x80e0, &ctl->sd_mem_card_opt);
++ break;
++ case MMC_BUS_WIDTH_4:
++ writew(0x00e0, &ctl->sd_mem_card_opt);
++ break;
++ }
++
++ /* Potentially we may need a 140us pause here. FIXME */
++ udelay(140);
++}
++
++static int tmio_mmc_get_ro(struct mmc_host *mmc) {
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct tmio_mmc_ctl __iomem *ctl = host->ctl;
++
++ return (readw(&ctl->status[0]) & TMIO_STAT_WRPROTECT)?0:1;
++}
++
++static struct mmc_host_ops tmio_mmc_ops = {
++ .request = tmio_mmc_request,
++ .set_ios = tmio_mmc_set_ios,
++ .get_ro = tmio_mmc_get_ro,
++};
++
++static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) {
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct mmc_host *mmc = platform_get_drvdata(dev);
++ int ret;
++
++ ret = mmc_suspend_host(mmc, state);
++
++ /* Tell MFD core it can disable us now.*/
++ if(!ret && cell->disable)
++ cell->disable(dev);
++
++ return ret;
++}
++
++static int tmio_mmc_resume(struct platform_device *dev) {
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct mmc_host *mmc = platform_get_drvdata(dev);
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ struct tmio_mmc_cnf __iomem *cnf = host->cnf;
++
++ /* Enable the MMC/SD Control registers */
++ writew(SDCREN, &cnf->cmd);
++ writel(dev->resource[0].start & 0xfffe, &cnf->ctl_base);
++
++ /* Tell the MFD core we are ready to be enabled */
++ if(cell->enable)
++ cell->enable(dev);
++
++ mmc_resume_host(mmc);
++
++ return 0;
++}
++
++static int __devinit tmio_mmc_probe(struct platform_device *dev)
++{
++ struct mfd_cell *cell = mfd_get_cell(dev);
++ struct tmio_mmc_cnf __iomem *cnf;
++ struct tmio_mmc_ctl __iomem *ctl;
++ struct tmio_mmc_host *host;
++ struct mmc_host *mmc;
++ int ret = -ENOMEM;
++
++ mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev);
++ if (!mmc) {
++ goto out;
++ }
++
++ host = mmc_priv(mmc);
++ host->mmc = mmc;
++ platform_set_drvdata(dev, mmc); /* Used so we can de-init safely. */
++
++ host->cnf = cnf = ioremap((unsigned long)dev->resource[1].start,
++ (unsigned long)dev->resource[1].end -
++ (unsigned long)dev->resource[1].start);
++ if(!host->cnf)
++ goto host_free;
++
++ host->ctl = ctl = ioremap((unsigned long)dev->resource[0].start,
++ (unsigned long)dev->resource[0].end -
++ (unsigned long)dev->resource[0].start);
++ if (!host->ctl) {
++ goto unmap_cnf;
++ }
++
++ mmc->ops = &tmio_mmc_ops;
++ mmc->caps = MMC_CAP_4_BIT_DATA;
++ mmc->f_min = 46875;
++ mmc->f_max = 24000000;
++ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
++
++ /* Enable the MMC/SD Control registers */
++ writew(SDCREN, &cnf->cmd);
++ writel(dev->resource[0].start & 0xfffe, &cnf->ctl_base);
++
++ /* Tell the MFD core we are ready to be enabled */
++ if(cell->enable)
++ cell->enable(dev);
++
++ writeb(0x01,&cnf->pwr_ctl[2]); /* Disable SD power during suspend */
++ writeb(0x1f, &cnf->stop_clk_ctl); /* Route clock to SDIO??? FIXME */
++ writeb(0x0, &cnf->pwr_ctl[1]); /* Power down SD bus*/
++ tmio_mmc_clk_stop(host); /* Stop bus clock */
++ reset(host); /* Reset MMC HC */
++
++ host->irq = (unsigned long)dev->resource[2].start;
++ ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED, "tmio-mmc", host);
++ if (ret){
++ ret = -ENODEV;
++ DBG("Failed to allocate IRQ.\n");
++ goto unmap_ctl;
++ }
++ set_irq_type(host->irq, IRQT_FALLING);
++
++ mmc_add_host(mmc);
++
++ printk(KERN_INFO "%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
++ (unsigned long)host->ctl, host->irq);
++
++ /* Lets unmask the IRQs we want to know about */
++ disable_mmc_irqs(ctl, TMIO_MASK_ALL);
++ enable_mmc_irqs(ctl, TMIO_MASK_IRQ);
++
++ return 0;
++
++unmap_ctl:
++ iounmap(host->ctl);
++unmap_cnf:
++ iounmap(host->cnf);
++host_free:
++ mmc_free_host(mmc);
++out:
++ return ret;
++}
++
++static int __devexit tmio_mmc_remove(struct platform_device *dev)
++{
++ struct mmc_host *mmc = platform_get_drvdata(dev);
++
++ platform_set_drvdata(dev, NULL);
++
++ if (mmc) {
++ struct tmio_mmc_host *host = mmc_priv(mmc);
++ mmc_remove_host(mmc);
++ free_irq(host->irq, host);
++ /* FIXME - we might want to consider stopping the chip here. */
++ iounmap(host->ctl);
++ iounmap(host->cnf);
++ mmc_free_host(mmc); /* FIXME - why does this call hang ? */
++ }
++ return 0;
++}
++
++/* ------------------- device registration ----------------------- */
++
++static struct platform_driver tmio_mmc_driver = {
++ .driver = {
++ .name = "tmio-mmc",
++ },
++ .probe = tmio_mmc_probe,
++ .remove = __devexit_p(tmio_mmc_remove),
++#ifdef CONFIG_PM
++ .suspend = tmio_mmc_suspend,
++ .resume = tmio_mmc_resume,
++#endif
++};
++
++
++static int __init tmio_mmc_init(void)
++{
++ return platform_driver_register (&tmio_mmc_driver);
++}
++
++static void __exit tmio_mmc_exit(void)
++{
++ platform_driver_unregister (&tmio_mmc_driver);
++}
++
++module_init(tmio_mmc_init);
++module_exit(tmio_mmc_exit);
++
++MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
++MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
++MODULE_LICENSE("GPLv2");
+diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
+new file mode 100644
+index 0000000..d4d9f8f
+--- /dev/null
++++ b/drivers/mmc/host/tmio_mmc.h
+@@ -0,0 +1,205 @@
++/* Definitons for use with the tmio_mmc.c
++ *
++ * (c) 2005 Ian Molton <spyro@f2s.com>
++ * (c) 2007 Ian Molton <spyro@f2s.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++struct tmio_mmc_cnf {
++ u8 x00[4];
++ u16 cmd;
++ u8 x01[10];
++ u32 ctl_base;
++ u8 x02[41];
++ u8 int_pin;
++ u8 x03[2];
++ u8 stop_clk_ctl;
++ u8 gclk_ctl; /* Gated Clock Control */
++ u8 sd_clk_mode; /* 0x42 */
++ u8 x04;
++ u16 pin_status;
++ u8 x05[2];
++ u8 pwr_ctl[3];
++ u8 x06;
++ u8 card_detect_mode;
++ u8 x07[3];
++ u8 sd_slot;
++ u8 x08[159];
++ u8 ext_gclk_ctl_1; /* Extended Gated Clock Control 1 */
++ u8 ext_gclk_ctl_2; /* Extended Gated Clock Control 2 */
++ u8 x09[7];
++ u8 ext_gclk_ctl_3; /* Extended Gated Clock Control 3 */
++ u8 sd_led_en_1;
++ u8 x10[3];
++ u8 sd_led_en_2;
++ u8 x11;
++} __attribute__ ((packed));
++
++#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
++
++struct tmio_mmc_ctl {
++ u16 sd_cmd;
++ u16 x00;
++ u16 arg_reg[2];
++ u16 stop_internal_action;
++ u16 xfer_blk_count;
++ u16 response[8];
++ u16 status[2];
++ u16 irq_mask[2];
++ u16 sd_card_clk_ctl;
++ u16 sd_xfer_len;
++ u16 sd_mem_card_opt;
++ u16 x01;
++ u16 sd_error_detail_status[2];
++ u16 sd_data_port[2];
++ u16 transaction_ctl;
++ u16 x02[85];
++ u16 reset_sd;
++ u16 x03[15];
++ u16 sdio_regs[28];
++ u16 clk_and_wait_ctl;
++ u16 x04[83];
++ u16 reset_sdio;
++ u16 x05[15];
++} __attribute__ ((packed));
++
++/* Definitions for values the CTRL_STATUS register can take. */
++#define TMIO_STAT_CMDRESPEND 0x00000001
++#define TMIO_STAT_DATAEND 0x00000004
++#define TMIO_STAT_CARD_REMOVE 0x00000008
++#define TMIO_STAT_CARD_INSERT 0x00000010
++#define TMIO_STAT_SIGSTATE 0x00000020
++#define TMIO_STAT_WRPROTECT 0x00000080
++#define TMIO_STAT_CARD_REMOVE_A 0x00000100
++#define TMIO_STAT_CARD_INSERT_A 0x00000200
++#define TMIO_STAT_SIGSTATE_A 0x00000400
++#define TMIO_STAT_CMD_IDX_ERR 0x00010000
++#define TMIO_STAT_CRCFAIL 0x00020000
++#define TMIO_STAT_STOPBIT_ERR 0x00040000
++#define TMIO_STAT_DATATIMEOUT 0x00080000
++#define TMIO_STAT_RXOVERFLOW 0x00100000
++#define TMIO_STAT_TXUNDERRUN 0x00200000
++#define TMIO_STAT_CMDTIMEOUT 0x00400000
++#define TMIO_STAT_RXRDY 0x01000000
++#define TMIO_STAT_TXRQ 0x02000000
++#define TMIO_STAT_ILL_FUNC 0x20000000
++#define TMIO_STAT_CMD_BUSY 0x40000000
++#define TMIO_STAT_ILL_ACCESS 0x80000000
++
++/* Define some IRQ masks */
++/* This is the mask used at reset by the chip */
++#define TMIO_MASK_ALL 0x837f031d
++#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
++ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
++#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
++ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
++#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
++ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
++#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
++
++#define enable_mmc_irqs(ctl, i) \
++ do { \
++ u32 mask;\
++ mask = tmio_ioread32((ctl)->irq_mask); \
++ mask &= ~((i) & TMIO_MASK_IRQ); \
++ tmio_iowrite32(mask, (ctl)->irq_mask); \
++ } while (0)
++
++#define disable_mmc_irqs(ctl, i) \
++ do { \
++ u32 mask;\
++ mask = tmio_ioread32((ctl)->irq_mask); \
++ mask |= ((i) & TMIO_MASK_IRQ); \
++ tmio_iowrite32(mask, (ctl)->irq_mask); \
++ } while (0)
++
++#define ack_mmc_irqs(ctl, i) \
++ do { \
++ u32 mask;\
++ mask = tmio_ioread32((ctl)->status); \
++ mask &= ~((i) & TMIO_MASK_IRQ); \
++ tmio_iowrite32(mask, (ctl)->status); \
++ } while (0)
++
++
++struct tmio_mmc_host {
++ struct tmio_mmc_cnf __iomem *cnf;
++ struct tmio_mmc_ctl __iomem *ctl;
++ struct mmc_command *cmd;
++ struct mmc_request *mrq;
++ struct mmc_data *data;
++ struct mmc_host *mmc;
++ int irq;
++
++ /* pio related stuff */
++ struct scatterlist *sg_ptr;
++ unsigned int sg_len;
++ unsigned int sg_off;
++};
++
++#include <linux/scatterlist.h>
++#include <linux/blkdev.h>
++
++static inline void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data)
++{
++ host->sg_len = data->sg_len;
++ host->sg_ptr = data->sg;
++ host->sg_off = 0;
++}
++
++static inline int tmio_mmc_next_sg(struct tmio_mmc_host *host)
++{
++ host->sg_ptr++;
++ host->sg_off = 0;
++ return --host->sg_len;
++}
++
++static inline char *tmio_mmc_kmap_atomic(struct tmio_mmc_host *host, unsigned long *flags)
++{
++ struct scatterlist *sg = host->sg_ptr;
++
++ local_irq_save(*flags);
++ return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
++}
++
++static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host, unsigned long *flags)
++{
++ kunmap_atomic(sg_page(host->sg_ptr), KM_BIO_SRC_IRQ);
++ local_irq_restore(*flags);
++}
++
++#ifdef CONFIG_MMC_DEBUG
++#define DBG(args...) printk(args)
++
++void debug_status(u32 status){
++ printk("status: %08x = ", status);
++ if(status & TMIO_STAT_CARD_REMOVE) printk("Card_removed ");
++ if(status & TMIO_STAT_CARD_INSERT) printk("Card_insert ");
++ if(status & TMIO_STAT_SIGSTATE) printk("Sigstate ");
++ if(status & TMIO_STAT_WRPROTECT) printk("Write_protect ");
++ if(status & TMIO_STAT_CARD_REMOVE_A) printk("Card_remove_A ");
++ if(status & TMIO_STAT_CARD_INSERT_A) printk("Card_insert_A ");
++ if(status & TMIO_STAT_SIGSTATE_A) printk("Sigstate_A ");
++ if(status & TMIO_STAT_CMD_IDX_ERR) printk("Cmd_IDX_Err ");
++ if(status & TMIO_STAT_STOPBIT_ERR) printk("Stopbit_ERR ");
++ if(status & TMIO_STAT_ILL_FUNC) printk("ILLEGAL_FUNC ");
++ if(status & TMIO_STAT_CMD_BUSY) printk("CMD_BUSY ");
++ if(status & TMIO_STAT_CMDRESPEND) printk("Response_end ");
++ if(status & TMIO_STAT_DATAEND) printk("Data_end ");
++ if(status & TMIO_STAT_CRCFAIL) printk("CRC_failure ");
++ if(status & TMIO_STAT_DATATIMEOUT) printk("Data_timeout ");
++ if(status & TMIO_STAT_CMDTIMEOUT) printk("Command_timeout ");
++ if(status & TMIO_STAT_RXOVERFLOW) printk("RX_OVF ");
++ if(status & TMIO_STAT_TXUNDERRUN) printk("TX_UND ");
++ if(status & TMIO_STAT_RXRDY) printk("RX_rdy ");
++ if(status & TMIO_STAT_TXRQ) printk("TX_req ");
++ if(status & TMIO_STAT_ILL_ACCESS) printk("ILLEGAL_ACCESS ");
++ printk("\n");
++}
++#else
++#define DBG(fmt,args...) do { } while (0)
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch
new file mode 100644
index 0000000000..0fa10ebd4c
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0012-Tosa-keyboard-support.patch
@@ -0,0 +1,593 @@
+From 6d377e8f80ce421e6842ac5f42081345fbc70002 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 01:27:41 +0300
+Subject: [PATCH 12/64] Tosa keyboard support
+
+Support keyboard on tosa (Sharp Zaurus SL-6000x).
+Largely based on patches by Dirk Opfer.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 43 ++++
+ drivers/input/keyboard/Kconfig | 21 ++
+ drivers/input/keyboard/Makefile | 1 +
+ drivers/input/keyboard/tosakbd.c | 415 ++++++++++++++++++++++++++++++++++++++
+ include/asm-arm/arch-pxa/tosa.h | 30 +++
+ 5 files changed, 510 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/keyboard/tosakbd.c
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 240fd04..e7e0f52 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -21,6 +21,8 @@
+ #include <linux/mmc/host.h>
+ #include <linux/pm.h>
+ #include <linux/delay.h>
++#include <linux/gpio_keys.h>
++#include <linux/input.h>
+
+ #include <asm/setup.h>
+ #include <asm/memory.h>
+@@ -253,6 +255,46 @@ static struct platform_device tosakbd_device = {
+ .id = -1,
+ };
+
++static struct gpio_keys_button tosa_gpio_keys[] = {
++ {
++ .type = EV_PWR,
++ .code = KEY_SUSPEND,
++ .gpio = TOSA_GPIO_ON_KEY,
++ .desc = "On key",
++ .wakeup = 1,
++ .active_low = 1,
++ },
++ {
++ .type = EV_KEY,
++ .code = TOSA_KEY_RECORD,
++ .gpio = TOSA_GPIO_RECORD_BTN,
++ .desc = "Record Button",
++ .wakeup = 1,
++ .active_low = 1,
++ },
++ {
++ .type = EV_KEY,
++ .code = TOSA_KEY_SYNC,
++ .gpio = TOSA_GPIO_SYNC,
++ .desc = "Sync Button",
++ .wakeup = 1,
++ .active_low = 1,
++ },
++};
++
++static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
++ .buttons = tosa_gpio_keys,
++ .nbuttons = ARRAY_SIZE(tosa_gpio_keys),
++};
++
++static struct platform_device tosa_gpio_keys_device = {
++ .name = "gpio-keys",
++ .id = -1,
++ .dev = {
++ .platform_data = &tosa_gpio_keys_platform_data,
++ },
++};
++
+ /*
+ * Tosa LEDs
+ */
+@@ -265,6 +307,7 @@ static struct platform_device *devices[] __initdata = {
+ &tosascoop_device,
+ &tosascoop_jc_device,
+ &tosakbd_device,
++ &tosa_gpio_keys_device,
+ &tosaled_device,
+ };
+
+diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
+index 086d58c..0c32762 100644
+--- a/drivers/input/keyboard/Kconfig
++++ b/drivers/input/keyboard/Kconfig
+@@ -154,6 +154,27 @@ config KEYBOARD_SPITZ
+ To compile this driver as a module, choose M here: the
+ module will be called spitzkbd.
+
++config KEYBOARD_TOSA
++ tristate "Tosa keyboard"
++ depends on MACH_TOSA
++ default y
++ help
++ Say Y here to enable the keyboard on the Sharp Zaurus SL-6000x (Tosa)
++
++ To compile this driver as a module, choose M here: the
++ module will be called tosakbd.
++
++config KEYBOARD_TOSA_USE_EXT_KEYCODES
++ bool "Tosa keyboard: use extended keycodes"
++ depends on KEYBOARD_TOSA
++ default n
++ help
++ Say Y here to enable the tosa keyboard driver to generate extended
++ (>= 127) keycodes. Be aware, that they can't be correctly interpreted
++ by either console keyboard driver or by Kdrive keybd driver.
++
++ Say Y only if you know, what you are doing!
++
+ config KEYBOARD_AMIGA
+ tristate "Amiga keyboard"
+ depends on AMIGA
+diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
+index e97455f..6caa065 100644
+--- a/drivers/input/keyboard/Makefile
++++ b/drivers/input/keyboard/Makefile
+@@ -15,6 +15,7 @@ obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
+ obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
+ obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
+ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
++obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
+ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
+ obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
+ obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o
+diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
+new file mode 100644
+index 0000000..3884d1e
+--- /dev/null
++++ b/drivers/input/keyboard/tosakbd.c
+@@ -0,0 +1,415 @@
++/*
++ * Keyboard driver for Sharp Tosa models (SL-6000x)
++ *
++ * Copyright (c) 2005 Dirk Opfer
++ * Copyright (c) 2007 Dmitry Baryshkov
++ *
++ * Based on xtkbd.c/locomkbd.c/corgikbd.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++
++#include <asm/arch/gpio.h>
++#include <asm/arch/tosa.h>
++
++#define KB_ROWMASK(r) (1 << (r))
++#define SCANCODE(r, c) (((r)<<4) + (c) + 1)
++#define NR_SCANCODES SCANCODE(TOSA_KEY_SENSE_NUM - 1, TOSA_KEY_STROBE_NUM - 1) + 1
++
++#define SCAN_INTERVAL (HZ/10)
++
++#define KB_DISCHARGE_DELAY 10
++#define KB_ACTIVATE_DELAY 10
++
++static unsigned int tosakbd_keycode[NR_SCANCODES] = {
++0,
++0, KEY_W, 0, 0, 0, KEY_K, KEY_BACKSPACE, KEY_P,
++0, 0, 0, 0, 0, 0, 0, 0,
++KEY_Q, KEY_E, KEY_T, KEY_Y, 0, KEY_O, KEY_I, KEY_COMMA,
++0, 0, 0, 0, 0, 0, 0, 0,
++KEY_A, KEY_D, KEY_G, KEY_U, 0, KEY_L, KEY_ENTER, KEY_DOT,
++0, 0, 0, 0, 0, 0, 0, 0,
++KEY_Z, KEY_C, KEY_V, KEY_J, TOSA_KEY_ADDRESSBOOK, TOSA_KEY_CANCEL, TOSA_KEY_CENTER, TOSA_KEY_OK,
++KEY_LEFTSHIFT, 0, 0, 0, 0, 0, 0, 0,
++KEY_S, KEY_R, KEY_B, KEY_N, TOSA_KEY_CALENDAR, TOSA_KEY_HOMEPAGE, KEY_LEFTCTRL, TOSA_KEY_LIGHT,
++0, KEY_RIGHTSHIFT, 0, 0, 0, 0, 0, 0,
++KEY_TAB, KEY_SLASH, KEY_H, KEY_M, TOSA_KEY_MENU, 0, KEY_UP, 0,
++0, 0, TOSA_KEY_FN, 0, 0, 0, 0, 0,
++KEY_X, KEY_F, KEY_SPACE, KEY_APOSTROPHE, TOSA_KEY_MAIL, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
++0, 0, 0,
++};
++
++struct tosakbd {
++ unsigned int keycode[ARRAY_SIZE(tosakbd_keycode)];
++ struct input_dev *input;
++
++ spinlock_t lock; /* protect kbd scanning */
++ struct timer_list timer;
++};
++
++
++/* Helper functions for reading the keyboard matrix
++ * Note: We should really be using pxa_gpio_mode to alter GPDR but it
++ * requires a function call per GPIO bit which is excessive
++ * when we need to access 12 bits at once, multiple times.
++ * These functions must be called within local_irq_save()/local_irq_restore()
++ * or similar.
++ */
++#define GET_ROWS_STATUS(c) ((GPLR2 & TOSA_GPIO_ALL_SENSE_BIT) >> TOSA_GPIO_ALL_SENSE_RSHIFT)
++
++static inline void tosakbd_discharge_all(void)
++{
++ /* STROBE All HiZ */
++ GPCR1 = TOSA_GPIO_HIGH_STROBE_BIT;
++ GPDR1 &= ~TOSA_GPIO_HIGH_STROBE_BIT;
++ GPCR2 = TOSA_GPIO_LOW_STROBE_BIT;
++ GPDR2 &= ~TOSA_GPIO_LOW_STROBE_BIT;
++}
++
++static inline void tosakbd_activate_all(void)
++{
++ /* STROBE ALL -> High */
++ GPSR1 = TOSA_GPIO_HIGH_STROBE_BIT;
++ GPDR1 |= TOSA_GPIO_HIGH_STROBE_BIT;
++ GPSR2 = TOSA_GPIO_LOW_STROBE_BIT;
++ GPDR2 |= TOSA_GPIO_LOW_STROBE_BIT;
++
++ udelay(KB_DISCHARGE_DELAY);
++
++ /* STATE CLEAR */
++ GEDR2 |= TOSA_GPIO_ALL_SENSE_BIT;
++}
++
++static inline void tosakbd_activate_col(int col)
++{
++ if (col <= 5) {
++ /* STROBE col -> High, not col -> HiZ */
++ GPSR1 = TOSA_GPIO_STROBE_BIT(col);
++ GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++ } else {
++ /* STROBE col -> High, not col -> HiZ */
++ GPSR2 = TOSA_GPIO_STROBE_BIT(col);
++ GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++ }
++}
++
++static inline void tosakbd_reset_col(int col)
++{
++ if (col <= 5) {
++ /* STROBE col -> Low */
++ GPCR1 = TOSA_GPIO_STROBE_BIT(col);
++ /* STROBE col -> out, not col -> HiZ */
++ GPDR1 = (GPDR1 & ~TOSA_GPIO_HIGH_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++ } else {
++ /* STROBE col -> Low */
++ GPCR2 = TOSA_GPIO_STROBE_BIT(col);
++ /* STROBE col -> out, not col -> HiZ */
++ GPDR2 = (GPDR2 & ~TOSA_GPIO_LOW_STROBE_BIT) | TOSA_GPIO_STROBE_BIT(col);
++ }
++}
++/*
++ * The tosa keyboard only generates interrupts when a key is pressed.
++ * So when a key is pressed, we enable a timer. This timer scans the
++ * keyboard, and this is how we detect when the key is released.
++ */
++
++/* Scan the hardware keyboard and push any changes up through the input layer */
++static void tosakbd_scankeyboard(struct platform_device *dev)
++{
++ struct tosakbd *tosakbd = platform_get_drvdata(dev);
++ unsigned int row, col, rowd;
++ unsigned long flags;
++ unsigned int num_pressed = 0;
++
++ spin_lock_irqsave(&tosakbd->lock, flags);
++
++ for (col = 0; col < TOSA_KEY_STROBE_NUM; col++) {
++ /*
++ * Discharge the output driver capacitatance
++ * in the keyboard matrix. (Yes it is significant..)
++ */
++ tosakbd_discharge_all();
++ udelay(KB_DISCHARGE_DELAY);
++
++ tosakbd_activate_col(col);
++ udelay(KB_ACTIVATE_DELAY);
++
++ rowd = GET_ROWS_STATUS(col);
++
++ for (row = 0; row < TOSA_KEY_SENSE_NUM; row++) {
++ unsigned int scancode, pressed;
++ scancode = SCANCODE(row, col);
++ pressed = rowd & KB_ROWMASK(row);
++
++ if (pressed && !tosakbd->keycode[scancode])
++ dev_warn(&dev->dev,
++ "unhandled scancode: 0x%02x\n",
++ scancode);
++
++ input_report_key(tosakbd->input,
++ tosakbd->keycode[scancode],
++ pressed);
++ if (pressed)
++ num_pressed++;
++ }
++
++ tosakbd_reset_col(col);
++ }
++
++ tosakbd_activate_all();
++
++ input_sync(tosakbd->input);
++
++ /* if any keys are pressed, enable the timer */
++ if (num_pressed)
++ mod_timer(&tosakbd->timer, jiffies + SCAN_INTERVAL);
++
++ spin_unlock_irqrestore(&tosakbd->lock, flags);
++}
++
++/*
++ * tosa keyboard interrupt handler.
++ */
++static irqreturn_t tosakbd_interrupt(int irq, void *__dev)
++{
++ struct platform_device *dev = __dev;
++ struct tosakbd *tosakbd = platform_get_drvdata(dev);
++
++ if (!timer_pending(&tosakbd->timer)) {
++ /** wait chattering delay **/
++ udelay(20);
++ tosakbd_scankeyboard(dev);
++ }
++
++ return IRQ_HANDLED;
++}
++
++/*
++ * tosa timer checking for released keys
++ */
++static void tosakbd_timer_callback(unsigned long __dev)
++{
++ struct platform_device *dev = (struct platform_device *)__dev;
++ tosakbd_scankeyboard(dev);
++}
++
++#ifdef CONFIG_PM
++static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
++{
++ struct tosakbd *tosakbd = platform_get_drvdata(dev);
++
++ del_timer_sync(&tosakbd->timer);
++
++ return 0;
++}
++
++static int tosakbd_resume(struct platform_device *dev)
++{
++ tosakbd_scankeyboard(dev);
++
++ return 0;
++}
++#else
++#define tosakbd_suspend NULL
++#define tosakbd_resume NULL
++#endif
++
++static int __devinit tosakbd_probe(struct platform_device *pdev) {
++
++ int i;
++ struct tosakbd *tosakbd;
++ struct input_dev *input_dev;
++ int error;
++
++ tosakbd = kzalloc(sizeof(struct tosakbd), GFP_KERNEL);
++ if (!tosakbd)
++ return -ENOMEM;
++
++ input_dev = input_allocate_device();
++ if (!input_dev) {
++ kfree(tosakbd);
++ return -ENOMEM;
++ }
++
++ platform_set_drvdata(pdev, tosakbd);
++
++ spin_lock_init(&tosakbd->lock);
++
++ /* Init Keyboard rescan timer */
++ init_timer(&tosakbd->timer);
++ tosakbd->timer.function = tosakbd_timer_callback;
++ tosakbd->timer.data = (unsigned long) pdev;
++
++ tosakbd->input = input_dev;
++
++ input_set_drvdata(input_dev, tosakbd);
++ input_dev->name = "Tosa Keyboard";
++ input_dev->phys = "tosakbd/input0";
++ input_dev->dev.parent = &pdev->dev;
++
++ input_dev->id.bustype = BUS_HOST;
++ input_dev->id.vendor = 0x0001;
++ input_dev->id.product = 0x0001;
++ input_dev->id.version = 0x0100;
++
++ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++ input_dev->keycode = tosakbd->keycode;
++ input_dev->keycodesize = sizeof(unsigned int);
++ input_dev->keycodemax = ARRAY_SIZE(tosakbd_keycode);
++
++ memcpy(tosakbd->keycode, tosakbd_keycode, sizeof(tosakbd_keycode));
++
++ for (i = 0; i < ARRAY_SIZE(tosakbd_keycode); i++)
++ __set_bit(tosakbd->keycode[i], input_dev->keybit);
++ clear_bit(0, input_dev->keybit);
++
++ /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
++ for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
++ int gpio = TOSA_GPIO_KEY_SENSE(i);
++ int irq;
++ error = gpio_request(gpio, "tosakbd");
++ if (error < 0) {
++ printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
++ " error %d\n", gpio, error);
++ goto fail;
++ }
++
++ error = gpio_direction_input(TOSA_GPIO_KEY_SENSE(i));
++ if (error < 0) {
++ printk(KERN_ERR "tosakbd: failed to configure input"
++ " direction for GPIO %d, error %d\n",
++ gpio, error);
++ gpio_free(gpio);
++ goto fail;
++ }
++
++ irq = gpio_to_irq(gpio);
++ if (irq < 0) {
++ error = irq;
++ printk(KERN_ERR "gpio-keys: Unable to get irq number"
++ " for GPIO %d, error %d\n",
++ gpio, error);
++ gpio_free(gpio);
++ goto fail;
++ }
++
++ error = request_irq(irq, tosakbd_interrupt,
++ IRQF_DISABLED | IRQF_TRIGGER_RISING,
++ "tosakbd", pdev);
++
++ if (error) {
++ printk("tosakbd: Can't get IRQ: %d: error %d!\n",
++ irq, error);
++ gpio_free(gpio);
++ goto fail;
++ }
++ }
++
++ /* Set Strobe lines as outputs - set high */
++ for (i = 0; i < TOSA_KEY_STROBE_NUM; i++) {
++ int gpio = TOSA_GPIO_KEY_STROBE(i);
++ error = gpio_request(gpio, "tosakbd");
++ if (error < 0) {
++ printk(KERN_ERR "tosakbd: failed to request GPIO %d, "
++ " error %d\n", gpio, error);
++ goto fail2;
++ }
++
++ error = gpio_direction_output(gpio, 1);
++ if (error < 0) {
++ printk(KERN_ERR "tosakbd: failed to configure input"
++ " direction for GPIO %d, error %d\n",
++ gpio, error);
++ gpio_free(gpio);
++ goto fail;
++ }
++
++ }
++
++ error = input_register_device(input_dev);
++ if (error) {
++ printk(KERN_ERR "tosakbd: Unable to register input device, "
++ "error: %d\n", error);
++ goto fail;
++ }
++
++ printk(KERN_INFO "input: Tosa Keyboard Registered\n");
++
++ return 0;
++
++fail2:
++ while (--i >= 0)
++ gpio_free(TOSA_GPIO_KEY_STROBE(i));
++
++ i = TOSA_KEY_SENSE_NUM;
++fail:
++ while (--i >= 0) {
++ free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), pdev);
++ gpio_free(TOSA_GPIO_KEY_SENSE(i));
++ }
++
++ platform_set_drvdata(pdev, NULL);
++ input_free_device(input_dev);
++ kfree(tosakbd);
++
++ return error;
++}
++
++static int __devexit tosakbd_remove(struct platform_device *dev) {
++
++ int i;
++ struct tosakbd *tosakbd = platform_get_drvdata(dev);
++
++ for (i = 0; i < TOSA_KEY_STROBE_NUM; i++)
++ gpio_free(TOSA_GPIO_KEY_STROBE(i));
++
++ for (i = 0; i < TOSA_KEY_SENSE_NUM; i++) {
++ free_irq(gpio_to_irq(TOSA_GPIO_KEY_SENSE(i)), dev);
++ gpio_free(TOSA_GPIO_KEY_SENSE(i));
++ }
++
++ del_timer_sync(&tosakbd->timer);
++
++ input_unregister_device(tosakbd->input);
++
++ kfree(tosakbd);
++
++ return 0;
++}
++
++static struct platform_driver tosakbd_driver = {
++ .probe = tosakbd_probe,
++ .remove = __devexit_p(tosakbd_remove),
++ .suspend = tosakbd_suspend,
++ .resume = tosakbd_resume,
++ .driver = {
++ .name = "tosa-keyboard",
++ },
++};
++
++static int __devinit tosakbd_init(void)
++{
++ return platform_driver_register(&tosakbd_driver);
++}
++
++static void __exit tosakbd_exit(void)
++{
++ platform_driver_unregister(&tosakbd_driver);
++}
++
++module_init(tosakbd_init);
++module_exit(tosakbd_exit);
++
++MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
++MODULE_DESCRIPTION("Tosa Keyboard Driver");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
+index c3364a2..c05e4fa 100644
+--- a/include/asm-arm/arch-pxa/tosa.h
++++ b/include/asm-arm/arch-pxa/tosa.h
+@@ -163,4 +163,34 @@
+
+ extern struct platform_device tosascoop_jc_device;
+ extern struct platform_device tosascoop_device;
++
++#define TOSA_KEY_SYNC KEY_102ND /* ??? */
++
++
++#ifndef CONFIG_KEYBOARD_TOSA_USE_EXT_KEYCODES
++#define TOSA_KEY_RECORD KEY_YEN
++#define TOSA_KEY_ADDRESSBOOK KEY_KATAKANA
++#define TOSA_KEY_CANCEL KEY_ESC
++#define TOSA_KEY_CENTER KEY_HIRAGANA
++#define TOSA_KEY_OK KEY_HENKAN
++#define TOSA_KEY_CALENDAR KEY_KATAKANAHIRAGANA
++#define TOSA_KEY_HOMEPAGE KEY_HANGEUL
++#define TOSA_KEY_LIGHT KEY_MUHENKAN
++#define TOSA_KEY_MENU KEY_HANJA
++#define TOSA_KEY_FN KEY_RIGHTALT
++#define TOSA_KEY_MAIL KEY_ZENKAKUHANKAKU
++#else
++#define TOSA_KEY_RECORD KEY_RECORD
++#define TOSA_KEY_ADDRESSBOOK KEY_ADDRESSBOOK
++#define TOSA_KEY_CANCEL KEY_CANCEL
++#define TOSA_KEY_CENTER KEY_SELECT /* ??? */
++#define TOSA_KEY_OK KEY_OK
++#define TOSA_KEY_CALENDAR KEY_CALENDAR
++#define TOSA_KEY_HOMEPAGE KEY_HOMEPAGE
++#define TOSA_KEY_LIGHT KEY_KBDILLUMTOGGLE
++#define TOSA_KEY_MENU KEY_MENU
++#define TOSA_KEY_FN KEY_FN
++#define TOSA_KEY_MAIL KEY_MAIL
++#endif
++
+ #endif /* _ASM_ARCH_TOSA_H_ */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch b/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch
new file mode 100644
index 0000000000..082a2c72b8
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch
@@ -0,0 +1,61 @@
+From 18c1a92a09faf75ebdac7ac471c741a6622cf3e2 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 01:27:49 +0300
+Subject: [PATCH 13/64] USB: gadget: pxa2xx_udc supports inverted vbus
+
+Some boards (like e.g. Tosa) invert the VBUS-detection signal:
+it's low when a host is supplying VBUS, and high otherwise.
+Allow specifying whether gpio_vbus value is inverted.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/usb/gadget/pxa2xx_udc.c | 9 +++++++--
+ include/asm-arm/mach/udc_pxa2xx.h | 2 ++
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
+index 3173b39..4f7d4ef 100644
+--- a/drivers/usb/gadget/pxa2xx_udc.c
++++ b/drivers/usb/gadget/pxa2xx_udc.c
+@@ -127,8 +127,10 @@ static int is_vbus_present(void)
+ {
+ struct pxa2xx_udc_mach_info *mach = the_controller->mach;
+
+- if (mach->gpio_vbus)
+- return gpio_get_value(mach->gpio_vbus);
++ if (mach->gpio_vbus) {
++ int value = gpio_get_value(mach->gpio_vbus);
++ return mach->gpio_vbus_inverted ? !value : value;
++ }
+ if (mach->udc_is_connected)
+ return mach->udc_is_connected();
+ return 1;
+@@ -1397,6 +1399,9 @@ static irqreturn_t udc_vbus_irq(int irq, void *_dev)
+ struct pxa2xx_udc *dev = _dev;
+ int vbus = gpio_get_value(dev->mach->gpio_vbus);
+
++ if (dev->mach->gpio_vbus_inverted)
++ vbus = !vbus;
++
+ pxa2xx_udc_vbus_session(&dev->gadget, vbus);
+ return IRQ_HANDLED;
+ }
+diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/include/asm-arm/mach/udc_pxa2xx.h
+index ff0a957..f191e14 100644
+--- a/include/asm-arm/mach/udc_pxa2xx.h
++++ b/include/asm-arm/mach/udc_pxa2xx.h
+@@ -19,7 +19,9 @@ struct pxa2xx_udc_mach_info {
+ * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane
+ * VBUS IRQ and omit the methods above. Store the GPIO number
+ * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits.
++ * Note that sometimes the signals go through inverters...
+ */
++ bool gpio_vbus_inverted;
+ u16 gpio_vbus; /* high == vbus present */
+ u16 gpio_pullup; /* high == pullup activated */
+ };
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch b/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch
new file mode 100644
index 0000000000..98783efea0
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0014-tosa_udc_use_gpio_vbus.patch.patch
@@ -0,0 +1,38 @@
+From 932ff38b17c7847c43e2bad01b510b64c27f9810 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 01:27:59 +0300
+Subject: [PATCH 14/64] tosa_udc_use_gpio_vbus.patch
+
+Use gpio_vbus instead of udc_is_connected for udc on tosa.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ arch/arm/mach-pxa/tosa.c | 9 ++-------
+ 1 files changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index e7e0f52..5268e94 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -159,15 +159,10 @@ static void tosa_udc_command(int cmd)
+ }
+ }
+
+-static int tosa_udc_is_connected(void)
+-{
+- return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0);
+-}
+-
+-
+ static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ .udc_command = tosa_udc_command,
+- .udc_is_connected = tosa_udc_is_connected,
++ .gpio_vbus = TOSA_GPIO_USB_IN,
++ .gpio_vbus_inverted = 1,
+ };
+
+ /*
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch b/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch
new file mode 100644
index 0000000000..f8e57e8306
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0015-sharpsl-export-params.patch
@@ -0,0 +1,32 @@
+From bba216220d17d1091413e82c9924ac5614402c05 Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Wed, 9 Jan 2008 01:28:06 +0300
+Subject: [PATCH 15/64] sharpsl export params
+
+---
+ arch/arm/common/sharpsl_param.c | 2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/arch/arm/common/sharpsl_param.c b/arch/arm/common/sharpsl_param.c
+index aad4d94..d56c932 100644
+--- a/arch/arm/common/sharpsl_param.c
++++ b/arch/arm/common/sharpsl_param.c
+@@ -12,6 +12,7 @@
+ */
+
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/string.h>
+ #include <asm/mach/sharpsl_param.h>
+
+@@ -36,6 +37,7 @@
+ #define PHAD_MAGIC MAGIC_CHG('P','H','A','D')
+
+ struct sharpsl_param_info sharpsl_param;
++EXPORT_SYMBOL(sharpsl_param);
+
+ void sharpsl_save_param(void)
+ {
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch b/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch
new file mode 100644
index 0000000000..d73de0698c
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch
@@ -0,0 +1,44 @@
+From 0fe7b491b70efafbd41185f8e95a3eada65984a1 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 28 Jan 2008 01:49:28 +0300
+Subject: [PATCH 16/64] This patch fixes the pxa25x clocks definitions to add hwuart.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/pxa25x.c | 9 ++++++++-
+ 1 files changed, 8 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
+index 9732d5d..006a6e0 100644
+--- a/arch/arm/mach-pxa/pxa25x.c
++++ b/arch/arm/mach-pxa/pxa25x.c
+@@ -111,11 +111,14 @@ static const struct clkops clk_pxa25x_lcd_ops = {
+ * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
+ * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
+ */
++static struct clk pxa25x_hwuart_clk =
++ INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev)
++;
++
+ static struct clk pxa25x_clks[] = {
+ INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
+ INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
+ INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
+- INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
+ INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
+ INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
+ INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
+@@ -303,6 +306,10 @@ static int __init pxa25x_init(void)
+ {
+ int ret = 0;
+
++ /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
++ if (cpu_is_pxa25x())
++ clks_register(&pxa25x_hwuart_clk, 1);
++
+ if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
+ clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch b/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch
new file mode 100644
index 0000000000..5163361da3
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch
@@ -0,0 +1,280 @@
+From 71857e8f6c4a8d2d3eac3037f02e0c30c6fdb37e Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 01:43:28 +0300
+Subject: [PATCH 17/64] Convert pxa2xx UDC to use debugfs
+
+Use debugfs instead of /proc/driver/udc
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/usb/gadget/pxa2xx_udc.c | 100 +++++++++++++++++----------------------
+ drivers/usb/gadget/pxa2xx_udc.h | 10 +++-
+ 2 files changed, 51 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
+index 4f7d4ef..2900556 100644
+--- a/drivers/usb/gadget/pxa2xx_udc.c
++++ b/drivers/usb/gadget/pxa2xx_udc.c
+@@ -38,13 +38,14 @@
+ #include <linux/timer.h>
+ #include <linux/list.h>
+ #include <linux/interrupt.h>
+-#include <linux/proc_fs.h>
+ #include <linux/mm.h>
+ #include <linux/platform_device.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/irq.h>
+ #include <linux/clk.h>
+ #include <linux/err.h>
++#include <linux/seq_file.h>
++#include <linux/debugfs.h>
+
+ #include <asm/byteorder.h>
+ #include <asm/dma.h>
+@@ -993,45 +994,36 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
+
+ /*-------------------------------------------------------------------------*/
+
+-#ifdef CONFIG_USB_GADGET_DEBUG_FILES
+-
+-static const char proc_node_name [] = "driver/udc";
++#ifdef CONFIG_USB_GADGET_DEBUG_FS
+
++static struct pxa2xx_udc memory;
+ static int
+-udc_proc_read(char *page, char **start, off_t off, int count,
+- int *eof, void *_dev)
++udc_seq_show(struct seq_file *m, void *d)
+ {
+- char *buf = page;
+- struct pxa2xx_udc *dev = _dev;
+- char *next = buf;
+- unsigned size = count;
++ struct pxa2xx_udc *dev = m->private;
+ unsigned long flags;
+- int i, t;
++ int i;
+ u32 tmp;
+
+- if (off != 0)
+- return 0;
++
++ BUG_ON(dev == NULL);
+
+ local_irq_save(flags);
+
+ /* basic device status */
+- t = scnprintf(next, size, DRIVER_DESC "\n"
++ seq_printf(m, DRIVER_DESC "\n"
+ "%s version: %s\nGadget driver: %s\nHost %s\n\n",
+ driver_name, DRIVER_VERSION SIZE_STR "(pio)",
+ dev->driver ? dev->driver->driver.name : "(none)",
+ is_vbus_present() ? "full speed" : "disconnected");
+- size -= t;
+- next += t;
+
+ /* registers for device and ep0 */
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
+ UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
+- size -= t;
+- next += t;
+
+ tmp = UDCCR;
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "udccr %02X =%s%s%s%s%s%s%s%s\n", tmp,
+ (tmp & UDCCR_REM) ? " rem" : "",
+ (tmp & UDCCR_RSTIR) ? " rstir" : "",
+@@ -1041,11 +1033,9 @@ udc_proc_read(char *page, char **start, off_t off, int count,
+ (tmp & UDCCR_RSM) ? " rsm" : "",
+ (tmp & UDCCR_UDA) ? " uda" : "",
+ (tmp & UDCCR_UDE) ? " ude" : "");
+- size -= t;
+- next += t;
+
+ tmp = UDCCS0;
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "udccs0 %02X =%s%s%s%s%s%s%s%s\n", tmp,
+ (tmp & UDCCS0_SA) ? " sa" : "",
+ (tmp & UDCCS0_RNE) ? " rne" : "",
+@@ -1055,28 +1045,22 @@ udc_proc_read(char *page, char **start, off_t off, int count,
+ (tmp & UDCCS0_FTF) ? " ftf" : "",
+ (tmp & UDCCS0_IPR) ? " ipr" : "",
+ (tmp & UDCCS0_OPR) ? " opr" : "");
+- size -= t;
+- next += t;
+
+ if (dev->has_cfr) {
+ tmp = UDCCFR;
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "udccfr %02X =%s%s\n", tmp,
+ (tmp & UDCCFR_AREN) ? " aren" : "",
+ (tmp & UDCCFR_ACM) ? " acm" : "");
+- size -= t;
+- next += t;
+ }
+
+ if (!is_vbus_present() || !dev->driver)
+ goto done;
+
+- t = scnprintf(next, size, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
++ seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
+ dev->stats.write.bytes, dev->stats.write.ops,
+ dev->stats.read.bytes, dev->stats.read.ops,
+ dev->stats.irqs);
+- size -= t;
+- next += t;
+
+ /* dump endpoint queues */
+ for (i = 0; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+@@ -1090,55 +1074,57 @@ udc_proc_read(char *page, char **start, off_t off, int count,
+ if (!d)
+ continue;
+ tmp = *dev->ep [i].reg_udccs;
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "%s max %d %s udccs %02x irqs %lu\n",
+ ep->ep.name, le16_to_cpu (d->wMaxPacketSize),
+ "pio", tmp, ep->pio_irqs);
+ /* TODO translate all five groups of udccs bits! */
+
+ } else /* ep0 should only have one transfer queued */
+- t = scnprintf(next, size, "ep0 max 16 pio irqs %lu\n",
++ seq_printf(m, "ep0 max 16 pio irqs %lu\n",
+ ep->pio_irqs);
+- if (t <= 0 || t > size)
+- goto done;
+- size -= t;
+- next += t;
+
+ if (list_empty(&ep->queue)) {
+- t = scnprintf(next, size, "\t(nothing queued)\n");
+- if (t <= 0 || t > size)
+- goto done;
+- size -= t;
+- next += t;
++ seq_printf(m, "\t(nothing queued)\n");
+ continue;
+ }
+ list_for_each_entry(req, &ep->queue, queue) {
+- t = scnprintf(next, size,
++ seq_printf(m,
+ "\treq %p len %d/%d buf %p\n",
+ &req->req, req->req.actual,
+ req->req.length, req->req.buf);
+- if (t <= 0 || t > size)
+- goto done;
+- size -= t;
+- next += t;
+ }
+ }
+
+ done:
+ local_irq_restore(flags);
+- *eof = 1;
+- return count - size;
++ return 0;
+ }
+
+-#define create_proc_files() \
+- create_proc_read_entry(proc_node_name, 0, NULL, udc_proc_read, dev)
+-#define remove_proc_files() \
+- remove_proc_entry(proc_node_name, NULL)
++static int
++udc_debugfs_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, udc_seq_show, inode->i_private);
++}
++
++static const struct file_operations debug_fops = {
++ .open = udc_debugfs_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++ .owner = THIS_MODULE,
++};
++
++#define create_debug_files(dev) \
++ dev->debugfs_udc = debugfs_create_file(dev->gadget.name, S_IRUGO, \
++ NULL, dev, &debug_fops)
++#define remove_debug_files(dev) \
++ if (dev->debugfs_udc) debugfs_remove(dev->debugfs_udc)
+
+ #else /* !CONFIG_USB_GADGET_DEBUG_FILES */
+
+-#define create_proc_files() do {} while (0)
+-#define remove_proc_files() do {} while (0)
++#define create_debug_files(dev) do {} while (0)
++#define remove_debug_files(dev) do {} while (0)
+
+ #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
+
+@@ -2245,7 +2231,7 @@ lubbock_fail0:
+ goto err_vbus_irq;
+ }
+ }
+- create_proc_files();
++ create_debug_files(dev);
+
+ return 0;
+
+@@ -2282,7 +2268,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
+ return -EBUSY;
+
+ udc_disable(dev);
+- remove_proc_files();
++ remove_debug_files(dev);
+
+ if (dev->got_irq) {
+ free_irq(platform_get_irq(pdev, 0), dev);
+diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
+index 1db46d7..c08b1a2 100644
+--- a/drivers/usb/gadget/pxa2xx_udc.h
++++ b/drivers/usb/gadget/pxa2xx_udc.h
+@@ -129,6 +129,10 @@ struct pxa2xx_udc {
+ struct pxa2xx_udc_mach_info *mach;
+ u64 dma_mask;
+ struct pxa2xx_ep ep [PXA_UDC_NUM_ENDPOINTS];
++
++#ifdef CONFIG_USB_GADGET_DEBUG_FS
++ struct dentry *debugfs_udc;
++#endif
+ };
+
+ /*-------------------------------------------------------------------------*/
+@@ -153,6 +157,8 @@ static struct pxa2xx_udc *the_controller;
+
+ #ifdef DEBUG
+
++static int is_vbus_present(void);
++
+ static const char *state_name[] = {
+ "EP0_IDLE",
+ "EP0_IN_DATA_PHASE", "EP0_OUT_DATA_PHASE",
+@@ -207,8 +213,7 @@ dump_state(struct pxa2xx_udc *dev)
+ unsigned i;
+
+ DMSG("%s %s, uicr %02X.%02X, usir %02X.%02x, ufnr %02X.%02X\n",
+- //is_usb_connected() ? "host " : "disconnected",
+- "host ",
++ is_vbus_present() ? "host " : "disconnected",
+ state_name[dev->ep0state],
+ UICR1, UICR0, USIR1, USIR0, UFNRH, UFNRL);
+ dump_udccr("udccr");
+@@ -224,7 +230,7 @@ dump_state(struct pxa2xx_udc *dev)
+ } else
+ DMSG("ep0 driver '%s'\n", dev->driver->driver.name);
+
+- //if (!is_usb_connected())
+- // return;
++ if (!is_vbus_present())
++ return;
+
+ dump_udccs0 ("udccs0");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch b/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch
new file mode 100644
index 0000000000..7bf4ad02d6
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch
@@ -0,0 +1,225 @@
+From b9a0fdbf333b461682d5da8b9aaa42f4de91ffcf Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 10 Feb 2008 03:29:17 +0300
+Subject: [PATCH 18/64] Fix the pxa2xx_udc to balance calls to clk_enable/clk_disable
+
+Signed-off-by: Dmitry Baryshkov dbaryshkov@gmail.com
+---
+ drivers/usb/gadget/pxa2xx_udc.c | 84 +++++++++++++++++++++++----------------
+ drivers/usb/gadget/pxa2xx_udc.h | 6 ++-
+ 2 files changed, 54 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
+index 2900556..8e32d07 100644
+--- a/drivers/usb/gadget/pxa2xx_udc.c
++++ b/drivers/usb/gadget/pxa2xx_udc.c
+@@ -680,7 +680,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+
+ /* kickstart this i/o queue? */
+ if (list_empty(&ep->queue) && !ep->stopped) {
+- if (ep->desc == 0 /* ep0 */) {
++ if (ep->desc == NULL /* ep0 */) {
+ unsigned length = _req->length;
+
+ switch (dev->ep0state) {
+@@ -734,7 +734,7 @@ pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
+ }
+
+ /* pio or dma irq handler advances the queue. */
+- if (likely (req != 0))
++ if (likely (req != NULL))
+ list_add_tail(&req->queue, &ep->queue);
+ local_irq_restore(flags);
+
+@@ -934,20 +934,35 @@ static void udc_disable(struct pxa2xx_udc *);
+ /* We disable the UDC -- and its 48 MHz clock -- whenever it's not
+ * in active use.
+ */
+-static int pullup(struct pxa2xx_udc *udc, int is_active)
++static int pullup(struct pxa2xx_udc *udc)
+ {
+- is_active = is_active && udc->vbus && udc->pullup;
++ int is_active = udc->vbus && udc->pullup && ! udc->suspended;
+ DMSG("%s\n", is_active ? "active" : "inactive");
+- if (is_active)
+- udc_enable(udc);
+- else {
+- if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
+- DMSG("disconnect %s\n", udc->driver
+- ? udc->driver->driver.name
+- : "(no driver)");
+- stop_activity(udc, udc->driver);
++ if (is_active) {
++ if (!udc->active) {
++ udc->active = 1;
++#ifdef CONFIG_ARCH_PXA
++ /* Enable clock for USB device */
++ clk_enable(udc->clk);
++#endif
++ udc_enable(udc);
+ }
+- udc_disable(udc);
++ } else {
++ if (udc->active) {
++ if (udc->gadget.speed != USB_SPEED_UNKNOWN) {
++ DMSG("disconnect %s\n", udc->driver
++ ? udc->driver->driver.name
++ : "(no driver)");
++ stop_activity(udc, udc->driver);
++ }
++ udc_disable(udc);
++#ifdef CONFIG_ARCH_PXA
++ /* Disable clock for USB device */
++ clk_disable(udc->clk);
++#endif
++ udc->active = 0;
++ }
++
+ }
+ return 0;
+ }
+@@ -958,9 +973,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+ struct pxa2xx_udc *udc;
+
+ udc = container_of(_gadget, struct pxa2xx_udc, gadget);
+- udc->vbus = is_active = (is_active != 0);
++ udc->vbus = (is_active != 0);
+ DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
+- pullup(udc, is_active);
++ pullup(udc);
+ return 0;
+ }
+
+@@ -975,9 +990,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
+ if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+ return -EOPNOTSUPP;
+
+- is_active = (is_active != 0);
+- udc->pullup = is_active;
+- pullup(udc, is_active);
++ udc->pullup = (is_active != 0);
++ pullup(udc);
+ return 0;
+ }
+
+@@ -998,7 +1012,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = {
+
+ static struct pxa2xx_udc memory;
+ static int
+-udc_seq_show(struct seq_file *m, void *d)
++udc_seq_show(struct seq_file *m, void *_d)
+ {
+ struct pxa2xx_udc *dev = m->private;
+ unsigned long flags;
+@@ -1145,11 +1159,6 @@ static void udc_disable(struct pxa2xx_udc *dev)
+
+ udc_clear_mask_UDCCR(UDCCR_UDE);
+
+-#ifdef CONFIG_ARCH_PXA
+- /* Disable clock for USB device */
+- clk_disable(dev->clk);
+-#endif
+-
+ ep0_idle (dev);
+ dev->gadget.speed = USB_SPEED_UNKNOWN;
+ }
+@@ -1190,11 +1199,6 @@ static void udc_enable (struct pxa2xx_udc *dev)
+ {
+ udc_clear_mask_UDCCR(UDCCR_UDE);
+
+-#ifdef CONFIG_ARCH_PXA
+- /* Enable clock for USB device */
+- clk_enable(dev->clk);
+-#endif
+-
+ /* try to clear these bits before we enable the udc */
+ udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR);
+
+@@ -1285,7 +1289,7 @@ fail:
+ * for set_configuration as well as eventual disconnect.
+ */
+ DMSG("registered gadget driver '%s'\n", driver->driver.name);
+- pullup(dev, 1);
++ pullup(dev);
+ dump_state(dev);
+ return 0;
+ }
+@@ -1328,7 +1332,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+ return -EINVAL;
+
+ local_irq_disable();
+- pullup(dev, 0);
++ dev->pullup = 0;
++ pullup(dev);
+ stop_activity(dev, driver);
+ local_irq_enable();
+
+@@ -2267,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
+ if (dev->driver)
+ return -EBUSY;
+
+- udc_disable(dev);
++ dev->pullup = 0;
++ pullup(dev);
++
+ remove_debug_files(dev);
+
+ if (dev->got_irq) {
+@@ -2315,10 +2322,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev)
+ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
+ {
+ struct pxa2xx_udc *udc = platform_get_drvdata(dev);
++ unsigned long flags;
+
+ if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+ WARN("USB host won't detect disconnect!\n");
+- pullup(udc, 0);
++ udc->suspended = 1;
++
++ local_irq_save(flags);
++ pullup(udc);
++ local_irq_restore(flags);
+
+ return 0;
+ }
+@@ -2326,8 +2338,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
+ static int pxa2xx_udc_resume(struct platform_device *dev)
+ {
+ struct pxa2xx_udc *udc = platform_get_drvdata(dev);
++ unsigned long flags;
+
+- pullup(udc, 1);
++ udc->suspended = 0;
++ local_irq_save(flags);
++ pullup(udc);
++ local_irq_restore(flags);
+
+ return 0;
+ }
+diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
+index c08b1a2..93586b2 100644
+--- a/drivers/usb/gadget/pxa2xx_udc.h
++++ b/drivers/usb/gadget/pxa2xx_udc.h
+@@ -119,7 +119,9 @@ struct pxa2xx_udc {
+ has_cfr : 1,
+ req_pending : 1,
+ req_std : 1,
+- req_config : 1;
++ req_config : 1,
++ suspended : 1,
++ active : 1;
+
+ #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200))
+ struct timer_list timer;
+@@ -239,7 +241,7 @@ dump_state(struct pxa2xx_udc *dev)
+ dev->stats.read.bytes, dev->stats.read.ops);
+
+ for (i = 1; i < PXA_UDC_NUM_ENDPOINTS; i++) {
+- if (dev->ep [i].desc == 0)
++ if (dev->ep [i].desc == NULL)
+ continue;
+ DMSG ("udccs%d = %02x\n", i, *dev->ep->reg_udccs);
+ }
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch
new file mode 100644
index 0000000000..4b4107d655
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0019-pxa-remove-periodic-mode-emulation-support.patch
@@ -0,0 +1,128 @@
+From bda65817167cce5294e1d84670f36815262ed550 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk@dyn-67.arm.linux.org.uk>
+Date: Sun, 3 Feb 2008 21:58:12 +0300
+Subject: [PATCH 19/64] pxa: remove periodic mode emulation support
+
+Apparantly, the generic time subsystem can accurately emulate periodic
+mode via the one-shot support code, so we don't need our own periodic
+emulation code anymore. Just ensure that we build support for one shot
+into the generic time subsystem.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/mach-pxa/time.c | 61 ++++++----------------------------------------
+ 2 files changed, 9 insertions(+), 53 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index a04f507..1be7182 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -345,6 +345,7 @@ config ARCH_PXA
+ select GENERIC_GPIO
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
++ select TICK_ONESHOT
+ help
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+
+diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
+index fbfa192..3c4abbf 100644
+--- a/arch/arm/mach-pxa/time.c
++++ b/arch/arm/mach-pxa/time.c
+@@ -59,55 +59,17 @@ unsigned long long sched_clock(void)
+ }
+
+
++#define MIN_OSCR_DELTA 16
++
+ static irqreturn_t
+ pxa_ost0_interrupt(int irq, void *dev_id)
+ {
+- int next_match;
+ struct clock_event_device *c = dev_id;
+
+- if (c->mode == CLOCK_EVT_MODE_ONESHOT) {
+- /* Disarm the compare/match, signal the event. */
+- OIER &= ~OIER_E0;
+- OSSR = OSSR_M0;
+- c->event_handler(c);
+- } else if (c->mode == CLOCK_EVT_MODE_PERIODIC) {
+- /* Call the event handler as many times as necessary
+- * to recover missed events, if any (if we update
+- * OSMR0 and OSCR0 is still ahead of us, we've missed
+- * the event). As we're dealing with that, re-arm the
+- * compare/match for the next event.
+- *
+- * HACK ALERT:
+- *
+- * There's a latency between the instruction that
+- * writes to OSMR0 and the actual commit to the
+- * physical hardware, because the CPU doesn't (have
+- * to) run at bus speed, there's a write buffer
+- * between the CPU and the bus, etc. etc. So if the
+- * target OSCR0 is "very close", to the OSMR0 load
+- * value, the update to OSMR0 might not get to the
+- * hardware in time and we'll miss that interrupt.
+- *
+- * To be safe, if the new OSMR0 is "very close" to the
+- * target OSCR0 value, we call the event_handler as
+- * though the event actually happened. According to
+- * Nico's comment in the previous version of this
+- * code, experience has shown that 6 OSCR ticks is
+- * "very close" but he went with 8. We will use 16,
+- * based on the results of testing on PXA270.
+- *
+- * To be doubly sure, we also tell clkevt via
+- * clockevents_register_device() not to ask for
+- * anything that might put us "very close".
+- */
+-#define MIN_OSCR_DELTA 16
+- do {
+- OSSR = OSSR_M0;
+- next_match = (OSMR0 += LATCH);
+- c->event_handler(c);
+- } while (((signed long)(next_match - OSCR) <= MIN_OSCR_DELTA)
+- && (c->mode == CLOCK_EVT_MODE_PERIODIC));
+- }
++ /* Disarm the compare/match, signal the event. */
++ OIER &= ~OIER_E0;
++ OSSR = OSSR_M0;
++ c->event_handler(c);
+
+ return IRQ_HANDLED;
+ }
+@@ -133,14 +95,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+ unsigned long irqflags;
+
+ switch (mode) {
+- case CLOCK_EVT_MODE_PERIODIC:
+- raw_local_irq_save(irqflags);
+- OSSR = OSSR_M0;
+- OIER |= OIER_E0;
+- OSMR0 = OSCR + LATCH;
+- raw_local_irq_restore(irqflags);
+- break;
+-
+ case CLOCK_EVT_MODE_ONESHOT:
+ raw_local_irq_save(irqflags);
+ OIER &= ~OIER_E0;
+@@ -158,13 +112,14 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
+ break;
+
+ case CLOCK_EVT_MODE_RESUME:
++ case CLOCK_EVT_MODE_PERIODIC:
+ break;
+ }
+ }
+
+ static struct clock_event_device ckevt_pxa_osmr0 = {
+ .name = "osmr0",
+- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
++ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .rating = 200,
+ .cpumask = CPU_MASK_CPU0,
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch b/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch
new file mode 100644
index 0000000000..0a42bc5855
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch
@@ -0,0 +1,257 @@
+From ee8ca5742e0000dd2369ef4d328c2c1117276a3b Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 02:56:28 +0300
+Subject: [PATCH 20/64] Provide dew device/clock backports from 2.6.24-git
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/mach-pxa/devices.h | 12 ++++++++++++
+ arch/arm/mach-pxa/pxa25x.c | 18 ++++++++++++------
+ arch/arm/mach-pxa/pxa27x.c | 22 ++++++++++++++++------
+ arch/arm/mach-pxa/pxa3xx.c | 30 ++++++++++++++++++++++++++++++
+ kernel/Makefile | 1 +
+ 6 files changed, 72 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 1be7182..10faf9c 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -367,6 +367,7 @@ config ARCH_SA1100
+ select ARCH_DISCONTIGMEM_ENABLE
+ select ARCH_MTD_XIP
+ select GENERIC_GPIO
++ select GENERIC_TIME
+ help
+ Support for StrongARM 11x0 based boards.
+
+diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h
+index 94c8d5c..96c7c89 100644
+--- a/arch/arm/mach-pxa/devices.h
++++ b/arch/arm/mach-pxa/devices.h
+@@ -1,4 +1,6 @@
+ extern struct platform_device pxa_device_mci;
++extern struct platform_device pxa3xx_device_mci2;
++extern struct platform_device pxa3xx_device_mci3;
+ extern struct platform_device pxa_device_udc;
+ extern struct platform_device pxa_device_fb;
+ extern struct platform_device pxa_device_ffuart;
+@@ -12,3 +14,13 @@ extern struct platform_device pxa_device_rtc;
+
+ extern struct platform_device pxa27x_device_i2c_power;
+ extern struct platform_device pxa27x_device_ohci;
++
++extern struct platform_device pxa25x_device_ssp;
++extern struct platform_device pxa25x_device_nssp;
++extern struct platform_device pxa25x_device_assp;
++extern struct platform_device pxa27x_device_ssp1;
++extern struct platform_device pxa27x_device_ssp2;
++extern struct platform_device pxa27x_device_ssp3;
++extern struct platform_device pxa3xx_device_ssp4;
++
++void __init pxa_register_device(struct platform_device *dev, void *data);
+diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
+index 006a6e0..5988d99 100644
+--- a/arch/arm/mach-pxa/pxa25x.c
++++ b/arch/arm/mach-pxa/pxa25x.c
+@@ -123,12 +123,15 @@ static struct clk pxa25x_clks[] = {
+ INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
+ INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
+ INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
++
++ INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev),
++ INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev),
++ INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
++
+ /*
+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+ INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+- INIT_CKEN("SSPCLK", SSP, 3686400, 0, NULL),
+ INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
+- INIT_CKEN("NSSPCLK", NSSP, 3686400, 0, NULL),
+ */
+ INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
+ };
+@@ -216,8 +219,6 @@ static void pxa25x_cpu_pm_restore(unsigned long *sleep_save)
+
+ static void pxa25x_cpu_pm_enter(suspend_state_t state)
+ {
+- CKEN = 0;
+-
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ /* set resume return address */
+@@ -239,6 +240,8 @@ static void __init pxa25x_init_pm(void)
+ {
+ pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns;
+ }
++#else
++static inline void pxa25x_init_pm(void) {}
+ #endif
+
+ /* PXA25x: supports wakeup from GPIO0..GPIO15 and RTC alarm
+@@ -300,6 +303,9 @@ static struct platform_device *pxa25x_devices[] __initdata = {
+ &pxa_device_i2s,
+ &pxa_device_ficp,
+ &pxa_device_rtc,
++ &pxa25x_device_ssp,
++ &pxa25x_device_nssp,
++ &pxa25x_device_assp,
+ };
+
+ static int __init pxa25x_init(void)
+@@ -315,9 +321,9 @@ static int __init pxa25x_init(void)
+
+ if ((ret = pxa_init_dma(16)))
+ return ret;
+-#ifdef CONFIG_PM
++
+ pxa25x_init_pm();
+-#endif
++
+ ret = platform_add_devices(pxa25x_devices,
+ ARRAY_SIZE(pxa25x_devices));
+ }
+diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
+index 8e126e6..30ca4fd 100644
+--- a/arch/arm/mach-pxa/pxa27x.c
++++ b/arch/arm/mach-pxa/pxa27x.c
+@@ -150,11 +150,12 @@ static struct clk pxa27x_clks[] = {
+ INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
+ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
+
++ INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
++ INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
++ INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
++
+ /*
+ INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
+- INIT_CKEN("SSPCLK", SSP1, 13000000, 0, NULL),
+- INIT_CKEN("SSPCLK", SSP2, 13000000, 0, NULL),
+- INIT_CKEN("SSPCLK", SSP3, 13000000, 0, NULL),
+ INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
+ INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
+ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
+@@ -304,6 +305,8 @@ static void __init pxa27x_init_pm(void)
+ {
+ pxa_cpu_pm_fns = &pxa27x_cpu_pm_fns;
+ }
++#else
++static inline void pxa27x_init_pm(void) {}
+ #endif
+
+ /* PXA27x: Various gpios can issue wakeup events. This logic only
+@@ -423,6 +426,11 @@ struct platform_device pxa27x_device_i2c_power = {
+ .num_resources = ARRAY_SIZE(i2c_power_resources),
+ };
+
++void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
++{
++ pxa27x_device_i2c_power.dev.platform_data = info;
++}
++
+ static struct platform_device *devices[] __initdata = {
+ &pxa_device_mci,
+ &pxa_device_udc,
+@@ -435,7 +443,9 @@ static struct platform_device *devices[] __initdata = {
+ &pxa_device_ficp,
+ &pxa_device_rtc,
+ &pxa27x_device_i2c_power,
+- &pxa27x_device_ohci,
++ &pxa27x_device_ssp1,
++ &pxa27x_device_ssp2,
++ &pxa27x_device_ssp3,
+ };
+
+ static int __init pxa27x_init(void)
+@@ -446,9 +456,9 @@ static int __init pxa27x_init(void)
+
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+-#ifdef CONFIG_PM
++
+ pxa27x_init_pm();
+-#endif
++
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+ return ret;
+diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
+index 61d9c9d..ccab9da 100644
+--- a/arch/arm/mach-pxa/pxa3xx.c
++++ b/arch/arm/mach-pxa/pxa3xx.c
+@@ -189,8 +189,31 @@ static struct clk pxa3xx_clks[] = {
+
+ PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
+ PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
++ PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
++
++ PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
++ PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
++ PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
++ PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
++
++ PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
++ PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
++ PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
+ };
+
++#ifdef CONFIG_PM
++#define SLEEP_SAVE_SIZE 4
++
++#define ISRAM_START 0x5c000000
++#define ISRAM_SIZE SZ_256K
++
++static inline void pxa3xx_init_pm(void) {}
++static inline void pxa3xx_init_irq_pm(void) {}
++#else
++static inline void pxa3xx_init_pm(void) {}
++static inline void pxa3xx_init_irq_pm(void) {}
++#endif
++
+ void __init pxa3xx_init_irq(void)
+ {
+ /* enable CP6 access */
+@@ -202,6 +225,7 @@ void __init pxa3xx_init_irq(void)
+ pxa_init_irq_low();
+ pxa_init_irq_high();
+ pxa_init_irq_gpio(128);
++ pxa3xx_init_irq_pm();
+ }
+
+ /*
+@@ -219,6 +243,10 @@ static struct platform_device *devices[] __initdata = {
+ &pxa_device_i2s,
+ &pxa_device_ficp,
+ &pxa_device_rtc,
++ &pxa27x_device_ssp1,
++ &pxa27x_device_ssp2,
++ &pxa27x_device_ssp3,
++ &pxa3xx_device_ssp4,
+ };
+
+ static int __init pxa3xx_init(void)
+@@ -231,6 +259,8 @@ static int __init pxa3xx_init(void)
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+
++ pxa3xx_init_pm();
++
+ return platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+ return 0;
+diff --git a/kernel/Makefile b/kernel/Makefile
+index dfa9695..6d9a87c 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -57,6 +57,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
+ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
+ obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+ obj-$(CONFIG_MARKERS) += marker.o
++obj-$(CONFIG_LATENCYTOP) += latencytop.o
+
+ ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch b/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch
new file mode 100644
index 0000000000..3f8512128a
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch
@@ -0,0 +1,121 @@
+From b77665c545bc260d2b93add129413e4a724d7e6e Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell@users.sourceforge.net>
+Date: Fri, 18 Jan 2008 00:35:00 +0300
+Subject: [PATCH 21/64] Add an empty drivers/gpio directory for gpiolib infrastructure and GPIO
+ expanders. It will be populated by later patches.
+
+This won't be the only place to hold such gpio_chip code. Many external chips
+add a few GPIOs as secondary functionality (such as MFD drivers) and platform
+code frequently needs to closely integrate GPIO and IRQ support.
+
+This is placed *early* in the build/link sequence since it's common for other
+drivers to depend on GPIOs to do their work, so they must be initialized early
+in the device_initcall() sequence.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Acked-by: Jean Delvare <khali@linux-fr.org>
+Cc: Eric Miao <eric.miao@marvell.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Cc: Philipp Zabel <philipp.zabel@gmail.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Ben Gardner <bgardner@wabtec.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+ arch/arm/Kconfig | 2 ++
+ drivers/Kconfig | 2 ++
+ drivers/Makefile | 1 +
+ drivers/gpio/Kconfig | 32 ++++++++++++++++++++++++++++++++
+ drivers/gpio/Makefile | 3 +++
+ 5 files changed, 40 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/gpio/Kconfig
+ create mode 100644 drivers/gpio/Makefile
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 10faf9c..06ca241 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1042,6 +1042,8 @@ source "drivers/i2c/Kconfig"
+
+ source "drivers/spi/Kconfig"
+
++source "drivers/gpio/Kconfig"
++
+ source "drivers/w1/Kconfig"
+
+ source "drivers/power/Kconfig"
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index f4076d9..90e295a 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -52,6 +52,8 @@ source "drivers/i2c/Kconfig"
+
+ source "drivers/spi/Kconfig"
+
++source "drivers/gpio/Kconfig"
++
+ source "drivers/w1/Kconfig"
+
+ source "drivers/power/Kconfig"
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 8cb37e3..8e5101f 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -5,6 +5,7 @@
+ # Rewritten to use lists instead of if-statements.
+ #
+
++obj-$(CONFIG_HAVE_GPIO_LIB) += gpio/
+ obj-$(CONFIG_PCI) += pci/
+ obj-$(CONFIG_PARISC) += parisc/
+ obj-$(CONFIG_RAPIDIO) += rapidio/
+diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
+new file mode 100644
+index 0000000..560687c
+--- /dev/null
++++ b/drivers/gpio/Kconfig
+@@ -0,0 +1,32 @@
++#
++# GPIO infrastructure and expanders
++#
++
++config HAVE_GPIO_LIB
++ bool
++ help
++ Platforms select gpiolib if they use this infrastructure
++ for all their GPIOs, usually starting with ones integrated
++ into SOC processors.
++
++menu "GPIO Support"
++ depends on HAVE_GPIO_LIB
++
++config DEBUG_GPIO
++ bool "Debug GPIO calls"
++ depends on DEBUG_KERNEL
++ help
++ Say Y here to add some extra checks and diagnostics to GPIO calls.
++ The checks help ensure that GPIOs have been properly initialized
++ before they are used and that sleeping calls aren not made from
++ nonsleeping contexts. They can make bitbanged serial protocols
++ slower. The diagnostics help catch the type of setup errors
++ that are most common when setting up new platforms or boards.
++
++# put expanders in the right section, in alphabetical order
++
++comment "I2C GPIO expanders:"
++
++comment "SPI GPIO expanders:"
++
++endmenu
+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
+new file mode 100644
+index 0000000..cdbba6b
+--- /dev/null
++++ b/drivers/gpio/Makefile
+@@ -0,0 +1,3 @@
++# gpio support: dedicated expander chips, etc
++
++ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch b/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch
new file mode 100644
index 0000000000..f39fedbbaa
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch
@@ -0,0 +1,746 @@
+From 3a0251c01446f3a6763e4406ca5495102db63aa4 Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell@users.sourceforge.net>
+Date: Fri, 18 Jan 2008 00:35:20 +0300
+Subject: [PATCH 22/64] Provide new implementation infrastructure that platforms may choose to use
+ when implementing the GPIO programming interface. Platforms can update their
+ GPIO support to use this. In many cases the incremental cost to access a
+ non-inlined GPIO should be less than a dozen instructions, with the memory
+ cost being about a page (total) of extra data and code. The upside is:
+
+ * Providing two features which were "want to have (but OK to defer)" when
+ GPIO interfaces were first discussed in November 2006:
+
+ - A "struct gpio_chip" to plug in GPIOs that aren't directly supported
+ by SOC platforms, but come from FPGAs or other multifunction devices
+ using conventional device registers (like UCB-1x00 or SM501 GPIOs,
+ and southbridges in PCs with more open specs than usual).
+
+ - Full support for message-based GPIO expanders, where registers are
+ accessed through sleeping I/O calls. Previous support for these
+ "cansleep" calls was just stubs. (One example: the widely used
+ pcf8574 I2C chips, with 8 GPIOs each.)
+
+ * Including a non-stub implementation of the gpio_{request,free}() calls,
+ making those calls much more useful. The diagnostic labels are also
+ recorded given DEBUG_FS, so /sys/kernel/debug/gpio can show a snapshot
+ of all GPIOs known to this infrastructure.
+
+The driver programming interfaces introduced in 2.6.21 do not change at all;
+this infrastructure is entirely below those covers.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Jean Delvare <khali@linux-fr.org>
+Cc: Eric Miao <eric.miao@marvell.com>
+Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Cc: Philipp Zabel <philipp.zabel@gmail.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Ben Gardner <bgardner@wabtec.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+ drivers/gpio/Makefile | 2 +
+ drivers/gpio/gpiolib.c | 567 ++++++++++++++++++++++++++++++++++++++++++++
+ include/asm-generic/gpio.h | 98 ++++++++
+ 3 files changed, 667 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/gpio/gpiolib.c
+
+diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
+index cdbba6b..2db28ce 100644
+--- a/drivers/gpio/Makefile
++++ b/drivers/gpio/Makefile
+@@ -1,3 +1,5 @@
+ # gpio support: dedicated expander chips, etc
+
+ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
++
++obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+new file mode 100644
+index 0000000..d8db2f8
+--- /dev/null
++++ b/drivers/gpio/gpiolib.c
+@@ -0,0 +1,567 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/irq.h>
++#include <linux/spinlock.h>
++
++#include <asm/gpio.h>
++
++
++/* Optional implementation infrastructure for GPIO interfaces.
++ *
++ * Platforms may want to use this if they tend to use very many GPIOs
++ * that aren't part of a System-On-Chip core; or across I2C/SPI/etc.
++ *
++ * When kernel footprint or instruction count is an issue, simpler
++ * implementations may be preferred. The GPIO programming interface
++ * allows for inlining speed-critical get/set operations for common
++ * cases, so that access to SOC-integrated GPIOs can sometimes cost
++ * only an instruction or two per bit.
++ */
++
++
++/* When debugging, extend minimal trust to callers and platform code.
++ * Also emit diagnostic messages that may help initial bringup, when
++ * board setup or driver bugs are most common.
++ *
++ * Otherwise, minimize overhead in what may be bitbanging codepaths.
++ */
++#ifdef DEBUG
++#define extra_checks 1
++#else
++#define extra_checks 0
++#endif
++
++/* gpio_lock prevents conflicts during gpio_desc[] table updates.
++ * While any GPIO is requested, its gpio_chip is not removable;
++ * each GPIO's "requested" flag serves as a lock and refcount.
++ */
++static DEFINE_SPINLOCK(gpio_lock);
++
++struct gpio_desc {
++ struct gpio_chip *chip;
++ unsigned long flags;
++/* flag symbols are bit numbers */
++#define FLAG_REQUESTED 0
++#define FLAG_IS_OUT 1
++
++#ifdef CONFIG_DEBUG_FS
++ const char *label;
++#endif
++};
++static struct gpio_desc gpio_desc[ARCH_NR_GPIOS];
++
++static inline void desc_set_label(struct gpio_desc *d, const char *label)
++{
++#ifdef CONFIG_DEBUG_FS
++ d->label = label;
++#endif
++}
++
++/* Warn when drivers omit gpio_request() calls -- legal but ill-advised
++ * when setting direction, and otherwise illegal. Until board setup code
++ * and drivers use explicit requests everywhere (which won't happen when
++ * those calls have no teeth) we can't avoid autorequesting. This nag
++ * message should motivate switching to explicit requests...
++ */
++static void gpio_ensure_requested(struct gpio_desc *desc)
++{
++ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
++ pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc));
++ desc_set_label(desc, "[auto]");
++ }
++}
++
++/* caller holds gpio_lock *OR* gpio is marked as requested */
++static inline struct gpio_chip *gpio_to_chip(unsigned gpio)
++{
++ return gpio_desc[gpio].chip;
++}
++
++/**
++ * gpiochip_add() - register a gpio_chip
++ * @chip: the chip to register, with chip->base initialized
++ * Context: potentially before irqs or kmalloc will work
++ *
++ * Returns a negative errno if the chip can't be registered, such as
++ * because the chip->base is invalid or already associated with a
++ * different chip. Otherwise it returns zero as a success code.
++ */
++int gpiochip_add(struct gpio_chip *chip)
++{
++ unsigned long flags;
++ int status = 0;
++ unsigned id;
++
++ /* NOTE chip->base negative is reserved to mean a request for
++ * dynamic allocation. We don't currently support that.
++ */
++
++ if (chip->base < 0 || (chip->base + chip->ngpio) >= ARCH_NR_GPIOS) {
++ status = -EINVAL;
++ goto fail;
++ }
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ /* these GPIO numbers must not be managed by another gpio_chip */
++ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
++ if (gpio_desc[id].chip != NULL) {
++ status = -EBUSY;
++ break;
++ }
++ }
++ if (status == 0) {
++ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
++ gpio_desc[id].chip = chip;
++ gpio_desc[id].flags = 0;
++ }
++ }
++
++ spin_unlock_irqrestore(&gpio_lock, flags);
++fail:
++ /* failures here can mean systems won't boot... */
++ if (status)
++ pr_err("gpiochip_add: gpios %d..%d (%s) not registered\n",
++ chip->base, chip->base + chip->ngpio,
++ chip->label ? : "generic");
++ return status;
++}
++EXPORT_SYMBOL_GPL(gpiochip_add);
++
++/**
++ * gpiochip_remove() - unregister a gpio_chip
++ * @chip: the chip to unregister
++ *
++ * A gpio_chip with any GPIOs still requested may not be removed.
++ */
++int gpiochip_remove(struct gpio_chip *chip)
++{
++ unsigned long flags;
++ int status = 0;
++ unsigned id;
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ for (id = chip->base; id < chip->base + chip->ngpio; id++) {
++ if (test_bit(FLAG_REQUESTED, &gpio_desc[id].flags)) {
++ status = -EBUSY;
++ break;
++ }
++ }
++ if (status == 0) {
++ for (id = chip->base; id < chip->base + chip->ngpio; id++)
++ gpio_desc[id].chip = NULL;
++ }
++
++ spin_unlock_irqrestore(&gpio_lock, flags);
++ return status;
++}
++EXPORT_SYMBOL_GPL(gpiochip_remove);
++
++
++/* These "optional" allocation calls help prevent drivers from stomping
++ * on each other, and help provide better diagnostics in debugfs.
++ * They're called even less than the "set direction" calls.
++ */
++int gpio_request(unsigned gpio, const char *label)
++{
++ struct gpio_desc *desc;
++ int status = -EINVAL;
++ unsigned long flags;
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ if (gpio >= ARCH_NR_GPIOS)
++ goto done;
++ desc = &gpio_desc[gpio];
++ if (desc->chip == NULL)
++ goto done;
++
++ /* NOTE: gpio_request() can be called in early boot,
++ * before IRQs are enabled.
++ */
++
++ if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
++ desc_set_label(desc, label ? : "?");
++ status = 0;
++ } else
++ status = -EBUSY;
++
++done:
++ if (status)
++ pr_debug("gpio_request: gpio-%d (%s) status %d\n",
++ gpio, label ? : "?", status);
++ spin_unlock_irqrestore(&gpio_lock, flags);
++ return status;
++}
++EXPORT_SYMBOL_GPL(gpio_request);
++
++void gpio_free(unsigned gpio)
++{
++ unsigned long flags;
++ struct gpio_desc *desc;
++
++ if (gpio >= ARCH_NR_GPIOS) {
++ WARN_ON(extra_checks);
++ return;
++ }
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ desc = &gpio_desc[gpio];
++ if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags))
++ desc_set_label(desc, NULL);
++ else
++ WARN_ON(extra_checks);
++
++ spin_unlock_irqrestore(&gpio_lock, flags);
++}
++EXPORT_SYMBOL_GPL(gpio_free);
++
++
++/**
++ * gpiochip_is_requested - return string iff signal was requested
++ * @chip: controller managing the signal
++ * @offset: of signal within controller's 0..(ngpio - 1) range
++ *
++ * Returns NULL if the GPIO is not currently requested, else a string.
++ * If debugfs support is enabled, the string returned is the label passed
++ * to gpio_request(); otherwise it is a meaningless constant.
++ *
++ * This function is for use by GPIO controller drivers. The label can
++ * help with diagnostics, and knowing that the signal is used as a GPIO
++ * can help avoid accidentally multiplexing it to another controller.
++ */
++const char *gpiochip_is_requested(struct gpio_chip *chip, unsigned offset)
++{
++ unsigned gpio = chip->base + offset;
++
++ if (gpio >= ARCH_NR_GPIOS || gpio_desc[gpio].chip != chip)
++ return NULL;
++ if (test_bit(FLAG_REQUESTED, &gpio_desc[gpio].flags) == 0)
++ return NULL;
++#ifdef CONFIG_DEBUG_FS
++ return gpio_desc[gpio].label;
++#else
++ return "?";
++#endif
++}
++EXPORT_SYMBOL_GPL(gpiochip_is_requested);
++
++
++/* Drivers MUST set GPIO direction before making get/set calls. In
++ * some cases this is done in early boot, before IRQs are enabled.
++ *
++ * As a rule these aren't called more than once (except for drivers
++ * using the open-drain emulation idiom) so these are natural places
++ * to accumulate extra debugging checks. Note that we can't (yet)
++ * rely on gpio_request() having been called beforehand.
++ */
++
++int gpio_direction_input(unsigned gpio)
++{
++ unsigned long flags;
++ struct gpio_chip *chip;
++ struct gpio_desc *desc = &gpio_desc[gpio];
++ int status = -EINVAL;
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ if (gpio >= ARCH_NR_GPIOS)
++ goto fail;
++ chip = desc->chip;
++ if (!chip || !chip->get || !chip->direction_input)
++ goto fail;
++ gpio -= chip->base;
++ if (gpio >= chip->ngpio)
++ goto fail;
++ gpio_ensure_requested(desc);
++
++ /* now we know the gpio is valid and chip won't vanish */
++
++ spin_unlock_irqrestore(&gpio_lock, flags);
++
++ might_sleep_if(extra_checks && chip->can_sleep);
++
++ status = chip->direction_input(chip, gpio);
++ if (status == 0)
++ clear_bit(FLAG_IS_OUT, &desc->flags);
++ return status;
++fail:
++ spin_unlock_irqrestore(&gpio_lock, flags);
++ if (status)
++ pr_debug("%s: gpio-%d status %d\n",
++ __FUNCTION__, gpio, status);
++ return status;
++}
++EXPORT_SYMBOL_GPL(gpio_direction_input);
++
++int gpio_direction_output(unsigned gpio, int value)
++{
++ unsigned long flags;
++ struct gpio_chip *chip;
++ struct gpio_desc *desc = &gpio_desc[gpio];
++ int status = -EINVAL;
++
++ spin_lock_irqsave(&gpio_lock, flags);
++
++ if (gpio >= ARCH_NR_GPIOS)
++ goto fail;
++ chip = desc->chip;
++ if (!chip || !chip->set || !chip->direction_output)
++ goto fail;
++ gpio -= chip->base;
++ if (gpio >= chip->ngpio)
++ goto fail;
++ gpio_ensure_requested(desc);
++
++ /* now we know the gpio is valid and chip won't vanish */
++
++ spin_unlock_irqrestore(&gpio_lock, flags);
++
++ might_sleep_if(extra_checks && chip->can_sleep);
++
++ status = chip->direction_output(chip, gpio, value);
++ if (status == 0)
++ set_bit(FLAG_IS_OUT, &desc->flags);
++ return status;
++fail:
++ spin_unlock_irqrestore(&gpio_lock, flags);
++ if (status)
++ pr_debug("%s: gpio-%d status %d\n",
++ __FUNCTION__, gpio, status);
++ return status;
++}
++EXPORT_SYMBOL_GPL(gpio_direction_output);
++
++
++/* I/O calls are only valid after configuration completed; the relevant
++ * "is this a valid GPIO" error checks should already have been done.
++ *
++ * "Get" operations are often inlinable as reading a pin value register,
++ * and masking the relevant bit in that register.
++ *
++ * When "set" operations are inlinable, they involve writing that mask to
++ * one register to set a low value, or a different register to set it high.
++ * Otherwise locking is needed, so there may be little value to inlining.
++ *
++ *------------------------------------------------------------------------
++ *
++ * IMPORTANT!!! The hot paths -- get/set value -- assume that callers
++ * have requested the GPIO. That can include implicit requesting by
++ * a direction setting call. Marking a gpio as requested locks its chip
++ * in memory, guaranteeing that these table lookups need no more locking
++ * and that gpiochip_remove() will fail.
++ *
++ * REVISIT when debugging, consider adding some instrumentation to ensure
++ * that the GPIO was actually requested.
++ */
++
++/**
++ * __gpio_get_value() - return a gpio's value
++ * @gpio: gpio whose value will be returned
++ * Context: any
++ *
++ * This is used directly or indirectly to implement gpio_get_value().
++ * It returns the zero or nonzero value provided by the associated
++ * gpio_chip.get() method; or zero if no such method is provided.
++ */
++int __gpio_get_value(unsigned gpio)
++{
++ struct gpio_chip *chip;
++
++ chip = gpio_to_chip(gpio);
++ WARN_ON(extra_checks && chip->can_sleep);
++ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
++}
++EXPORT_SYMBOL_GPL(__gpio_get_value);
++
++/**
++ * __gpio_set_value() - assign a gpio's value
++ * @gpio: gpio whose value will be assigned
++ * @value: value to assign
++ * Context: any
++ *
++ * This is used directly or indirectly to implement gpio_set_value().
++ * It invokes the associated gpio_chip.set() method.
++ */
++void __gpio_set_value(unsigned gpio, int value)
++{
++ struct gpio_chip *chip;
++
++ chip = gpio_to_chip(gpio);
++ WARN_ON(extra_checks && chip->can_sleep);
++ chip->set(chip, gpio - chip->base, value);
++}
++EXPORT_SYMBOL_GPL(__gpio_set_value);
++
++/**
++ * __gpio_cansleep() - report whether gpio value access will sleep
++ * @gpio: gpio in question
++ * Context: any
++ *
++ * This is used directly or indirectly to implement gpio_cansleep(). It
++ * returns nonzero if access reading or writing the GPIO value can sleep.
++ */
++int __gpio_cansleep(unsigned gpio)
++{
++ struct gpio_chip *chip;
++
++ /* only call this on GPIOs that are valid! */
++ chip = gpio_to_chip(gpio);
++
++ return chip->can_sleep;
++}
++EXPORT_SYMBOL_GPL(__gpio_cansleep);
++
++
++
++/* There's no value in making it easy to inline GPIO calls that may sleep.
++ * Common examples include ones connected to I2C or SPI chips.
++ */
++
++int gpio_get_value_cansleep(unsigned gpio)
++{
++ struct gpio_chip *chip;
++
++ might_sleep_if(extra_checks);
++ chip = gpio_to_chip(gpio);
++ return chip->get(chip, gpio - chip->base);
++}
++EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
++
++void gpio_set_value_cansleep(unsigned gpio, int value)
++{
++ struct gpio_chip *chip;
++
++ might_sleep_if(extra_checks);
++ chip = gpio_to_chip(gpio);
++ chip->set(chip, gpio - chip->base, value);
++}
++EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);
++
++
++#ifdef CONFIG_DEBUG_FS
++
++#include <linux/debugfs.h>
++#include <linux/seq_file.h>
++
++
++static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
++{
++ unsigned i;
++ unsigned gpio = chip->base;
++ struct gpio_desc *gdesc = &gpio_desc[gpio];
++ int is_out;
++
++ for (i = 0; i < chip->ngpio; i++, gpio++, gdesc++) {
++ if (!test_bit(FLAG_REQUESTED, &gdesc->flags))
++ continue;
++
++ is_out = test_bit(FLAG_IS_OUT, &gdesc->flags);
++ seq_printf(s, " gpio-%-3d (%-12s) %s %s",
++ gpio, gdesc->label,
++ is_out ? "out" : "in ",
++ chip->get
++ ? (chip->get(chip, i) ? "hi" : "lo")
++ : "? ");
++
++ if (!is_out) {
++ int irq = gpio_to_irq(gpio);
++ struct irq_desc *desc = irq_desc + irq;
++
++ /* This races with request_irq(), set_irq_type(),
++ * and set_irq_wake() ... but those are "rare".
++ *
++ * More significantly, trigger type flags aren't
++ * currently maintained by genirq.
++ */
++ if (irq >= 0 && desc->action) {
++ char *trigger;
++
++ switch (desc->status & IRQ_TYPE_SENSE_MASK) {
++ case IRQ_TYPE_NONE:
++ trigger = "(default)";
++ break;
++ case IRQ_TYPE_EDGE_FALLING:
++ trigger = "edge-falling";
++ break;
++ case IRQ_TYPE_EDGE_RISING:
++ trigger = "edge-rising";
++ break;
++ case IRQ_TYPE_EDGE_BOTH:
++ trigger = "edge-both";
++ break;
++ case IRQ_TYPE_LEVEL_HIGH:
++ trigger = "level-high";
++ break;
++ case IRQ_TYPE_LEVEL_LOW:
++ trigger = "level-low";
++ break;
++ default:
++ trigger = "?trigger?";
++ break;
++ }
++
++ seq_printf(s, " irq-%d %s%s",
++ irq, trigger,
++ (desc->status & IRQ_WAKEUP)
++ ? " wakeup" : "");
++ }
++ }
++
++ seq_printf(s, "\n");
++ }
++}
++
++static int gpiolib_show(struct seq_file *s, void *unused)
++{
++ struct gpio_chip *chip = NULL;
++ unsigned gpio;
++ int started = 0;
++
++ /* REVISIT this isn't locked against gpio_chip removal ... */
++
++ for (gpio = 0; gpio < ARCH_NR_GPIOS; gpio++) {
++ if (chip == gpio_desc[gpio].chip)
++ continue;
++ chip = gpio_desc[gpio].chip;
++ if (!chip)
++ continue;
++
++ seq_printf(s, "%sGPIOs %d-%d, %s%s:\n",
++ started ? "\n" : "",
++ chip->base, chip->base + chip->ngpio - 1,
++ chip->label ? : "generic",
++ chip->can_sleep ? ", can sleep" : "");
++ started = 1;
++ if (chip->dbg_show)
++ chip->dbg_show(s, chip);
++ else
++ gpiolib_dbg_show(s, chip);
++ }
++ return 0;
++}
++
++static int gpiolib_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, gpiolib_show, NULL);
++}
++
++static struct file_operations gpiolib_operations = {
++ .open = gpiolib_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int __init gpiolib_debugfs_init(void)
++{
++ /* /sys/kernel/debug/gpio */
++ (void) debugfs_create_file("gpio", S_IFREG | S_IRUGO,
++ NULL, NULL, &gpiolib_operations);
++ return 0;
++}
++subsys_initcall(gpiolib_debugfs_init);
++
++#endif /* DEBUG_FS */
+diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
+index 2d0aab1..f29a502 100644
+--- a/include/asm-generic/gpio.h
++++ b/include/asm-generic/gpio.h
+@@ -1,6 +1,102 @@
+ #ifndef _ASM_GENERIC_GPIO_H
+ #define _ASM_GENERIC_GPIO_H
+
++#ifdef CONFIG_HAVE_GPIO_LIB
++
++/* Platforms may implement their GPIO interface with library code,
++ * at a small performance cost for non-inlined operations and some
++ * extra memory (for code and for per-GPIO table entries).
++ *
++ * While the GPIO programming interface defines valid GPIO numbers
++ * to be in the range 0..MAX_INT, this library restricts them to the
++ * smaller range 0..ARCH_NR_GPIOS.
++ */
++
++#ifndef ARCH_NR_GPIOS
++#define ARCH_NR_GPIOS 256
++#endif
++
++struct seq_file;
++
++/**
++ * struct gpio_chip - abstract a GPIO controller
++ * @label: for diagnostics
++ * @direction_input: configures signal "offset" as input, or returns error
++ * @get: returns value for signal "offset"; for output signals this
++ * returns either the value actually sensed, or zero
++ * @direction_output: configures signal "offset" as output, or returns error
++ * @set: assigns output value for signal "offset"
++ * @dbg_show: optional routine to show contents in debugfs; default code
++ * will be used when this is omitted, but custom code can show extra
++ * state (such as pullup/pulldown configuration).
++ * @base: identifies the first GPIO number handled by this chip; or, if
++ * negative during registration, requests dynamic ID allocation.
++ * @ngpio: the number of GPIOs handled by this controller; the last GPIO
++ * handled is (base + ngpio - 1).
++ * @can_sleep: flag must be set iff get()/set() methods sleep, as they
++ * must while accessing GPIO expander chips over I2C or SPI
++ *
++ * A gpio_chip can help platforms abstract various sources of GPIOs so
++ * they can all be accessed through a common programing interface.
++ * Example sources would be SOC controllers, FPGAs, multifunction
++ * chips, dedicated GPIO expanders, and so on.
++ *
++ * Each chip controls a number of signals, identified in method calls
++ * by "offset" values in the range 0..(@ngpio - 1). When those signals
++ * are referenced through calls like gpio_get_value(gpio), the offset
++ * is calculated by subtracting @base from the gpio number.
++ */
++struct gpio_chip {
++ char *label;
++
++ int (*direction_input)(struct gpio_chip *chip,
++ unsigned offset);
++ int (*get)(struct gpio_chip *chip,
++ unsigned offset);
++ int (*direction_output)(struct gpio_chip *chip,
++ unsigned offset, int value);
++ void (*set)(struct gpio_chip *chip,
++ unsigned offset, int value);
++ void (*dbg_show)(struct seq_file *s,
++ struct gpio_chip *chip);
++ int base;
++ u16 ngpio;
++ unsigned can_sleep:1;
++};
++
++extern const char *gpiochip_is_requested(struct gpio_chip *chip,
++ unsigned offset);
++
++/* add/remove chips */
++extern int gpiochip_add(struct gpio_chip *chip);
++extern int __must_check gpiochip_remove(struct gpio_chip *chip);
++
++
++/* Always use the library code for GPIO management calls,
++ * or when sleeping may be involved.
++ */
++extern int gpio_request(unsigned gpio, const char *label);
++extern void gpio_free(unsigned gpio);
++
++extern int gpio_direction_input(unsigned gpio);
++extern int gpio_direction_output(unsigned gpio, int value);
++
++extern int gpio_get_value_cansleep(unsigned gpio);
++extern void gpio_set_value_cansleep(unsigned gpio, int value);
++
++
++/* A platform's <asm/gpio.h> code may want to inline the I/O calls when
++ * the GPIO is constant and refers to some always-present controller,
++ * giving direct access to chip registers and tight bitbanging loops.
++ */
++extern int __gpio_get_value(unsigned gpio);
++extern void __gpio_set_value(unsigned gpio, int value);
++
++extern int __gpio_cansleep(unsigned gpio);
++
++
++#else
++
+ /* platforms that don't directly support access to GPIOs through I2C, SPI,
+ * or other blocking infrastructure can use these wrappers.
+ */
+@@ -22,4 +118,6 @@ static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+ gpio_set_value(gpio, value);
+ }
+
++#endif
++
+ #endif /* _ASM_GENERIC_GPIO_H */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch b/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch
new file mode 100644
index 0000000000..7a37be85cf
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch
@@ -0,0 +1,498 @@
+From 49da9bd487e54164a75503e0037a054cce697ed5 Mon Sep 17 00:00:00 2001
+From: Philipp Zabel <philipp.zabel@gmail.com>
+Date: Tue, 12 Feb 2008 04:38:12 +0300
+Subject: [PATCH 23/64] This adds gpiolib support for the PXA architecture:
+ - move all GPIO API functions from generic.c into gpio.c
+ - convert the gpio_get/set_value macros into inline functions
+
+This makes it easier to hook up GPIOs provided by external chips like
+ASICs and CPLDs.
+
+Signed-off-by: Philipp Zabel <philipp.zabel@gmail.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Cc: Jean Delvare <khali@linux-fr.org>
+Cc: Eric Miao <eric.miao@marvell.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Cc: Ben Gardner <bgardner@wabtec.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/mach-pxa/Makefile | 3 +-
+ arch/arm/mach-pxa/generic.c | 93 ----------------
+ arch/arm/mach-pxa/generic.h | 1 +
+ arch/arm/mach-pxa/gpio.c | 197 +++++++++++++++++++++++++++++++++++
+ arch/arm/mach-pxa/irq.c | 2 +
+ include/asm-arm/arch-pxa/gpio.h | 48 ++++-----
+ include/asm-arm/arch-pxa/pxa-regs.h | 13 +++
+ 8 files changed, 236 insertions(+), 122 deletions(-)
+ create mode 100644 arch/arm/mach-pxa/gpio.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 06ca241..423e953 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -346,6 +346,7 @@ config ARCH_PXA
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select TICK_ONESHOT
++ select HAVE_GPIO_LIB
+ help
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+
+diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
+index 4263527..5cb0216 100644
+--- a/arch/arm/mach-pxa/Makefile
++++ b/arch/arm/mach-pxa/Makefile
+@@ -3,7 +3,8 @@
+ #
+
+ # Common support (must be linked before board specific support)
+-obj-y += clock.o generic.o irq.o dma.o time.o
++obj-y += clock.o generic.o irq.o dma.o \
++ time.o gpio.o
+ obj-$(CONFIG_PXA25x) += pxa25x.o
+ obj-$(CONFIG_PXA27x) += pxa27x.o
+ obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
+diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
+index 1c34946..6c07292 100644
+--- a/arch/arm/mach-pxa/generic.c
++++ b/arch/arm/mach-pxa/generic.c
+@@ -32,7 +32,6 @@
+ #include <asm/mach/map.h>
+
+ #include <asm/arch/pxa-regs.h>
+-#include <asm/arch/gpio.h>
+ #include <asm/arch/udc.h>
+ #include <asm/arch/pxafb.h>
+ #include <asm/arch/mmc.h>
+@@ -73,97 +72,6 @@ unsigned int get_memclk_frequency_10khz(void)
+ EXPORT_SYMBOL(get_memclk_frequency_10khz);
+
+ /*
+- * Handy function to set GPIO alternate functions
+- */
+-int pxa_last_gpio;
+-
+-int pxa_gpio_mode(int gpio_mode)
+-{
+- unsigned long flags;
+- int gpio = gpio_mode & GPIO_MD_MASK_NR;
+- int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
+- int gafr;
+-
+- if (gpio > pxa_last_gpio)
+- return -EINVAL;
+-
+- local_irq_save(flags);
+- if (gpio_mode & GPIO_DFLT_LOW)
+- GPCR(gpio) = GPIO_bit(gpio);
+- else if (gpio_mode & GPIO_DFLT_HIGH)
+- GPSR(gpio) = GPIO_bit(gpio);
+- if (gpio_mode & GPIO_MD_MASK_DIR)
+- GPDR(gpio) |= GPIO_bit(gpio);
+- else
+- GPDR(gpio) &= ~GPIO_bit(gpio);
+- gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
+- GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
+- local_irq_restore(flags);
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL(pxa_gpio_mode);
+-
+-int gpio_direction_input(unsigned gpio)
+-{
+- unsigned long flags;
+- u32 mask;
+-
+- if (gpio > pxa_last_gpio)
+- return -EINVAL;
+-
+- mask = GPIO_bit(gpio);
+- local_irq_save(flags);
+- GPDR(gpio) &= ~mask;
+- local_irq_restore(flags);
+-
+- return 0;
+-}
+-EXPORT_SYMBOL(gpio_direction_input);
+-
+-int gpio_direction_output(unsigned gpio, int value)
+-{
+- unsigned long flags;
+- u32 mask;
+-
+- if (gpio > pxa_last_gpio)
+- return -EINVAL;
+-
+- mask = GPIO_bit(gpio);
+- local_irq_save(flags);
+- if (value)
+- GPSR(gpio) = mask;
+- else
+- GPCR(gpio) = mask;
+- GPDR(gpio) |= mask;
+- local_irq_restore(flags);
+-
+- return 0;
+-}
+-EXPORT_SYMBOL(gpio_direction_output);
+-
+-/*
+- * Return GPIO level
+- */
+-int pxa_gpio_get_value(unsigned gpio)
+-{
+- return __gpio_get_value(gpio);
+-}
+-
+-EXPORT_SYMBOL(pxa_gpio_get_value);
+-
+-/*
+- * Set output GPIO level
+- */
+-void pxa_gpio_set_value(unsigned gpio, int value)
+-{
+- __gpio_set_value(gpio, value);
+-}
+-
+-EXPORT_SYMBOL(pxa_gpio_set_value);
+-
+-/*
+ * Routine to safely enable or disable a clock in the CKEN
+ */
+ void __pxa_set_cken(int clock, int enable)
+@@ -178,7 +86,6 @@ void __pxa_set_cken(int clock, int enable)
+
+ local_irq_restore(flags);
+ }
+-
+ EXPORT_SYMBOL(__pxa_set_cken);
+
+ /*
+diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
+index b30f240..727a9f5 100644
+--- a/arch/arm/mach-pxa/generic.h
++++ b/arch/arm/mach-pxa/generic.h
+@@ -16,6 +16,7 @@ extern void __init pxa_init_irq_low(void);
+ extern void __init pxa_init_irq_high(void);
+ extern void __init pxa_init_irq_gpio(int gpio_nr);
+ extern void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int));
++extern void __init pxa_init_gpio(int gpio_nr);
+ extern void __init pxa25x_init_irq(void);
+ extern void __init pxa27x_init_irq(void);
+ extern void __init pxa3xx_init_irq(void);
+diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
+new file mode 100644
+index 0000000..8638dd7
+--- /dev/null
++++ b/arch/arm/mach-pxa/gpio.c
+@@ -0,0 +1,197 @@
++/*
++ * linux/arch/arm/mach-pxa/gpio.c
++ *
++ * Generic PXA GPIO handling
++ *
++ * Author: Nicolas Pitre
++ * Created: Jun 15, 2001
++ * Copyright: 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 version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++
++#include <asm/gpio.h>
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/arch/pxa-regs.h>
++
++#include "generic.h"
++
++
++struct pxa_gpio_chip {
++ struct gpio_chip chip;
++ void __iomem *regbase;
++};
++
++int pxa_last_gpio;
++
++/*
++ * Configure pins for GPIO or other functions
++ */
++int pxa_gpio_mode(int gpio_mode)
++{
++ unsigned long flags;
++ int gpio = gpio_mode & GPIO_MD_MASK_NR;
++ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
++ int gafr;
++
++ if (gpio > pxa_last_gpio)
++ return -EINVAL;
++
++ local_irq_save(flags);
++ if (gpio_mode & GPIO_DFLT_LOW)
++ GPCR(gpio) = GPIO_bit(gpio);
++ else if (gpio_mode & GPIO_DFLT_HIGH)
++ GPSR(gpio) = GPIO_bit(gpio);
++ if (gpio_mode & GPIO_MD_MASK_DIR)
++ GPDR(gpio) |= GPIO_bit(gpio);
++ else
++ GPDR(gpio) &= ~GPIO_bit(gpio);
++ gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
++ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
++ local_irq_restore(flags);
++
++ return 0;
++}
++EXPORT_SYMBOL(pxa_gpio_mode);
++
++static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
++{
++ unsigned long flags;
++ u32 mask = 1 << offset;
++ u32 value;
++ struct pxa_gpio_chip *pxa;
++ void __iomem *gpdr;
++
++ pxa = container_of(chip, struct pxa_gpio_chip, chip);
++ gpdr = pxa->regbase + GPDR_OFFSET;
++ local_irq_save(flags);
++ value = __raw_readl(gpdr);
++ value &= ~mask;
++ __raw_writel(value, gpdr);
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++static int pxa_gpio_direction_output(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ unsigned long flags;
++ u32 mask = 1 << offset;
++ u32 tmp;
++ struct pxa_gpio_chip *pxa;
++ void __iomem *gpdr;
++
++ pxa = container_of(chip, struct pxa_gpio_chip, chip);
++ __raw_writel(mask,
++ pxa->regbase + (value ? GPSR_OFFSET : GPCR_OFFSET));
++ gpdr = pxa->regbase + GPDR_OFFSET;
++ local_irq_save(flags);
++ tmp = __raw_readl(gpdr);
++ tmp |= mask;
++ __raw_writel(tmp, gpdr);
++ local_irq_restore(flags);
++
++ return 0;
++}
++
++/*
++ * Return GPIO level
++ */
++static int pxa_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ u32 mask = 1 << offset;
++ struct pxa_gpio_chip *pxa;
++
++ pxa = container_of(chip, struct pxa_gpio_chip, chip);
++ return __raw_readl(pxa->regbase + GPLR_OFFSET) & mask;
++}
++
++/*
++ * Set output GPIO level
++ */
++static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
++{
++ u32 mask = 1 << offset;
++ struct pxa_gpio_chip *pxa;
++
++ pxa = container_of(chip, struct pxa_gpio_chip, chip);
++
++ if (value)
++ __raw_writel(mask, pxa->regbase + GPSR_OFFSET);
++ else
++ __raw_writel(mask, pxa->regbase + GPCR_OFFSET);
++}
++
++static struct pxa_gpio_chip pxa_gpio_chip[] = {
++ [0] = {
++ .regbase = GPIO0_BASE,
++ .chip = {
++ .label = "gpio-0",
++ .direction_input = pxa_gpio_direction_input,
++ .direction_output = pxa_gpio_direction_output,
++ .get = pxa_gpio_get,
++ .set = pxa_gpio_set,
++ .base = 0,
++ .ngpio = 32,
++ },
++ },
++ [1] = {
++ .regbase = GPIO1_BASE,
++ .chip = {
++ .label = "gpio-1",
++ .direction_input = pxa_gpio_direction_input,
++ .direction_output = pxa_gpio_direction_output,
++ .get = pxa_gpio_get,
++ .set = pxa_gpio_set,
++ .base = 32,
++ .ngpio = 32,
++ },
++ },
++ [2] = {
++ .regbase = GPIO2_BASE,
++ .chip = {
++ .label = "gpio-2",
++ .direction_input = pxa_gpio_direction_input,
++ .direction_output = pxa_gpio_direction_output,
++ .get = pxa_gpio_get,
++ .set = pxa_gpio_set,
++ .base = 64,
++ .ngpio = 32, /* 21 for PXA25x */
++ },
++ },
++#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
++ [3] = {
++ .regbase = GPIO3_BASE,
++ .chip = {
++ .label = "gpio-3",
++ .direction_input = pxa_gpio_direction_input,
++ .direction_output = pxa_gpio_direction_output,
++ .get = pxa_gpio_get,
++ .set = pxa_gpio_set,
++ .base = 96,
++ .ngpio = 32,
++ },
++ },
++#endif
++};
++
++void __init pxa_init_gpio(int gpio_nr)
++{
++ int i;
++
++ /* add a GPIO chip for each register bank.
++ * the last PXA25x register only contains 21 GPIOs
++ */
++ for (i = 0; i < gpio_nr; i += 32) {
++ if (i+32 > gpio_nr)
++ pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
++ gpiochip_add(&pxa_gpio_chip[i/32].chip);
++ }
++}
+diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
+index 07acb45..d0965ef 100644
+--- a/arch/arm/mach-pxa/irq.c
++++ b/arch/arm/mach-pxa/irq.c
+@@ -310,6 +310,8 @@ void __init pxa_init_irq_gpio(int gpio_nr)
+ /* Install handler for GPIO>=2 edge detect interrupts */
+ set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
+ set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
++
++ pxa_init_gpio(gpio_nr);
+ }
+
+ void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int))
+diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h
+index 9dbc2dc..bdbf5f9 100644
+--- a/include/asm-arm/arch-pxa/gpio.h
++++ b/include/asm-arm/arch-pxa/gpio.h
+@@ -28,43 +28,35 @@
+ #include <asm/irq.h>
+ #include <asm/hardware.h>
+
+-static inline int gpio_request(unsigned gpio, const char *label)
+-{
+- return 0;
+-}
++#include <asm-generic/gpio.h>
+
+-static inline void gpio_free(unsigned gpio)
+-{
+- return;
+-}
+
+-extern int gpio_direction_input(unsigned gpio);
+-extern int gpio_direction_output(unsigned gpio, int value);
++/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
++ * Those cases currently cause holes in the GPIO number space.
++ */
++#define NR_BUILTIN_GPIO 128
+
+-static inline int __gpio_get_value(unsigned gpio)
++static inline int gpio_get_value(unsigned gpio)
+ {
+- return GPLR(gpio) & GPIO_bit(gpio);
++ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO))
++ return GPLR(gpio) & GPIO_bit(gpio);
++ else
++ return __gpio_get_value(gpio);
+ }
+
+-#define gpio_get_value(gpio) \
+- (__builtin_constant_p(gpio) ? \
+- __gpio_get_value(gpio) : \
+- pxa_gpio_get_value(gpio))
+-
+-static inline void __gpio_set_value(unsigned gpio, int value)
++static inline void gpio_set_value(unsigned gpio, int value)
+ {
+- if (value)
+- GPSR(gpio) = GPIO_bit(gpio);
+- else
+- GPCR(gpio) = GPIO_bit(gpio);
++ if (__builtin_constant_p(gpio) && (gpio < NR_BUILTIN_GPIO)) {
++ if (value)
++ GPSR(gpio) = GPIO_bit(gpio);
++ else
++ GPCR(gpio) = GPIO_bit(gpio);
++ } else {
++ __gpio_set_value(gpio, value);
++ }
+ }
+
+-#define gpio_set_value(gpio,value) \
+- (__builtin_constant_p(gpio) ? \
+- __gpio_set_value(gpio, value) : \
+- pxa_gpio_set_value(gpio, value))
+-
+-#include <asm-generic/gpio.h> /* cansleep wrappers */
++#define gpio_cansleep __gpio_cansleep
+
+ #define gpio_to_irq(gpio) IRQ_GPIO(gpio)
+ #define irq_to_gpio(irq) IRQ_TO_GPIO(irq)
+diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
+index 1bd398d..bd57417 100644
+--- a/include/asm-arm/arch-pxa/pxa-regs.h
++++ b/include/asm-arm/arch-pxa/pxa-regs.h
+@@ -1131,6 +1131,19 @@
+ * General Purpose I/O
+ */
+
++#define GPIO0_BASE ((void __iomem *)io_p2v(0x40E00000))
++#define GPIO1_BASE ((void __iomem *)io_p2v(0x40E00004))
++#define GPIO2_BASE ((void __iomem *)io_p2v(0x40E00008))
++#define GPIO3_BASE ((void __iomem *)io_p2v(0x40E00100))
++
++#define GPLR_OFFSET 0x00
++#define GPDR_OFFSET 0x0C
++#define GPSR_OFFSET 0x18
++#define GPCR_OFFSET 0x24
++#define GRER_OFFSET 0x30
++#define GFER_OFFSET 0x3C
++#define GEDR_OFFSET 0x48
++
+ #define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */
+ #define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */
+ #define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch b/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch
new file mode 100644
index 0000000000..e460379de6
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch
@@ -0,0 +1,238 @@
+From 7ba82399f2d2df6114ad552999f2e1b9a19cb47a Mon Sep 17 00:00:00 2001
+From: David Brownell <dbrownell@users.sourceforge.net>
+Date: Sat, 19 Jan 2008 19:41:18 +0300
+Subject: [PATCH 24/64] Update Documentation/gpio.txt, primarily to include the new "gpiolib"
+ infrastructure.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Jean Delvare <khali@linux-fr.org>
+Cc: Eric Miao <eric.miao@marvell.com>
+Cc: Sam Ravnborg <sam@ravnborg.org>
+Cc: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Cc: Philipp Zabel <philipp.zabel@gmail.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Ben Gardner <bgardner@wabtec.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+ Documentation/gpio.txt | 133 +++++++++++++++++++++++++++++++++++++++++++----
+ 1 files changed, 121 insertions(+), 12 deletions(-)
+
+diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
+index 6bc2ba2..8da724e 100644
+--- a/Documentation/gpio.txt
++++ b/Documentation/gpio.txt
+@@ -32,7 +32,7 @@ The exact capabilities of GPIOs vary between systems. Common options:
+ - Input values are likewise readable (1, 0). Some chips support readback
+ of pins configured as "output", which is very useful in such "wire-OR"
+ cases (to support bidirectional signaling). GPIO controllers may have
+- input de-glitch logic, sometimes with software controls.
++ input de-glitch/debounce logic, sometimes with software controls.
+
+ - Inputs can often be used as IRQ signals, often edge triggered but
+ sometimes level triggered. Such IRQs may be configurable as system
+@@ -60,10 +60,13 @@ used on a board that's wired differently. Only least-common-denominator
+ functionality can be very portable. Other features are platform-specific,
+ and that can be critical for glue logic.
+
+-Plus, this doesn't define an implementation framework, just an interface.
++Plus, this doesn't require any implementation framework, just an interface.
+ One platform might implement it as simple inline functions accessing chip
+ registers; another might implement it by delegating through abstractions
+-used for several very different kinds of GPIO controller.
++used for several very different kinds of GPIO controller. (There is some
++optional code supporting such an implementation strategy, described later
++in this document, but drivers acting as clients to the GPIO interface must
++not care how it's implemented.)
+
+ That said, if the convention is supported on their platform, drivers should
+ use it when possible. Platforms should declare GENERIC_GPIO support in
+@@ -121,6 +124,11 @@ before tasking is enabled, as part of early board setup.
+ For output GPIOs, the value provided becomes the initial output value.
+ This helps avoid signal glitching during system startup.
+
++For compatibility with legacy interfaces to GPIOs, setting the direction
++of a GPIO implicitly requests that GPIO (see below) if it has not been
++requested already. That compatibility may be removed in the future;
++explicitly requesting GPIOs is strongly preferred.
++
+ Setting the direction can fail if the GPIO number is invalid, or when
+ that particular GPIO can't be used in that mode. It's generally a bad
+ idea to rely on boot firmware to have set the direction correctly, since
+@@ -133,6 +141,7 @@ Spinlock-Safe GPIO access
+ -------------------------
+ Most GPIO controllers can be accessed with memory read/write instructions.
+ That doesn't need to sleep, and can safely be done from inside IRQ handlers.
++(That includes hardirq contexts on RT kernels.)
+
+ Use these calls to access such GPIOs:
+
+@@ -145,7 +154,7 @@ Use these calls to access such GPIOs:
+ The values are boolean, zero for low, nonzero for high. When reading the
+ value of an output pin, the value returned should be what's seen on the
+ pin ... that won't always match the specified output value, because of
+-issues including wire-OR and output latencies.
++issues including open-drain signaling and output latencies.
+
+ The get/set calls have no error returns because "invalid GPIO" should have
+ been reported earlier from gpio_direction_*(). However, note that not all
+@@ -170,7 +179,8 @@ get to the head of a queue to transmit a command and get its response.
+ This requires sleeping, which can't be done from inside IRQ handlers.
+
+ Platforms that support this type of GPIO distinguish them from other GPIOs
+-by returning nonzero from this call:
++by returning nonzero from this call (which requires a valid GPIO number,
++either explicitly or implicitly requested):
+
+ int gpio_cansleep(unsigned gpio);
+
+@@ -209,8 +219,11 @@ before tasking is enabled, as part of early board setup.
+ These calls serve two basic purposes. One is marking the signals which
+ are actually in use as GPIOs, for better diagnostics; systems may have
+ several hundred potential GPIOs, but often only a dozen are used on any
+-given board. Another is to catch conflicts between drivers, reporting
+-errors when drivers wrongly think they have exclusive use of that signal.
++given board. Another is to catch conflicts, identifying errors when
++(a) two or more drivers wrongly think they have exclusive use of that
++signal, or (b) something wrongly believes it's safe to remove drivers
++needed to manage a signal that's in active use. That is, requesting a
++GPIO can serve as a kind of lock.
+
+ These two calls are optional because not not all current Linux platforms
+ offer such functionality in their GPIO support; a valid implementation
+@@ -223,6 +236,9 @@ Note that requesting a GPIO does NOT cause it to be configured in any
+ way; it just marks that GPIO as in use. Separate code must handle any
+ pin setup (e.g. controlling which pin the GPIO uses, pullup/pulldown).
+
++Also note that it's your responsibility to have stopped using a GPIO
++before you free it.
++
+
+ GPIOs mapped to IRQs
+ --------------------
+@@ -238,7 +254,7 @@ map between them using calls like:
+
+ Those return either the corresponding number in the other namespace, or
+ else a negative errno code if the mapping can't be done. (For example,
+-some GPIOs can't used as IRQs.) It is an unchecked error to use a GPIO
++some GPIOs can't be used as IRQs.) It is an unchecked error to use a GPIO
+ number that wasn't set up as an input using gpio_direction_input(), or
+ to use an IRQ number that didn't originally come from gpio_to_irq().
+
+@@ -299,17 +315,110 @@ Related to multiplexing is configuration and enabling of the pullups or
+ pulldowns integrated on some platforms. Not all platforms support them,
+ or support them in the same way; and any given board might use external
+ pullups (or pulldowns) so that the on-chip ones should not be used.
++(When a circuit needs 5 kOhm, on-chip 100 kOhm resistors won't do.)
+
+ There are other system-specific mechanisms that are not specified here,
+ like the aforementioned options for input de-glitching and wire-OR output.
+ Hardware may support reading or writing GPIOs in gangs, but that's usually
+ configuration dependent: for GPIOs sharing the same bank. (GPIOs are
+ commonly grouped in banks of 16 or 32, with a given SOC having several such
+-banks.) Some systems can trigger IRQs from output GPIOs. Code relying on
+-such mechanisms will necessarily be nonportable.
++banks.) Some systems can trigger IRQs from output GPIOs, or read values
++from pins not managed as GPIOs. Code relying on such mechanisms will
++necessarily be nonportable.
+
+-Dynamic definition of GPIOs is not currently supported; for example, as
++Dynamic definition of GPIOs is not currently standard; for example, as
+ a side effect of configuring an add-on board with some GPIO expanders.
+
+ These calls are purely for kernel space, but a userspace API could be built
+-on top of it.
++on top of them.
++
++
++GPIO implementor's framework (OPTIONAL)
++=======================================
++As noted earlier, there is an optional implementation framework making it
++easier for platforms to support different kinds of GPIO controller using
++the same programming interface.
++
++As a debugging aid, if debugfs is available a /sys/kernel/debug/gpio file
++will be found there. That will list all the controllers registered through
++this framework, and the state of the GPIOs currently in use.
++
++
++Controller Drivers: gpio_chip
++-----------------------------
++In this framework each GPIO controller is packaged as a "struct gpio_chip"
++with information common to each controller of that type:
++
++ - methods to establish GPIO direction
++ - methods used to access GPIO values
++ - flag saying whether calls to its methods may sleep
++ - optional debugfs dump method (showing extra state like pullup config)
++ - label for diagnostics
++
++There is also per-instance data, which may come from device.platform_data:
++the number of its first GPIO, and how many GPIOs it exposes.
++
++The code implementing a gpio_chip should support multiple instances of the
++controller, possibly using the driver model. That code will configure each
++gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be
++rare; use gpiochip_remove() when it is unavoidable.
++
++Most often a gpio_chip is part of an instance-specific structure with state
++not exposed by the GPIO interfaces, such as addressing, power management,
++and more. Chips such as codecs will have complex non-GPIO state,
++
++Any debugfs dump method should normally ignore signals which haven't been
++requested as GPIOs. They can use gpiochip_is_requested(), which returns
++either NULL or the label associated with that GPIO when it was requested.
++
++
++Platform Support
++----------------
++To support this framework, a platform's Kconfig will "select HAVE_GPIO_LIB"
++and arrange that its <asm/gpio.h> includes <asm-generic/gpio.h> and defines
++three functions: gpio_get_value(), gpio_set_value(), and gpio_cansleep().
++They may also want to provide a custom value for ARCH_NR_GPIOS.
++
++Trivial implementations of those functions can directly use framework
++code, which always dispatches through the gpio_chip:
++
++ #define gpio_get_value __gpio_get_value
++ #define gpio_set_value __gpio_set_value
++ #define gpio_cansleep __gpio_cansleep
++
++Fancier implementations could instead define those as inline functions with
++logic optimizing access to specific SOC-based GPIOs. For example, if the
++referenced GPIO is the constant "12", getting or setting its value could
++cost as little as two or three instructions, never sleeping. When such an
++optimization is not possible those calls must delegate to the framework
++code, costing at least a few dozen instructions. For bitbanged I/O, such
++instruction savings can be significant.
++
++For SOCs, platform-specific code defines and registers gpio_chip instances
++for each bank of on-chip GPIOs. Those GPIOs should be numbered/labeled to
++match chip vendor documentation, and directly match board schematics. They
++may well start at zero and go up to a platform-specific limit. Such GPIOs
++are normally integrated into platform initialization to make them always be
++available, from arch_initcall() or earlier; they can often serve as IRQs.
++
++
++Board Support
++-------------
++For external GPIO controllers -- such as I2C or SPI expanders, ASICs, multi
++function devices, FPGAs or CPLDs -- most often board-specific code handles
++registering controller devices and ensures that their drivers know what GPIO
++numbers to use with gpiochip_add(). Their numbers often start right after
++platform-specific GPIOs.
++
++For example, board setup code could create structures identifying the range
++of GPIOs that chip will expose, and passes them to each GPIO expander chip
++using platform_data. Then the chip driver's probe() routine could pass that
++data to gpiochip_add().
++
++Initialization order can be important. For example, when a device relies on
++an I2C-based GPIO, its probe() routine should only be called after that GPIO
++becomes available. That may mean the device should not be registered until
++calls for that GPIO can work. One way to address such dependencies is for
++such gpio_chip controllers to provide setup() and teardown() callbacks to
++board specific code; those board specific callbacks would register devices
++once all the necessary resources are available.
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch b/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch
new file mode 100644
index 0000000000..84d0fd3e19
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch
@@ -0,0 +1,434 @@
+From 39717c1328f6aa13330eded0e0e268993cfd1eea Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Tue, 12 Feb 2008 10:39:53 +0300
+Subject: [PATCH 25/64] Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+
+---
+ arch/arm/mach-pxa/Makefile | 2 +-
+ arch/arm/mach-pxa/devices.c | 401 +++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 402 insertions(+), 1 deletions(-)
+ create mode 100644 arch/arm/mach-pxa/devices.c
+
+diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
+index 5cb0216..f276d24 100644
+--- a/arch/arm/mach-pxa/Makefile
++++ b/arch/arm/mach-pxa/Makefile
+@@ -4,7 +4,7 @@
+
+ # Common support (must be linked before board specific support)
+ obj-y += clock.o generic.o irq.o dma.o \
+- time.o gpio.o
++ time.o gpio.o devices.o
+ obj-$(CONFIG_PXA25x) += pxa25x.o
+ obj-$(CONFIG_PXA27x) += pxa27x.o
+ obj-$(CONFIG_PXA3xx) += pxa3xx.o mfp.o
+diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
+new file mode 100644
+index 0000000..928131a
+--- /dev/null
++++ b/arch/arm/mach-pxa/devices.c
+@@ -0,0 +1,401 @@
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/platform_device.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/arch/gpio.h>
++#include <asm/arch/udc.h>
++#include <asm/arch/pxafb.h>
++#include <asm/arch/mmc.h>
++#include <asm/arch/irda.h>
++#include <asm/arch/i2c.h>
++#include <asm/arch/ohci.h>
++
++#include "devices.h"
++
++#ifdef CONFIG_PXA25x
++
++static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa25x_resource_ssp[] = {
++ [0] = {
++ .start = 0x41000000,
++ .end = 0x4100001f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SSP,
++ .end = IRQ_SSP,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 13,
++ .end = 13,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 14,
++ .end = 14,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa25x_device_ssp = {
++ .name = "pxa25x-ssp",
++ .id = 0,
++ .dev = {
++ .dma_mask = &pxa25x_ssp_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa25x_resource_ssp,
++ .num_resources = ARRAY_SIZE(pxa25x_resource_ssp),
++};
++
++static u64 pxa25x_nssp_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa25x_resource_nssp[] = {
++ [0] = {
++ .start = 0x41400000,
++ .end = 0x4140002f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_NSSP,
++ .end = IRQ_NSSP,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 15,
++ .end = 15,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 16,
++ .end = 16,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa25x_device_nssp = {
++ .name = "pxa25x-nssp",
++ .id = 1,
++ .dev = {
++ .dma_mask = &pxa25x_nssp_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa25x_resource_nssp,
++ .num_resources = ARRAY_SIZE(pxa25x_resource_nssp),
++};
++
++static u64 pxa25x_assp_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa25x_resource_assp[] = {
++ [0] = {
++ .start = 0x41500000,
++ .end = 0x4150002f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_ASSP,
++ .end = IRQ_ASSP,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 23,
++ .end = 23,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 24,
++ .end = 24,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa25x_device_assp = {
++ /* ASSP is basically equivalent to NSSP */
++ .name = "pxa25x-nssp",
++ .id = 2,
++ .dev = {
++ .dma_mask = &pxa25x_assp_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa25x_resource_assp,
++ .num_resources = ARRAY_SIZE(pxa25x_resource_assp),
++};
++#endif /* CONFIG_PXA25x */
++
++#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
++
++static u64 pxa27x_ohci_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa27x_resource_ohci[] = {
++ [0] = {
++ .start = 0x4C000000,
++ .end = 0x4C00ff6f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_USBH1,
++ .end = IRQ_USBH1,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++struct platform_device pxa27x_device_ohci = {
++ .name = "pxa27x-ohci",
++ .id = -1,
++ .dev = {
++ .dma_mask = &pxa27x_ohci_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .num_resources = ARRAY_SIZE(pxa27x_resource_ohci),
++ .resource = pxa27x_resource_ohci,
++};
++
++void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
++{
++ pxa_register_device(&pxa27x_device_ohci, info);
++}
++
++static u64 pxa27x_ssp1_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa27x_resource_ssp1[] = {
++ [0] = {
++ .start = 0x41000000,
++ .end = 0x4100003f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SSP,
++ .end = IRQ_SSP,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 13,
++ .end = 13,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 14,
++ .end = 14,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa27x_device_ssp1 = {
++ .name = "pxa27x-ssp",
++ .id = 0,
++ .dev = {
++ .dma_mask = &pxa27x_ssp1_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa27x_resource_ssp1,
++ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp1),
++};
++
++static u64 pxa27x_ssp2_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa27x_resource_ssp2[] = {
++ [0] = {
++ .start = 0x41700000,
++ .end = 0x4170003f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SSP2,
++ .end = IRQ_SSP2,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 15,
++ .end = 15,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 16,
++ .end = 16,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa27x_device_ssp2 = {
++ .name = "pxa27x-ssp",
++ .id = 1,
++ .dev = {
++ .dma_mask = &pxa27x_ssp2_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa27x_resource_ssp2,
++ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp2),
++};
++
++static u64 pxa27x_ssp3_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa27x_resource_ssp3[] = {
++ [0] = {
++ .start = 0x41900000,
++ .end = 0x4190003f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SSP3,
++ .end = IRQ_SSP3,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 66,
++ .end = 66,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 67,
++ .end = 67,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa27x_device_ssp3 = {
++ .name = "pxa27x-ssp",
++ .id = 2,
++ .dev = {
++ .dma_mask = &pxa27x_ssp3_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa27x_resource_ssp3,
++ .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3),
++};
++#endif /* CONFIG_PXA27x || CONFIG_PXA3xx */
++
++#ifdef CONFIG_PXA3xx
++static u64 pxa3xx_ssp4_dma_mask = DMA_BIT_MASK(32);
++
++static struct resource pxa3xx_resource_ssp4[] = {
++ [0] = {
++ .start = 0x41a00000,
++ .end = 0x41a0003f,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_SSP4,
++ .end = IRQ_SSP4,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ /* DRCMR for RX */
++ .start = 2,
++ .end = 2,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ /* DRCMR for TX */
++ .start = 3,
++ .end = 3,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa3xx_device_ssp4 = {
++ /* PXA3xx SSP is basically equivalent to PXA27x */
++ .name = "pxa27x-ssp",
++ .id = 3,
++ .dev = {
++ .dma_mask = &pxa3xx_ssp4_dma_mask,
++ .coherent_dma_mask = DMA_BIT_MASK(32),
++ },
++ .resource = pxa3xx_resource_ssp4,
++ .num_resources = ARRAY_SIZE(pxa3xx_resource_ssp4),
++};
++
++static struct resource pxa3xx_resources_mci2[] = {
++ [0] = {
++ .start = 0x42000000,
++ .end = 0x42000fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_MMC2,
++ .end = IRQ_MMC2,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = 93,
++ .end = 93,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ .start = 94,
++ .end = 94,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa3xx_device_mci2 = {
++ .name = "pxa2xx-mci",
++ .id = 1,
++ .dev = {
++ .dma_mask = &pxamci_dmamask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci2),
++ .resource = pxa3xx_resources_mci2,
++};
++
++void __init pxa3xx_set_mci2_info(struct pxamci_platform_data *info)
++{
++ pxa_register_device(&pxa3xx_device_mci2, info);
++}
++
++static struct resource pxa3xx_resources_mci3[] = {
++ [0] = {
++ .start = 0x42500000,
++ .end = 0x42500fff,
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = IRQ_MMC3,
++ .end = IRQ_MMC3,
++ .flags = IORESOURCE_IRQ,
++ },
++ [2] = {
++ .start = 100,
++ .end = 100,
++ .flags = IORESOURCE_DMA,
++ },
++ [3] = {
++ .start = 101,
++ .end = 101,
++ .flags = IORESOURCE_DMA,
++ },
++};
++
++struct platform_device pxa3xx_device_mci3 = {
++ .name = "pxa2xx-mci",
++ .id = 2,
++ .dev = {
++ .dma_mask = &pxamci_dmamask,
++ .coherent_dma_mask = 0xffffffff,
++ },
++ .num_resources = ARRAY_SIZE(pxa3xx_resources_mci3),
++ .resource = pxa3xx_resources_mci3,
++};
++
++void __init pxa3xx_set_mci3_info(struct pxamci_platform_data *info)
++{
++ pxa_register_device(&pxa3xx_device_mci3, info);
++}
++
++#endif /* CONFIG_PXA3xx */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch b/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch
new file mode 100644
index 0000000000..e1323e4edc
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch
@@ -0,0 +1,134 @@
+From cbe46408b666983284e8be290950d526dbc0f0a4 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:08:16 +0300
+Subject: [PATCH 26/64] I don't think we should check for IRQs when determining which one
+ of power supplies to register. Better use is_{ac,usb}_online
+ callbacks, this will not produce an obstacle to implement polling --
+ when irqs aren't mandatory. I'll send my two pending patches to show
+ the idea.
+
+For this particular issue, I think something like that should work.
+If it works for you, I'll commit that version, preserving your
+authorship, of course.
+---
+ drivers/power/pda_power.c | 80 ++++++++++++++++++++++++--------------------
+ 1 files changed, 44 insertions(+), 36 deletions(-)
+
+diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
+index c058f28..d98622f 100644
+--- a/drivers/power/pda_power.c
++++ b/drivers/power/pda_power.c
+@@ -168,66 +168,74 @@ static int pda_power_probe(struct platform_device *pdev)
+ pda_power_supplies[1].num_supplicants = pdata->num_supplicants;
+ }
+
+- ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
+- if (ret) {
+- dev_err(dev, "failed to register %s power supply\n",
+- pda_power_supplies[0].name);
+- goto supply0_failed;
+- }
++ if (pdata->is_ac_online) {
++ ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
++ if (ret) {
++ dev_err(dev, "failed to register %s power supply\n",
++ pda_power_supplies[0].name);
++ goto ac_supply_failed;
++ }
+
+- ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
+- if (ret) {
+- dev_err(dev, "failed to register %s power supply\n",
+- pda_power_supplies[1].name);
+- goto supply1_failed;
++ if (ac_irq) {
++ ret = request_irq(ac_irq->start, power_changed_isr,
++ get_irq_flags(ac_irq), ac_irq->name,
++ &pda_power_supplies[0]);
++ if (ret) {
++ dev_err(dev, "request ac irq failed\n");
++ goto ac_irq_failed;
++ }
++ }
+ }
+
+- if (ac_irq) {
+- ret = request_irq(ac_irq->start, power_changed_isr,
+- get_irq_flags(ac_irq), ac_irq->name,
+- &pda_power_supplies[0]);
++ if (pdata->is_usb_online) {
++ ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
+ if (ret) {
+- dev_err(dev, "request ac irq failed\n");
+- goto ac_irq_failed;
++ dev_err(dev, "failed to register %s power supply\n",
++ pda_power_supplies[1].name);
++ goto usb_supply_failed;
+ }
+- }
+
+- if (usb_irq) {
+- ret = request_irq(usb_irq->start, power_changed_isr,
+- get_irq_flags(usb_irq), usb_irq->name,
+- &pda_power_supplies[1]);
+- if (ret) {
+- dev_err(dev, "request usb irq failed\n");
+- goto usb_irq_failed;
++ if (usb_irq) {
++ ret = request_irq(usb_irq->start, power_changed_isr,
++ get_irq_flags(usb_irq),
++ usb_irq->name,
++ &pda_power_supplies[1]);
++ if (ret) {
++ dev_err(dev, "request usb irq failed\n");
++ goto usb_irq_failed;
++ }
+ }
+ }
+
+- goto success;
++ return 0;
+
+ usb_irq_failed:
+- if (ac_irq)
++ if (pdata->is_usb_online)
++ power_supply_unregister(&pda_power_supplies[1]);
++usb_supply_failed:
++ if (pdata->is_ac_online && ac_irq)
+ free_irq(ac_irq->start, &pda_power_supplies[0]);
+ ac_irq_failed:
+- power_supply_unregister(&pda_power_supplies[1]);
+-supply1_failed:
+- power_supply_unregister(&pda_power_supplies[0]);
+-supply0_failed:
++ if (pdata->is_ac_online)
++ power_supply_unregister(&pda_power_supplies[0]);
++ac_supply_failed:
+ noirqs:
+ wrongid:
+-success:
+ return ret;
+ }
+
+ static int pda_power_remove(struct platform_device *pdev)
+ {
+- if (usb_irq)
++ if (pdata->is_usb_online && usb_irq)
+ free_irq(usb_irq->start, &pda_power_supplies[1]);
+- if (ac_irq)
++ if (pdata->is_ac_online && ac_irq)
+ free_irq(ac_irq->start, &pda_power_supplies[0]);
+ del_timer_sync(&charger_timer);
+ del_timer_sync(&supply_timer);
+- power_supply_unregister(&pda_power_supplies[1]);
+- power_supply_unregister(&pda_power_supplies[0]);
++ if (pdata->is_usb_online)
++ power_supply_unregister(&pda_power_supplies[1]);
++ if (pdata->is_ac_online)
++ power_supply_unregister(&pda_power_supplies[0]);
+ return 0;
+ }
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch b/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch
new file mode 100644
index 0000000000..240d2d0bd9
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch
@@ -0,0 +1,59 @@
+From e5e9808fd5ed9cb54dd9da9fb91b32c4f7e9da52 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:08:17 +0300
+Subject: [PATCH 27/64] Add LiMn (one of the most common for small non-rechargable batteries)i
+ battery technology and voltage_min/_max properties support.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/power/power_supply_sysfs.c | 5 ++++-
+ include/linux/power_supply.h | 3 +++
+ 2 files changed, 7 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
+index 249f61b..45d2f95 100644
+--- a/drivers/power/power_supply_sysfs.c
++++ b/drivers/power/power_supply_sysfs.c
+@@ -46,7 +46,8 @@ static ssize_t power_supply_show_property(struct device *dev,
+ "Unspecified failure"
+ };
+ static char *technology_text[] = {
+- "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd"
++ "Unknown", "NiMH", "Li-ion", "Li-poly", "LiFe", "NiCd",
++ "LiMn"
+ };
+ static char *capacity_level_text[] = {
+ "Unknown", "Critical", "Low", "Normal", "High", "Full"
+@@ -88,6 +89,8 @@ static struct device_attribute power_supply_attrs[] = {
+ POWER_SUPPLY_ATTR(present),
+ POWER_SUPPLY_ATTR(online),
+ POWER_SUPPLY_ATTR(technology),
++ POWER_SUPPLY_ATTR(voltage_max),
++ POWER_SUPPLY_ATTR(voltage_min),
+ POWER_SUPPLY_ATTR(voltage_max_design),
+ POWER_SUPPLY_ATTR(voltage_min_design),
+ POWER_SUPPLY_ATTR(voltage_now),
+diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
+index 606c095..cdbc5b8 100644
+--- a/include/linux/power_supply.h
++++ b/include/linux/power_supply.h
+@@ -54,6 +54,7 @@ enum {
+ POWER_SUPPLY_TECHNOLOGY_LIPO,
+ POWER_SUPPLY_TECHNOLOGY_LiFe,
+ POWER_SUPPLY_TECHNOLOGY_NiCd,
++ POWER_SUPPLY_TECHNOLOGY_LiMn,
+ };
+
+ enum {
+@@ -72,6 +73,8 @@ enum power_supply_property {
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch b/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch
new file mode 100644
index 0000000000..ac5df97dff
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch
@@ -0,0 +1,72 @@
+From df0801d2cd6a7081700c79f437d1185cbe1960a7 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:08:18 +0300
+Subject: [PATCH 28/64] Add suspend/resume/wakeup support for pda_power.
+ Now with device_init_wakeup.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/power/pda_power.c | 34 ++++++++++++++++++++++++++++++++++
+ 1 files changed, 34 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
+index d98622f..28360e8 100644
+--- a/drivers/power/pda_power.c
++++ b/drivers/power/pda_power.c
+@@ -207,6 +207,8 @@ static int pda_power_probe(struct platform_device *pdev)
+ }
+ }
+
++ device_init_wakeup(&pdev->dev, 1);
++
+ return 0;
+
+ usb_irq_failed:
+@@ -239,12 +241,44 @@ static int pda_power_remove(struct platform_device *pdev)
+ return 0;
+ }
+
++#ifdef CONFIG_PM
++static int pda_power_suspend(struct platform_device *pdev, pm_message_t state)
++{
++ if (device_may_wakeup(&pdev->dev)) {
++ if (ac_irq)
++ enable_irq_wake(ac_irq->start);
++ if (usb_irq)
++ enable_irq_wake(usb_irq->start);
++ }
++
++ return 0;
++}
++
++static int pda_power_resume(struct platform_device *pdev)
++{
++ if (device_may_wakeup(&pdev->dev)) {
++ if (usb_irq)
++ disable_irq_wake(usb_irq->start);
++ if (ac_irq)
++ disable_irq_wake(ac_irq->start);
++ }
++
++ return 0;
++}
++#else
++#define pda_power_suspend NULL
++#define pda_power_resume NULL
++#endif
++
++
+ static struct platform_driver pda_power_pdrv = {
+ .driver = {
+ .name = "pda-power",
+ },
+ .probe = pda_power_probe,
+ .remove = pda_power_remove,
++ .suspend = pda_power_suspend,
++ .resume = pda_power_resume,
+ };
+
+ static int __init pda_power_init(void)
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch b/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch
new file mode 100644
index 0000000000..7347fd5a00
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch
@@ -0,0 +1,163 @@
+From 57d1450b4e5f27fa78c75895dc30213bde7191bc Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:08:18 +0300
+Subject: [PATCH 29/64] Support using VOLTAGE_* properties for apm calculations. It's pretty
+ dummy, but useful for batteries for which we can only get voltages.
+
+---
+ drivers/power/apm_power.c | 63 ++++++++++++++++++++++++++++++++++++--------
+ 1 files changed, 51 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
+index bbf3ee1..526c96e 100644
+--- a/drivers/power/apm_power.c
++++ b/drivers/power/apm_power.c
+@@ -13,6 +13,12 @@
+ #include <linux/power_supply.h>
+ #include <linux/apm-emulation.h>
+
++typedef enum {
++ SOURCE_ENERGY,
++ SOURCE_CHARGE,
++ SOURCE_VOLTAGE,
++} apm_source;
++
+ #define PSY_PROP(psy, prop, val) psy->get_property(psy, \
+ POWER_SUPPLY_PROP_##prop, val)
+
+@@ -87,7 +93,7 @@ static void find_main_battery(void)
+ }
+ }
+
+-static int calculate_time(int status, int using_charge)
++static int calculate_time(int status, apm_source source)
+ {
+ union power_supply_propval full;
+ union power_supply_propval empty;
+@@ -106,20 +112,34 @@ static int calculate_time(int status, int using_charge)
+ return -1;
+ }
+
+- if (using_charge) {
++ switch (source) {
++ case SOURCE_CHARGE:
+ full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+ full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+ empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+ cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+- } else {
++ break;
++ case SOURCE_ENERGY:
+ full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+ full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+ empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+ cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
++ break;
++ case SOURCE_VOLTAGE:
++ full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
++ full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
++ empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
++ empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
++ cur_avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
++ cur_now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
++ break;
++ default:
++ printk(KERN_ERR "Unsupported source: %d\n", source);
++ return -1;
+ }
+
+ if (_MPSY_PROP(full_prop, &full)) {
+@@ -146,7 +166,7 @@ static int calculate_time(int status, int using_charge)
+ return -((cur.intval - empty.intval) * 60L) / I.intval;
+ }
+
+-static int calculate_capacity(int using_charge)
++static int calculate_capacity(apm_source source)
+ {
+ enum power_supply_property full_prop, empty_prop;
+ enum power_supply_property full_design_prop, empty_design_prop;
+@@ -154,20 +174,33 @@ static int calculate_capacity(int using_charge)
+ union power_supply_propval empty, full, cur;
+ int ret;
+
+- if (using_charge) {
++ switch (source) {
++ case SOURCE_CHARGE:
+ full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+ empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN;
+ now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+ avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+- } else {
++ break;
++ case SOURCE_ENERGY:
+ full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+ empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+ full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+ empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN;
+ now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
+ avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
++ case SOURCE_VOLTAGE:
++ full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX;
++ empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN;
++ full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN;
++ empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN;
++ now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW;
++ avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG;
++ break;
++ default:
++ printk(KERN_ERR "Unsupported source: %d\n", source);
++ return -1;
+ }
+
+ if (_MPSY_PROP(full_prop, &full)) {
+@@ -234,10 +267,12 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info)
+ info->battery_life = capacity.intval;
+ } else {
+ /* try calculate using energy */
+- info->battery_life = calculate_capacity(0);
++ info->battery_life = calculate_capacity(SOURCE_ENERGY);
+ /* if failed try calculate using charge instead */
+ if (info->battery_life == -1)
+- info->battery_life = calculate_capacity(1);
++ info->battery_life = calculate_capacity(SOURCE_CHARGE);
++ if (info->battery_life == -1)
++ info->battery_life = calculate_capacity(SOURCE_VOLTAGE);
+ }
+
+ /* charging status */
+@@ -263,18 +298,22 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info)
+ !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) {
+ info->time = time_to_full.intval / 60;
+ } else {
+- info->time = calculate_time(status.intval, 0);
++ info->time = calculate_time(status.intval, SOURCE_ENERGY);
+ if (info->time == -1)
+- info->time = calculate_time(status.intval, 1);
++ info->time = calculate_time(status.intval, SOURCE_CHARGE);
++ if (info->time == -1)
++ info->time = calculate_time(status.intval, SOURCE_VOLTAGE);
+ }
+ } else {
+ if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) ||
+ !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) {
+ info->time = time_to_empty.intval / 60;
+ } else {
+- info->time = calculate_time(status.intval, 0);
++ info->time = calculate_time(status.intval, SOURCE_ENERGY);
++ if (info->time == -1)
++ info->time = calculate_time(status.intval, SOURCE_CHARGE);
+ if (info->time == -1)
+- info->time = calculate_time(status.intval, 1);
++ info->time = calculate_time(status.intval, SOURCE_VOLTAGE);
+ }
+ }
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch b/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch
new file mode 100644
index 0000000000..1c86a39c74
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0030-Core-driver-for-WM97xx-touchscreens.patch
@@ -0,0 +1,1083 @@
+From d3e044e0e10e6c6b75716cb927e92b4ec284132f Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:20 +0300
+Subject: [PATCH 30/64] Core driver for WM97xx touchscreens
+
+This patch series adds support for the touchscreen controllers provided
+by Wolfson Microelectronics WM97xx series chips in both polled and
+streaming modes.
+
+These drivers have been maintained out of tree since 2003. During that
+time the driver the primary maintainer was Liam Girdwood and a number of
+people have made contributions including Stanley Cai, Rodolfo Giometti,
+Russell King, Marc Kleine-Budde, Ian Molton, Vincent Sanders, Andrew
+Zabolotny, Graeme Gregory, Mike Arthur and myself. Apologies to anyone
+I have omitted.
+
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Cc: Stanley Cai <stanley.cai@intel.com>
+Cc: Rodolfo Giometti <giometti@enneenne.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Cc: Ian Molton <spyro@f2s.com>
+Cc: Vincent Sanders <vince@kyllikki.org>
+Cc: Andrew Zabolotny <zap@homelink.ru>
+---
+ drivers/input/touchscreen/wm97xx-core.c | 724 +++++++++++++++++++++++++++++++
+ include/linux/wm97xx.h | 309 +++++++++++++
+ 2 files changed, 1033 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/wm97xx-core.c
+ create mode 100644 include/linux/wm97xx.h
+
+diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
+new file mode 100644
+index 0000000..27a0a99
+--- /dev/null
++++ b/drivers/input/touchscreen/wm97xx-core.c
+@@ -0,0 +1,724 @@
++/*
++ * wm97xx-core.c -- Touch screen driver core for Wolfson WM9705, WM9712
++ * and WM9713 AC97 Codecs.
++ *
++ * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
++ * Parts Copyright : Ian Molton <spyro@f2s.com>
++ * Andrew Zabolotny <zap@homelink.ru>
++ * Russell King <rmk@arm.linux.org.uk>
++ *
++ * 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.
++ *
++ * Notes:
++ *
++ * Features:
++ * - supports WM9705, WM9712, WM9713
++ * - polling mode
++ * - continuous mode (arch-dependent)
++ * - adjustable rpu/dpp settings
++ * - adjustable pressure current
++ * - adjustable sample settle delay
++ * - 4 and 5 wire touchscreens (5 wire is WM9712 only)
++ * - pen down detection
++ * - battery monitor
++ * - sample AUX adcs
++ * - power management
++ * - codec GPIO
++ * - codec event notification
++ * Todo
++ * - Support for async sampling control for noisy LCDs.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/string.h>
++#include <linux/proc_fs.h>
++#include <linux/pm.h>
++#include <linux/interrupt.h>
++#include <linux/bitops.h>
++#include <linux/workqueue.h>
++#include <linux/wm97xx.h>
++#include <linux/uaccess.h>
++#include <linux/io.h>
++
++#define TS_NAME "wm97xx"
++#define WM_CORE_VERSION "0.65"
++#define DEFAULT_PRESSURE 0xb0c0
++
++
++/*
++ * Touchscreen absolute values
++ *
++ * These parameters are used to help the input layer discard out of
++ * range readings and reduce jitter etc.
++ *
++ * o min, max:- indicate the min and max values your touch screen returns
++ * o fuzz:- use a higher number to reduce jitter
++ *
++ * The default values correspond to Mainstone II in QVGA mode
++ *
++ * Please read
++ * Documentation/input/input-programming.txt for more details.
++ */
++
++static int abs_x[3] = {350, 3900, 5};
++module_param_array(abs_x, int, NULL, 0);
++MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");
++
++static int abs_y[3] = {320, 3750, 40};
++module_param_array(abs_y, int, NULL, 0);
++MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");
++
++static int abs_p[3] = {0, 150, 4};
++module_param_array(abs_p, int, NULL, 0);
++MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");
++
++/*
++ * wm97xx IO access, all IO locking done by AC97 layer
++ */
++int wm97xx_reg_read(struct wm97xx *wm, u16 reg)
++{
++ if (wm->ac97)
++ return wm->ac97->bus->ops->read(wm->ac97, reg);
++ else
++ return -1;
++}
++EXPORT_SYMBOL_GPL(wm97xx_reg_read);
++
++void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val)
++{
++ /* cache digitiser registers */
++ if (reg >= AC97_WM9713_DIG1 && reg <= AC97_WM9713_DIG3)
++ wm->dig[(reg - AC97_WM9713_DIG1) >> 1] = val;
++
++ /* cache gpio regs */
++ if (reg >= AC97_GPIO_CFG && reg <= AC97_MISC_AFE)
++ wm->gpio[(reg - AC97_GPIO_CFG) >> 1] = val;
++
++ /* wm9713 irq reg */
++ if (reg == 0x5a)
++ wm->misc = val;
++
++ if (wm->ac97)
++ wm->ac97->bus->ops->write(wm->ac97, reg, val);
++}
++EXPORT_SYMBOL_GPL(wm97xx_reg_write);
++
++/**
++ * wm97xx_read_aux_adc - Read the aux adc.
++ * @wm: wm97xx device.
++ * @adcsel: codec ADC to be read
++ *
++ * Reads the selected AUX ADC.
++ */
++
++int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel)
++{
++ int power_adc = 0, auxval;
++ u16 power = 0;
++
++ /* get codec */
++ mutex_lock(&wm->codec_mutex);
++
++ /* When the touchscreen is not in use, we may have to power up
++ * the AUX ADC before we can use sample the AUX inputs->
++ */
++ if (wm->id == WM9713_ID2 &&
++ (power = wm97xx_reg_read(wm, AC97_EXTENDED_MID)) & 0x8000) {
++ power_adc = 1;
++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power & 0x7fff);
++ }
++
++ /* Prepare the codec for AUX reading */
++ wm->codec->aux_prepare(wm);
++
++ /* Turn polling mode on to read AUX ADC */
++ wm->pen_probably_down = 1;
++ wm->codec->poll_sample(wm, adcsel, &auxval);
++
++ if (power_adc)
++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, power | 0x8000);
++
++ wm->codec->dig_restore(wm);
++
++ wm->pen_probably_down = 0;
++
++ mutex_unlock(&wm->codec_mutex);
++ return auxval & 0xfff;
++}
++EXPORT_SYMBOL_GPL(wm97xx_read_aux_adc);
++
++/**
++ * wm97xx_get_gpio - Get the status of a codec GPIO.
++ * @wm: wm97xx device.
++ * @gpio: gpio
++ *
++ * Get the status of a codec GPIO pin
++ */
++
++enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio)
++{
++ u16 status;
++ enum wm97xx_gpio_status ret;
++
++ mutex_lock(&wm->codec_mutex);
++ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
++
++ if (status & gpio)
++ ret = WM97XX_GPIO_HIGH;
++ else
++ ret = WM97XX_GPIO_LOW;
++
++ mutex_unlock(&wm->codec_mutex);
++ return ret;
++}
++EXPORT_SYMBOL_GPL(wm97xx_get_gpio);
++
++/**
++ * wm97xx_set_gpio - Set the status of a codec GPIO.
++ * @wm: wm97xx device.
++ * @gpio: gpio
++ *
++ *
++ * Set the status of a codec GPIO pin
++ */
++
++void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
++ enum wm97xx_gpio_status status)
++{
++ u16 reg;
++
++ mutex_lock(&wm->codec_mutex);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
++
++ if (status & WM97XX_GPIO_HIGH)
++ reg |= gpio;
++ else
++ reg &= ~gpio;
++
++ if (wm->id == WM9712_ID2)
++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg << 1);
++ else
++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, reg);
++ mutex_unlock(&wm->codec_mutex);
++}
++EXPORT_SYMBOL_GPL(wm97xx_set_gpio);
++
++/*
++ * Codec GPIO pin configuration, this sets pin direction, polarity,
++ * stickyness and wake up.
++ */
++void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, enum wm97xx_gpio_dir dir,
++ enum wm97xx_gpio_pol pol, enum wm97xx_gpio_sticky sticky,
++ enum wm97xx_gpio_wake wake)
++{
++ u16 reg;
++
++ mutex_lock(&wm->codec_mutex);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
++
++ if (pol == WM97XX_GPIO_POL_HIGH)
++ reg |= gpio;
++ else
++ reg &= ~gpio;
++
++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, reg);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
++
++ if (sticky == WM97XX_GPIO_STICKY)
++ reg |= gpio;
++ else
++ reg &= ~gpio;
++
++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, reg);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
++
++ if (wake == WM97XX_GPIO_WAKE)
++ reg |= gpio;
++ else
++ reg &= ~gpio;
++
++ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, reg);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
++
++ if (dir == WM97XX_GPIO_IN)
++ reg |= gpio;
++ else
++ reg &= ~gpio;
++
++ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg);
++ mutex_unlock(&wm->codec_mutex);
++}
++EXPORT_SYMBOL_GPL(wm97xx_config_gpio);
++
++/*
++ * Handle a pen down interrupt.
++ */
++static void wm97xx_pen_irq_worker(struct work_struct *work)
++{
++ struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work);
++
++ /* do we need to enable the touch panel reader */
++ if (wm->id == WM9705_ID2) {
++ if (wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD) &
++ WM97XX_PEN_DOWN)
++ wm->pen_is_down = 1;
++ else
++ wm->pen_is_down = 0;
++ } else {
++ u16 status, pol;
++ mutex_lock(&wm->codec_mutex);
++ status = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
++ pol = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
++
++ if (WM97XX_GPIO_13 & pol & status) {
++ wm->pen_is_down = 1;
++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol &
++ ~WM97XX_GPIO_13);
++ } else {
++ wm->pen_is_down = 0;
++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, pol |
++ WM97XX_GPIO_13);
++ }
++
++ if (wm->id == WM9712_ID2)
++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, (status &
++ ~WM97XX_GPIO_13) << 1);
++ else
++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, status &
++ ~WM97XX_GPIO_13);
++ mutex_unlock(&wm->codec_mutex);
++ }
++
++ queue_delayed_work(wm->ts_workq, &wm->ts_reader, 0);
++
++ if (!wm->pen_is_down && wm->mach_ops && wm->mach_ops->acc_enabled)
++ wm->mach_ops->acc_pen_up(wm);
++ wm->mach_ops->irq_enable(wm, 1);
++}
++
++/*
++ * Codec PENDOWN irq handler
++ *
++ * We have to disable the codec interrupt in the handler because it can
++ * take upto 1ms to clear the interrupt source. The interrupt is then enabled
++ * again in the slow handler when the source has been cleared.
++ */
++static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id)
++{
++ struct wm97xx *wm = dev_id;
++ wm->mach_ops->irq_enable(wm, 0);
++ queue_work(wm->ts_workq, &wm->pen_event_work);
++ return IRQ_HANDLED;
++}
++
++/*
++ * initialise pen IRQ handler and workqueue
++ */
++static int wm97xx_init_pen_irq(struct wm97xx *wm)
++{
++ u16 reg;
++
++ /* If an interrupt is supplied an IRQ enable operation must also be
++ * provided. */
++ BUG_ON(!wm->mach_ops->irq_enable);
++
++ INIT_WORK(&wm->pen_event_work, wm97xx_pen_irq_worker);
++
++ if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED,
++ "wm97xx-pen", wm)) {
++ dev_err(wm->dev,
++ "Failed to register pen down interrupt, polling");
++ wm->pen_irq = 0;
++ return -EINVAL;
++ }
++
++ /* enable PEN down on wm9712/13 */
++ if (wm->id != WM9705_ID2) {
++ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
++ wm97xx_reg_write(wm, AC97_MISC_AFE, reg & 0xfffb);
++ reg = wm97xx_reg_read(wm, 0x5a);
++ wm97xx_reg_write(wm, 0x5a, reg & ~0x0001);
++ }
++
++ return 0;
++}
++
++static int wm97xx_read_samples(struct wm97xx *wm)
++{
++ struct wm97xx_data data;
++ int rc;
++
++ mutex_lock(&wm->codec_mutex);
++
++ if (wm->mach_ops && wm->mach_ops->acc_enabled)
++ rc = wm->mach_ops->acc_pen_down(wm);
++ else
++ rc = wm->codec->poll_touch(wm, &data);
++
++ if (rc & RC_PENUP) {
++ if (wm->pen_is_down) {
++ wm->pen_is_down = 0;
++ dev_dbg(wm->dev, "pen up\n");
++ input_report_abs(wm->input_dev, ABS_PRESSURE, 0);
++ input_sync(wm->input_dev);
++ } else if (!(rc & RC_AGAIN)) {
++ /* We need high frequency updates only while
++ * pen is down, the user never will be able to
++ * touch screen faster than a few times per
++ * second... On the other hand, when the user
++ * is actively working with the touchscreen we
++ * don't want to lose the quick response. So we
++ * will slowly increase sleep time after the
++ * pen is up and quicky restore it to ~one task
++ * switch when pen is down again.
++ */
++ if (wm->ts_reader_interval < HZ / 10)
++ wm->ts_reader_interval++;
++ }
++
++ } else if (rc & RC_VALID) {
++ dev_dbg(wm->dev,
++ "pen down: x=%x:%d, y=%x:%d, pressure=%x:%d\n",
++ data.x >> 12, data.x & 0xfff, data.y >> 12,
++ data.y & 0xfff, data.p >> 12, data.p & 0xfff);
++ input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);
++ input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);
++ input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);
++ input_sync(wm->input_dev);
++ wm->pen_is_down = 1;
++ wm->ts_reader_interval = wm->ts_reader_min_interval;
++ } else if (rc & RC_PENDOWN) {
++ dev_dbg(wm->dev, "pen down");
++ wm->pen_is_down = 1;
++ wm->ts_reader_interval = wm->ts_reader_min_interval;
++ }
++
++ mutex_unlock(&wm->codec_mutex);
++ return rc;
++}
++
++/*
++* The touchscreen sample reader.
++*/
++static void wm97xx_ts_reader(struct work_struct *work)
++{
++ int rc;
++ struct wm97xx *wm = container_of(work, struct wm97xx, ts_reader.work);
++
++ BUG_ON(!wm->codec);
++
++ do {
++ rc = wm97xx_read_samples(wm);
++ } while (rc & RC_AGAIN);
++
++ if (wm->pen_is_down || !wm->pen_irq)
++ queue_delayed_work(wm->ts_workq, &wm->ts_reader,
++ wm->ts_reader_interval);
++}
++
++/**
++ * wm97xx_ts_input_open - Open the touch screen input device.
++ * @idev: Input device to be opened.
++ *
++ * Called by the input sub system to open a wm97xx touchscreen device.
++ * Starts the touchscreen thread and touch digitiser.
++ */
++static int wm97xx_ts_input_open(struct input_dev *idev)
++{
++ struct wm97xx *wm = input_get_drvdata(idev);
++
++ wm->ts_workq = create_singlethread_workqueue("kwm97xx");
++ if (wm->ts_workq == NULL) {
++ dev_err(wm->dev,
++ "Failed to create workqueue\n");
++ return -EINVAL;
++ }
++
++ /* start digitiser */
++ if (wm->mach_ops && wm->mach_ops->acc_enabled)
++ wm->codec->acc_enable(wm, 1);
++ wm->codec->dig_enable(wm, 1);
++
++ INIT_DELAYED_WORK(&wm->ts_reader, wm97xx_ts_reader);
++
++ wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1;
++ if (wm->ts_reader_min_interval < 1)
++ wm->ts_reader_min_interval = 1;
++ wm->ts_reader_interval = wm->ts_reader_min_interval;
++
++ wm->pen_is_down = 0;
++ if (wm->pen_irq)
++ wm97xx_init_pen_irq(wm);
++ else
++ dev_err(wm->dev, "No IRQ specified\n");
++
++ /* If we either don't have an interrupt for pen down events or
++ * failed to acquire it then we need to poll.
++ */
++ if (wm->pen_irq == 0)
++ queue_delayed_work(wm->ts_workq, &wm->ts_reader,
++ wm->ts_reader_interval);
++
++ return 0;
++}
++
++/**
++ * wm97xx_ts_input_close - Close the touch screen input device.
++ * @idev: Input device to be closed.
++ *
++ * Called by the input sub system to close a wm97xx touchscreen device.
++ * Kills the touchscreen thread and stops the touch digitiser.
++ */
++
++static void wm97xx_ts_input_close(struct input_dev *idev)
++{
++ struct wm97xx *wm = input_get_drvdata(idev);
++
++ if (wm->pen_irq)
++ free_irq(wm->pen_irq, wm);
++
++ wm->pen_is_down = 0;
++
++ /* ts_reader rearms itself so we need to explicitly stop it
++ * before we destroy the workqueue.
++ */
++ cancel_delayed_work_sync(&wm->ts_reader);
++ destroy_workqueue(wm->ts_workq);
++
++ /* stop digitiser */
++ wm->codec->dig_enable(wm, 0);
++ if (wm->mach_ops && wm->mach_ops->acc_enabled)
++ wm->codec->acc_enable(wm, 0);
++}
++
++static int wm97xx_probe(struct device *dev)
++{
++ struct wm97xx *wm;
++ int ret = 0, id = 0;
++
++ wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL);
++ if (!wm)
++ return -ENOMEM;
++ mutex_init(&wm->codec_mutex);
++
++ wm->dev = dev;
++ dev->driver_data = wm;
++ wm->ac97 = to_ac97_t(dev);
++
++ /* check that we have a supported codec */
++ id = wm97xx_reg_read(wm, AC97_VENDOR_ID1);
++ if (id != WM97XX_ID1) {
++ dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id);
++ kfree(wm);
++ return -ENODEV;
++ }
++
++ wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
++
++ dev_info(wm->dev, "detected a wm97%02x codec", wm->id & 0xff);
++
++ switch (wm->id & 0xff) {
++#ifdef CONFIG_TOUCHSCREEN_WM9705
++ case 0x05:
++ wm->codec = &wm9705_codec;
++ break;
++#endif
++#ifdef CONFIG_TOUCHSCREEN_WM9712
++ case 0x12:
++ wm->codec = &wm9712_codec;
++ break;
++#endif
++#ifdef CONFIG_TOUCHSCREEN_WM9713
++ case 0x13:
++ wm->codec = &wm9713_codec;
++ break;
++#endif
++ default:
++ dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
++ wm->id & 0xff);
++ kfree(wm);
++ return -ENODEV;
++ }
++
++ wm->input_dev = input_allocate_device();
++ if (wm->input_dev == NULL) {
++ kfree(wm);
++ return -ENOMEM;
++ }
++
++ /* set up touch configuration */
++ wm->input_dev->name = "wm97xx touchscreen";
++ wm->input_dev->open = wm97xx_ts_input_open;
++ wm->input_dev->close = wm97xx_ts_input_close;
++ set_bit(EV_ABS, wm->input_dev->evbit);
++ set_bit(ABS_X, wm->input_dev->absbit);
++ set_bit(ABS_Y, wm->input_dev->absbit);
++ set_bit(ABS_PRESSURE, wm->input_dev->absbit);
++ input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
++ abs_x[2], 0);
++ input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
++ abs_y[2], 0);
++ input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
++ abs_p[2], 0);
++ input_set_drvdata(wm->input_dev, wm);
++ wm->input_dev->dev.parent = dev;
++ ret = input_register_device(wm->input_dev);
++ if (ret < 0) {
++ input_free_device(wm->input_dev);
++ kfree(wm);
++ return -ENOMEM;
++ }
++
++ /* set up physical characteristics */
++ wm->codec->phy_init(wm);
++
++ /* load gpio cache */
++ wm->gpio[0] = wm97xx_reg_read(wm, AC97_GPIO_CFG);
++ wm->gpio[1] = wm97xx_reg_read(wm, AC97_GPIO_POLARITY);
++ wm->gpio[2] = wm97xx_reg_read(wm, AC97_GPIO_STICKY);
++ wm->gpio[3] = wm97xx_reg_read(wm, AC97_GPIO_WAKEUP);
++ wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
++ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
++
++ /* register our battery device */
++ wm->battery_dev = platform_device_alloc("wm97xx-battery", 0);
++ if (!wm->battery_dev)
++ goto batt_err;
++ platform_set_drvdata(wm->battery_dev, wm);
++ wm->battery_dev->dev.parent = dev;
++ ret = platform_device_register(wm->battery_dev);
++ if (ret < 0)
++ goto batt_reg_err;
++
++ /* register our extended touch device (for machine specific
++ * extensions) */
++ wm->touch_dev = platform_device_alloc("wm97xx-touch", 0);
++ if (!wm->touch_dev)
++ goto touch_err;
++ platform_set_drvdata(wm->touch_dev, wm);
++ wm->touch_dev->dev.parent = dev;
++ ret = platform_device_register(wm->touch_dev);
++ if (ret < 0)
++ goto touch_reg_err;
++
++ return ret;
++
++ touch_reg_err:
++ platform_device_put(wm->touch_dev);
++ touch_err:
++ platform_device_unregister(wm->battery_dev);
++ batt_reg_err:
++ platform_device_put(wm->battery_dev);
++ batt_err:
++ input_unregister_device(wm->input_dev);
++ kfree(wm);
++ return ret;
++}
++
++static int wm97xx_remove(struct device *dev)
++{
++ struct wm97xx *wm = dev_get_drvdata(dev);
++
++ platform_device_unregister(wm->battery_dev);
++ platform_device_unregister(wm->touch_dev);
++ input_unregister_device(wm->input_dev);
++
++ kfree(wm);
++ return 0;
++}
++
++#ifdef CONFIG_PM
++static int wm97xx_resume(struct device *dev)
++{
++ struct wm97xx *wm = dev_get_drvdata(dev);
++
++ /* restore digitiser and gpios */
++ if (wm->id == WM9713_ID2) {
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig[0]);
++ wm97xx_reg_write(wm, 0x5a, wm->misc);
++ if (wm->input_dev->users) {
++ u16 reg;
++ reg = wm97xx_reg_read(wm, AC97_EXTENDED_MID) & 0x7fff;
++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, reg);
++ }
++ }
++
++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig[1]);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2]);
++
++ wm97xx_reg_write(wm, AC97_GPIO_CFG, wm->gpio[0]);
++ wm97xx_reg_write(wm, AC97_GPIO_POLARITY, wm->gpio[1]);
++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, wm->gpio[2]);
++ wm97xx_reg_write(wm, AC97_GPIO_WAKEUP, wm->gpio[3]);
++ wm97xx_reg_write(wm, AC97_GPIO_STATUS, wm->gpio[4]);
++ wm97xx_reg_write(wm, AC97_MISC_AFE, wm->gpio[5]);
++
++ return 0;
++}
++
++#else
++#define wm97xx_resume NULL
++#endif
++
++/*
++ * Machine specific operations
++ */
++int wm97xx_register_mach_ops(struct wm97xx *wm,
++ struct wm97xx_mach_ops *mach_ops)
++{
++ mutex_lock(&wm->codec_mutex);
++ if (wm->mach_ops) {
++ mutex_unlock(&wm->codec_mutex);
++ return -EINVAL;
++ }
++ wm->mach_ops = mach_ops;
++ mutex_unlock(&wm->codec_mutex);
++ return 0;
++}
++EXPORT_SYMBOL_GPL(wm97xx_register_mach_ops);
++
++void wm97xx_unregister_mach_ops(struct wm97xx *wm)
++{
++ mutex_lock(&wm->codec_mutex);
++ wm->mach_ops = NULL;
++ mutex_unlock(&wm->codec_mutex);
++}
++EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
++
++static struct device_driver wm97xx_driver = {
++ .name = "ac97",
++ .bus = &ac97_bus_type,
++ .owner = THIS_MODULE,
++ .probe = wm97xx_probe,
++ .remove = wm97xx_remove,
++ .resume = wm97xx_resume,
++};
++
++static int __init wm97xx_init(void)
++{
++ return driver_register(&wm97xx_driver);
++}
++
++static void __exit wm97xx_exit(void)
++{
++ driver_unregister(&wm97xx_driver);
++}
++
++module_init(wm97xx_init);
++module_exit(wm97xx_exit);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
++MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
++MODULE_LICENSE("GPL");
+diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h
+new file mode 100644
+index 0000000..fc6e0b3
+--- /dev/null
++++ b/include/linux/wm97xx.h
+@@ -0,0 +1,309 @@
++
++/*
++ * Register bits and API for Wolfson WM97xx series of codecs
++ */
++
++#ifndef _LINUX_WM97XX_H
++#define _LINUX_WM97XX_H
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#include <sound/ac97_codec.h>
++#include <sound/initval.h>
++#include <linux/types.h>
++#include <linux/list.h>
++#include <linux/input.h> /* Input device layer */
++#include <linux/platform_device.h>
++
++/*
++ * WM97xx AC97 Touchscreen registers
++ */
++#define AC97_WM97XX_DIGITISER1 0x76
++#define AC97_WM97XX_DIGITISER2 0x78
++#define AC97_WM97XX_DIGITISER_RD 0x7a
++#define AC97_WM9713_DIG1 0x74
++#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1
++#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2
++
++/*
++ * WM97xx register bits
++ */
++#define WM97XX_POLL 0x8000 /* initiate a polling measurement */
++#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */
++#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */
++#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */
++#define WM97XX_ADCSEL_MASK 0x7000
++#define WM97XX_COO 0x0800 /* enable coordinate mode */
++#define WM97XX_CTC 0x0400 /* enable continuous mode */
++#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */
++#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */
++#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */
++#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */
++#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */
++#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */
++#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */
++#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */
++#define WM97XX_CM_RATE_MASK 0x03f0
++#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0))
++#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */
++#define WM97XX_DELAY_MASK 0x00f0
++#define WM97XX_SLEN 0x0008 /* slot read back enable */
++#define WM97XX_SLT(i) ((i - 5) & 0x7) /* panel slot (5-11) */
++#define WM97XX_SLT_MASK 0x0007
++#define WM97XX_PRP_DETW 0x4000 /* detect on, digitise off, wake */
++#define WM97XX_PRP_DET 0x8000 /* detect on, digitise off, no wake */
++#define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */
++#define WM97XX_RPR 0x2000 /* wake up on pen down */
++#define WM97XX_PEN_DOWN 0x8000 /* pen is down */
++#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */
++
++#define WM97XX_AUX_ID1 0x8001
++#define WM97XX_AUX_ID2 0x8002
++#define WM97XX_AUX_ID3 0x8003
++#define WM97XX_AUX_ID4 0x8004
++
++
++/* WM9712 Bits */
++#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */
++#define WM9712_PDEN 0x0800 /* measure only when pen down */
++#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */
++#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */
++#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */
++#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */
++#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */
++#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */
++#define WM9712_PD(i) (0x1 << i) /* power management */
++
++/* WM9712 Registers */
++#define AC97_WM9712_POWER 0x24
++#define AC97_WM9712_REV 0x58
++
++/* WM9705 Bits */
++#define WM9705_PDEN 0x1000 /* measure only when pen is down */
++#define WM9705_PINV 0x0800 /* inverts sense of pen down output */
++#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */
++#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */
++#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */
++#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */
++#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */
++#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */
++#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */
++#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */
++#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */
++
++
++/* WM9713 Bits */
++#define WM9713_PDPOL 0x0400 /* Pen down polarity */
++#define WM9713_POLL 0x0200 /* initiate a polling measurement */
++#define WM9713_CTC 0x0100 /* enable continuous mode */
++#define WM9713_ADCSEL_X 0x0002 /* X measurement */
++#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */
++#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */
++#define WM9713_COO 0x0001 /* enable coordinate mode */
++#define WM9713_PDEN 0x0800 /* measure only when pen down */
++#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */
++#define WM9713_WAIT 0x0200 /* coordinate wait */
++
++/* AUX ADC ID's */
++#define TS_COMP1 0x0
++#define TS_COMP2 0x1
++#define TS_BMON 0x2
++#define TS_WIPER 0x3
++
++/* ID numbers */
++#define WM97XX_ID1 0x574d
++#define WM9712_ID2 0x4c12
++#define WM9705_ID2 0x4c05
++#define WM9713_ID2 0x4c13
++
++/* Codec GPIO's */
++#define WM97XX_MAX_GPIO 16
++#define WM97XX_GPIO_1 (1 << 1)
++#define WM97XX_GPIO_2 (1 << 2)
++#define WM97XX_GPIO_3 (1 << 3)
++#define WM97XX_GPIO_4 (1 << 4)
++#define WM97XX_GPIO_5 (1 << 5)
++#define WM97XX_GPIO_6 (1 << 6)
++#define WM97XX_GPIO_7 (1 << 7)
++#define WM97XX_GPIO_8 (1 << 8)
++#define WM97XX_GPIO_9 (1 << 9)
++#define WM97XX_GPIO_10 (1 << 10)
++#define WM97XX_GPIO_11 (1 << 11)
++#define WM97XX_GPIO_12 (1 << 12)
++#define WM97XX_GPIO_13 (1 << 13)
++#define WM97XX_GPIO_14 (1 << 14)
++#define WM97XX_GPIO_15 (1 << 15)
++
++
++#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */
++
++
++/*---------------- Return codes from sample reading functions ---------------*/
++
++/* More data is available; call the sample gathering function again */
++#define RC_AGAIN 0x00000001
++/* The returned sample is valid */
++#define RC_VALID 0x00000002
++/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */
++#define RC_PENUP 0x00000004
++/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful
++ to tell the handler that the pen is down but we don't know yet his coords,
++ so the handler should not sleep or wait for pendown irq) */
++#define RC_PENDOWN 0x00000008
++
++/*
++ * The wm97xx driver provides a private API for writing platform-specific
++ * drivers.
++ */
++
++/* The structure used to return arch specific sampled data into */
++struct wm97xx_data {
++ int x;
++ int y;
++ int p;
++};
++
++/*
++ * Codec GPIO status
++ */
++enum wm97xx_gpio_status {
++ WM97XX_GPIO_HIGH,
++ WM97XX_GPIO_LOW
++};
++
++/*
++ * Codec GPIO direction
++ */
++enum wm97xx_gpio_dir {
++ WM97XX_GPIO_IN,
++ WM97XX_GPIO_OUT
++};
++
++/*
++ * Codec GPIO polarity
++ */
++enum wm97xx_gpio_pol {
++ WM97XX_GPIO_POL_HIGH,
++ WM97XX_GPIO_POL_LOW
++};
++
++/*
++ * Codec GPIO sticky
++ */
++enum wm97xx_gpio_sticky {
++ WM97XX_GPIO_STICKY,
++ WM97XX_GPIO_NOTSTICKY
++};
++
++/*
++ * Codec GPIO wake
++ */
++enum wm97xx_gpio_wake {
++ WM97XX_GPIO_WAKE,
++ WM97XX_GPIO_NOWAKE
++};
++
++/*
++ * Digitiser ioctl commands
++ */
++#define WM97XX_DIG_START 0x1
++#define WM97XX_DIG_STOP 0x2
++#define WM97XX_PHY_INIT 0x3
++#define WM97XX_AUX_PREPARE 0x4
++#define WM97XX_DIG_RESTORE 0x5
++
++struct wm97xx;
++
++extern struct wm97xx_codec_drv wm9705_codec;
++extern struct wm97xx_codec_drv wm9712_codec;
++extern struct wm97xx_codec_drv wm9713_codec;
++
++/*
++ * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs
++ */
++struct wm97xx_codec_drv {
++ u16 id;
++ char *name;
++
++ /* read 1 sample */
++ int (*poll_sample) (struct wm97xx *, int adcsel, int *sample);
++
++ /* read X,Y,[P] in poll */
++ int (*poll_touch) (struct wm97xx *, struct wm97xx_data *);
++
++ int (*acc_enable) (struct wm97xx *, int enable);
++ void (*phy_init) (struct wm97xx *);
++ void (*dig_enable) (struct wm97xx *, int enable);
++ void (*dig_restore) (struct wm97xx *);
++ void (*aux_prepare) (struct wm97xx *);
++};
++
++
++/* Machine specific and accelerated touch operations */
++struct wm97xx_mach_ops {
++
++ /* accelerated touch readback - coords are transmited on AC97 link */
++ int acc_enabled;
++ void (*acc_pen_up) (struct wm97xx *);
++ int (*acc_pen_down) (struct wm97xx *);
++ int (*acc_startup) (struct wm97xx *);
++ void (*acc_shutdown) (struct wm97xx *);
++
++ /* interrupt mask control - required for accelerated operation */
++ void (*irq_enable) (struct wm97xx *, int enable);
++
++ /* pre and post sample - can be used to minimise any analog noise */
++ void (*pre_sample) (int); /* function to run before sampling */
++ void (*post_sample) (int); /* function to run after sampling */
++};
++
++struct wm97xx {
++ u16 dig[3], id, gpio[6], misc; /* Cached codec registers */
++ u16 dig_save[3]; /* saved during aux reading */
++ struct wm97xx_codec_drv *codec; /* attached codec driver*/
++ struct input_dev *input_dev; /* touchscreen input device */
++ struct snd_ac97 *ac97; /* ALSA codec access */
++ struct device *dev; /* ALSA device */
++ struct platform_device *battery_dev;
++ struct platform_device *touch_dev;
++ struct wm97xx_mach_ops *mach_ops;
++ struct mutex codec_mutex;
++ struct delayed_work ts_reader; /* Used to poll touchscreen */
++ unsigned long ts_reader_interval; /* Current interval for timer */
++ unsigned long ts_reader_min_interval; /* Minimum interval */
++ unsigned int pen_irq; /* Pen IRQ number in use */
++ struct workqueue_struct *ts_workq;
++ struct work_struct pen_event_work;
++ u16 acc_slot; /* AC97 slot used for acc touch data */
++ u16 acc_rate; /* acc touch data rate */
++ unsigned pen_is_down:1; /* Pen is down */
++ unsigned aux_waiting:1; /* aux measurement waiting */
++ unsigned pen_probably_down:1; /* used in polling mode */
++};
++
++/*
++ * Codec GPIO access (not supported on WM9705)
++ * This can be used to set/get codec GPIO and Virtual GPIO status.
++ */
++enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio);
++void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio,
++ enum wm97xx_gpio_status status);
++void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio,
++ enum wm97xx_gpio_dir dir,
++ enum wm97xx_gpio_pol pol,
++ enum wm97xx_gpio_sticky sticky,
++ enum wm97xx_gpio_wake wake);
++
++/* codec AC97 IO access */
++int wm97xx_reg_read(struct wm97xx *wm, u16 reg);
++void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val);
++
++/* aux adc readback */
++int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel);
++
++/* machine ops */
++int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *);
++void wm97xx_unregister_mach_ops(struct wm97xx *);
++
++#endif
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch
new file mode 100644
index 0000000000..3890795f61
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch
@@ -0,0 +1,383 @@
+From 7b366ca784d0540613a43908de803e4dedc100d3 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:20 +0300
+Subject: [PATCH 31/64] Add chip driver for WM9705 touchscreen
+
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Cc: Stanley Cai <stanley.cai@intel.com>
+Cc: Rodolfo Giometti <giometti@enneenne.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Cc: Ian Molton <spyro@f2s.com>
+Cc: Vince Sanders <vince@kyllikki.org>
+Cc: Andrew Zabolotny <zap@homelink.ru>
+---
+ drivers/input/touchscreen/wm9705.c | 352 ++++++++++++++++++++++++++++++++++++
+ 1 files changed, 352 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/wm9705.c
+
+diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
+new file mode 100644
+index 0000000..f185104
+--- /dev/null
++++ b/drivers/input/touchscreen/wm9705.c
+@@ -0,0 +1,352 @@
++/*
++ * wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
++ *
++ * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
++ * Parts Copyright : Ian Molton <spyro@f2s.com>
++ * Andrew Zabolotny <zap@homelink.ru>
++ * Russell King <rmk@arm.linux.org.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++#include <linux/wm97xx.h>
++
++#define TS_NAME "wm97xx"
++#define WM9705_VERSION "0.62"
++#define DEFAULT_PRESSURE 0xb0c0
++
++/*
++ * Module parameters
++ */
++
++/*
++ * Set current used for pressure measurement.
++ *
++ * Set pil = 2 to use 400uA
++ * pil = 1 to use 200uA and
++ * pil = 0 to disable pressure measurement.
++ *
++ * This is used to increase the range of values returned by the adc
++ * when measureing touchpanel pressure.
++ */
++static int pil;
++module_param(pil, int, 0);
++MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
++
++/*
++ * Set threshold for pressure measurement.
++ *
++ * Pen down pressure below threshold is ignored.
++ */
++static int pressure = DEFAULT_PRESSURE & 0xfff;
++module_param(pressure, int, 0);
++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
++
++/*
++ * Set adc sample delay.
++ *
++ * For accurate touchpanel measurements, some settling time may be
++ * required between the switch matrix applying a voltage across the
++ * touchpanel plate and the ADC sampling the signal.
++ *
++ * This delay can be set by setting delay = n, where n is the array
++ * position of the delay in the array delay_table below.
++ * Long delays > 1ms are supported for completeness, but are not
++ * recommended.
++ */
++static int delay = 4;
++module_param(delay, int, 0);
++MODULE_PARM_DESC(delay, "Set adc sample delay.");
++
++/*
++ * Pen detect comparator threshold.
++ *
++ * 0 to Vmid in 15 steps, 0 = use zero power comparator with Vmid threshold
++ * i.e. 1 = Vmid/15 threshold
++ * 15 = Vmid/1 threshold
++ *
++ * Adjust this value if you are having problems with pen detect not
++ * detecting any down events.
++ */
++static int pdd = 8;
++module_param(pdd, int, 0);
++MODULE_PARM_DESC(pdd, "Set pen detect comparator threshold");
++
++/*
++ * Set adc mask function.
++ *
++ * Sources of glitch noise, such as signals driving an LCD display, may feed
++ * through to the touch screen plates and affect measurement accuracy. In
++ * order to minimise this, a signal may be applied to the MASK pin to delay or
++ * synchronise the sampling.
++ *
++ * 0 = No delay or sync
++ * 1 = High on pin stops conversions
++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
++ * 3 = Edge triggered, edge on pin starts conversion after delay param
++ */
++static int mask;
++module_param(mask, int, 0);
++MODULE_PARM_DESC(mask, "Set adc mask function.");
++
++/*
++ * ADC sample delay times in uS
++ */
++static const int delay_table[] = {
++ 21, /* 1 AC97 Link frames */
++ 42, /* 2 */
++ 84, /* 4 */
++ 167, /* 8 */
++ 333, /* 16 */
++ 667, /* 32 */
++ 1000, /* 48 */
++ 1333, /* 64 */
++ 2000, /* 96 */
++ 2667, /* 128 */
++ 3333, /* 160 */
++ 4000, /* 192 */
++ 4667, /* 224 */
++ 5333, /* 256 */
++ 6000, /* 288 */
++ 0 /* No delay, switch matrix always on */
++};
++
++/*
++ * Delay after issuing a POLL command.
++ *
++ * The delay is 3 AC97 link frames + the touchpanel settling delay
++ */
++static inline void poll_delay(int d)
++{
++ udelay(3 * AC97_LINK_FRAME + delay_table[d]);
++}
++
++/*
++ * set up the physical settings of the WM9705
++ */
++static void wm9705_phy_init(struct wm97xx *wm)
++{
++ u16 dig1 = 0, dig2 = WM97XX_RPR;
++
++ /*
++ * mute VIDEO and AUX as they share X and Y touchscreen
++ * inputs on the WM9705
++ */
++ wm97xx_reg_write(wm, AC97_AUX, 0x8000);
++ wm97xx_reg_write(wm, AC97_VIDEO, 0x8000);
++
++ /* touchpanel pressure current*/
++ if (pil == 2) {
++ dig2 |= WM9705_PIL;
++ dev_dbg(wm->dev,
++ "setting pressure measurement current to 400uA.");
++ } else if (pil)
++ dev_dbg(wm->dev,
++ "setting pressure measurement current to 200uA.");
++ if (!pil)
++ pressure = 0;
++
++ /* polling mode sample settling delay */
++ if (delay != 4) {
++ if (delay < 0 || delay > 15) {
++ dev_dbg(wm->dev, "supplied delay out of range.");
++ delay = 4;
++ }
++ }
++ dig1 &= 0xff0f;
++ dig1 |= WM97XX_DELAY(delay);
++ dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.",
++ delay_table[delay]);
++
++ /* WM9705 pdd */
++ dig2 |= (pdd & 0x000f);
++ dev_dbg(wm->dev, "setting pdd to Vmid/%d", 1 - (pdd & 0x000f));
++
++ /* mask */
++ dig2 |= ((mask & 0x3) << 4);
++
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
++}
++
++static void wm9705_dig_enable(struct wm97xx *wm, int enable)
++{
++ if (enable) {
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
++ wm->dig[2] | WM97XX_PRP_DET_DIG);
++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
++ } else
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
++ wm->dig[2] & ~WM97XX_PRP_DET_DIG);
++}
++
++static void wm9705_aux_prepare(struct wm97xx *wm)
++{
++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
++}
++
++static void wm9705_dig_restore(struct wm97xx *wm)
++{
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
++}
++
++static inline int is_pden(struct wm97xx *wm)
++{
++ return wm->dig[2] & WM9705_PDEN;
++}
++
++/*
++ * Read a sample from the WM9705 adc in polling mode.
++ */
++static int wm9705_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
++{
++ int timeout = 5 * delay;
++
++ if (!wm->pen_probably_down) {
++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (!(data & WM97XX_PEN_DOWN))
++ return RC_PENUP;
++ wm->pen_probably_down = 1;
++ }
++
++ /* set up digitiser */
++ if (adcsel & 0x8000)
++ adcsel = ((adcsel & 0x7fff) + 3) << 12;
++
++ if (wm->mach_ops && wm->mach_ops->pre_sample)
++ wm->mach_ops->pre_sample(adcsel);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
++ adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
++
++ /* wait 3 AC97 time slots + delay for conversion */
++ poll_delay(delay);
++
++ /* wait for POLL to go low */
++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
++ && timeout) {
++ udelay(AC97_LINK_FRAME);
++ timeout--;
++ }
++
++ if (timeout <= 0) {
++ /* If PDEN is set, we can get a timeout when pen goes up */
++ if (is_pden(wm))
++ wm->pen_probably_down = 0;
++ else
++ dev_dbg(wm->dev, "adc sample timeout");
++ return RC_PENUP;
++ }
++
++ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (wm->mach_ops && wm->mach_ops->post_sample)
++ wm->mach_ops->post_sample(adcsel);
++
++ /* check we have correct sample */
++ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
++ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
++ *sample & WM97XX_ADCSEL_MASK);
++ return RC_PENUP;
++ }
++
++ if (!(*sample & WM97XX_PEN_DOWN)) {
++ wm->pen_probably_down = 0;
++ return RC_PENUP;
++ }
++
++ return RC_VALID;
++}
++
++/*
++ * Sample the WM9705 touchscreen in polling mode
++ */
++static int wm9705_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
++{
++ int rc;
++
++ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_X, &data->x);
++ if (rc != RC_VALID)
++ return rc;
++ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y);
++ if (rc != RC_VALID)
++ return rc;
++ if (pil) {
++ rc = wm9705_poll_sample(wm, WM97XX_ADCSEL_PRES, &data->p);
++ if (rc != RC_VALID)
++ return rc;
++ } else
++ data->p = DEFAULT_PRESSURE;
++
++ return RC_VALID;
++}
++
++/*
++ * Enable WM9705 continuous mode, i.e. touch data is streamed across
++ * an AC97 slot
++ */
++static int wm9705_acc_enable(struct wm97xx *wm, int enable)
++{
++ u16 dig1, dig2;
++ int ret = 0;
++
++ dig1 = wm->dig[1];
++ dig2 = wm->dig[2];
++
++ if (enable) {
++ /* continous mode */
++ if (wm->mach_ops->acc_startup &&
++ (ret = wm->mach_ops->acc_startup(wm)) < 0)
++ return ret;
++ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
++ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
++ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
++ WM97XX_DELAY(delay) |
++ WM97XX_SLT(wm->acc_slot) |
++ WM97XX_RATE(wm->acc_rate);
++ if (pil)
++ dig1 |= WM97XX_ADCSEL_PRES;
++ dig2 |= WM9705_PDEN;
++ } else {
++ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
++ dig2 &= ~WM9705_PDEN;
++ if (wm->mach_ops->acc_shutdown)
++ wm->mach_ops->acc_shutdown(wm);
++ }
++
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
++ return ret;
++}
++
++struct wm97xx_codec_drv wm9705_codec = {
++ .id = WM9705_ID2,
++ .name = "wm9705",
++ .poll_sample = wm9705_poll_sample,
++ .poll_touch = wm9705_poll_touch,
++ .acc_enable = wm9705_acc_enable,
++ .phy_init = wm9705_phy_init,
++ .dig_enable = wm9705_dig_enable,
++ .dig_restore = wm9705_dig_restore,
++ .aux_prepare = wm9705_aux_prepare,
++};
++EXPORT_SYMBOL_GPL(wm9705_codec);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
++MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
++MODULE_LICENSE("GPL");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch
new file mode 100644
index 0000000000..6265910a1e
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch
@@ -0,0 +1,492 @@
+From b2640063b8321bdfb324c00d5f0c3366ac31696b Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:19 +0300
+Subject: [PATCH 32/64] Add chip driver for WM9712 touchscreen
+
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Cc: Stanley Cai <stanley.cai@intel.com>
+Cc: Rodolfo Giometti <giometti@enneenne.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Cc: Ian Molton <spyro@f2s.com>
+Cc: Vince Sanders <vince@kyllikki.org>
+Cc: Andrew Zabolotny <zap@homelink.ru>
+---
+ drivers/input/touchscreen/wm9712.c | 461 ++++++++++++++++++++++++++++++++++++
+ 1 files changed, 461 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/wm9712.c
+
+diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
+new file mode 100644
+index 0000000..eaab326
+--- /dev/null
++++ b/drivers/input/touchscreen/wm9712.c
+@@ -0,0 +1,461 @@
++/*
++ * wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
++ *
++ * Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
++ * Parts Copyright : Ian Molton <spyro@f2s.com>
++ * Andrew Zabolotny <zap@homelink.ru>
++ * Russell King <rmk@arm.linux.org.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++#include <linux/wm97xx.h>
++
++#define TS_NAME "wm97xx"
++#define WM9712_VERSION "0.61"
++#define DEFAULT_PRESSURE 0xb0c0
++
++/*
++ * Module parameters
++ */
++
++/*
++ * Set internal pull up for pen detect.
++ *
++ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
++ * i.e. pull up resistance = 64k Ohms / rpu.
++ *
++ * Adjust this value if you are having problems with pen detect not
++ * detecting any down event.
++ */
++static int rpu = 8;
++module_param(rpu, int, 0);
++MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
++
++/*
++ * Set current used for pressure measurement.
++ *
++ * Set pil = 2 to use 400uA
++ * pil = 1 to use 200uA and
++ * pil = 0 to disable pressure measurement.
++ *
++ * This is used to increase the range of values returned by the adc
++ * when measureing touchpanel pressure.
++ */
++static int pil;
++module_param(pil, int, 0);
++MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
++
++/*
++ * Set threshold for pressure measurement.
++ *
++ * Pen down pressure below threshold is ignored.
++ */
++static int pressure = DEFAULT_PRESSURE & 0xfff;
++module_param(pressure, int, 0);
++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
++
++/*
++ * Set adc sample delay.
++ *
++ * For accurate touchpanel measurements, some settling time may be
++ * required between the switch matrix applying a voltage across the
++ * touchpanel plate and the ADC sampling the signal.
++ *
++ * This delay can be set by setting delay = n, where n is the array
++ * position of the delay in the array delay_table below.
++ * Long delays > 1ms are supported for completeness, but are not
++ * recommended.
++ */
++static int delay = 3;
++module_param(delay, int, 0);
++MODULE_PARM_DESC(delay, "Set adc sample delay.");
++
++/*
++ * Set five_wire = 1 to use a 5 wire touchscreen.
++ *
++ * NOTE: Five wire mode does not allow for readback of pressure.
++ */
++static int five_wire;
++module_param(five_wire, int, 0);
++MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
++
++/*
++ * Set adc mask function.
++ *
++ * Sources of glitch noise, such as signals driving an LCD display, may feed
++ * through to the touch screen plates and affect measurement accuracy. In
++ * order to minimise this, a signal may be applied to the MASK pin to delay or
++ * synchronise the sampling.
++ *
++ * 0 = No delay or sync
++ * 1 = High on pin stops conversions
++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
++ * 3 = Edge triggered, edge on pin starts conversion after delay param
++ */
++static int mask;
++module_param(mask, int, 0);
++MODULE_PARM_DESC(mask, "Set adc mask function.");
++
++/*
++ * Coordinate Polling Enable.
++ *
++ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
++ * for every poll.
++ */
++static int coord;
++module_param(coord, int, 0);
++MODULE_PARM_DESC(coord, "Polling coordinate mode");
++
++/*
++ * ADC sample delay times in uS
++ */
++static const int delay_table[] = {
++ 21, /* 1 AC97 Link frames */
++ 42, /* 2 */
++ 84, /* 4 */
++ 167, /* 8 */
++ 333, /* 16 */
++ 667, /* 32 */
++ 1000, /* 48 */
++ 1333, /* 64 */
++ 2000, /* 96 */
++ 2667, /* 128 */
++ 3333, /* 160 */
++ 4000, /* 192 */
++ 4667, /* 224 */
++ 5333, /* 256 */
++ 6000, /* 288 */
++ 0 /* No delay, switch matrix always on */
++};
++
++/*
++ * Delay after issuing a POLL command.
++ *
++ * The delay is 3 AC97 link frames + the touchpanel settling delay
++ */
++static inline void poll_delay(int d)
++{
++ udelay(3 * AC97_LINK_FRAME + delay_table[d]);
++}
++
++/*
++ * set up the physical settings of the WM9712
++ */
++static void wm9712_phy_init(struct wm97xx *wm)
++{
++ u16 dig1 = 0;
++ u16 dig2 = WM97XX_RPR | WM9712_RPU(1);
++
++ /* WM9712 rpu */
++ if (rpu) {
++ dig2 &= 0xffc0;
++ dig2 |= WM9712_RPU(rpu);
++ dev_dbg(wm->dev, "setting pen detect pull-up to %d Ohms",
++ 64000 / rpu);
++ }
++
++ /* touchpanel pressure current*/
++ if (pil == 2) {
++ dig2 |= WM9712_PIL;
++ dev_dbg(wm->dev,
++ "setting pressure measurement current to 400uA.");
++ } else if (pil)
++ dev_dbg(wm->dev,
++ "setting pressure measurement current to 200uA.");
++ if (!pil)
++ pressure = 0;
++
++ /* WM9712 five wire */
++ if (five_wire) {
++ dig2 |= WM9712_45W;
++ dev_dbg(wm->dev, "setting 5-wire touchscreen mode.");
++ }
++
++ /* polling mode sample settling delay */
++ if (delay < 0 || delay > 15) {
++ dev_dbg(wm->dev, "supplied delay out of range.");
++ delay = 4;
++ }
++ dig1 &= 0xff0f;
++ dig1 |= WM97XX_DELAY(delay);
++ dev_dbg(wm->dev, "setting adc sample delay to %d u Secs.",
++ delay_table[delay]);
++
++ /* mask */
++ dig2 |= ((mask & 0x3) << 6);
++ if (mask) {
++ u16 reg;
++ /* Set GPIO4 as Mask Pin*/
++ reg = wm97xx_reg_read(wm, AC97_MISC_AFE);
++ wm97xx_reg_write(wm, AC97_MISC_AFE, reg | WM97XX_GPIO_4);
++ reg = wm97xx_reg_read(wm, AC97_GPIO_CFG);
++ wm97xx_reg_write(wm, AC97_GPIO_CFG, reg | WM97XX_GPIO_4);
++ }
++
++ /* wait - coord mode */
++ if (coord)
++ dig2 |= WM9712_WAIT;
++
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
++}
++
++static void wm9712_dig_enable(struct wm97xx *wm, int enable)
++{
++ u16 dig2 = wm->dig[2];
++
++ if (enable) {
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
++ dig2 | WM97XX_PRP_DET_DIG);
++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
++ } else
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2,
++ dig2 & ~WM97XX_PRP_DET_DIG);
++}
++
++static void wm9712_aux_prepare(struct wm97xx *wm)
++{
++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, 0);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, WM97XX_PRP_DET_DIG);
++}
++
++static void wm9712_dig_restore(struct wm97xx *wm)
++{
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, wm->dig_save[1]);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, wm->dig_save[2]);
++}
++
++static inline int is_pden(struct wm97xx *wm)
++{
++ return wm->dig[2] & WM9712_PDEN;
++}
++
++/*
++ * Read a sample from the WM9712 adc in polling mode.
++ */
++static int wm9712_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
++{
++ int timeout = 5 * delay;
++
++ if (!wm->pen_probably_down) {
++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (!(data & WM97XX_PEN_DOWN))
++ return RC_PENUP;
++ wm->pen_probably_down = 1;
++ }
++
++ /* set up digitiser */
++ if (adcsel & 0x8000)
++ adcsel = ((adcsel & 0x7fff) + 3) << 12;
++
++ if (wm->mach_ops && wm->mach_ops->pre_sample)
++ wm->mach_ops->pre_sample(adcsel);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
++ adcsel | WM97XX_POLL | WM97XX_DELAY(delay));
++
++ /* wait 3 AC97 time slots + delay for conversion */
++ poll_delay(delay);
++
++ /* wait for POLL to go low */
++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
++ && timeout) {
++ udelay(AC97_LINK_FRAME);
++ timeout--;
++ }
++
++ if (timeout <= 0) {
++ /* If PDEN is set, we can get a timeout when pen goes up */
++ if (is_pden(wm))
++ wm->pen_probably_down = 0;
++ else
++ dev_dbg(wm->dev, "adc sample timeout");
++ return RC_PENUP;
++ }
++
++ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (wm->mach_ops && wm->mach_ops->post_sample)
++ wm->mach_ops->post_sample(adcsel);
++
++ /* check we have correct sample */
++ if ((*sample & WM97XX_ADCSEL_MASK) != adcsel) {
++ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
++ *sample & WM97XX_ADCSEL_MASK);
++ return RC_PENUP;
++ }
++
++ if (!(*sample & WM97XX_PEN_DOWN)) {
++ wm->pen_probably_down = 0;
++ return RC_PENUP;
++ }
++
++ return RC_VALID;
++}
++
++/*
++ * Read a coord from the WM9712 adc in polling mode.
++ */
++static int wm9712_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
++{
++ int timeout = 5 * delay;
++
++ if (!wm->pen_probably_down) {
++ u16 data_rd = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (!(data_rd & WM97XX_PEN_DOWN))
++ return RC_PENUP;
++ wm->pen_probably_down = 1;
++ }
++
++ /* set up digitiser */
++ if (wm->mach_ops && wm->mach_ops->pre_sample)
++ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
++
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1,
++ WM97XX_COO | WM97XX_POLL | WM97XX_DELAY(delay));
++
++ /* wait 3 AC97 time slots + delay for conversion and read x */
++ poll_delay(delay);
++ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ /* wait for POLL to go low */
++ while ((wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER1) & WM97XX_POLL)
++ && timeout) {
++ udelay(AC97_LINK_FRAME);
++ timeout--;
++ }
++
++ if (timeout <= 0) {
++ /* If PDEN is set, we can get a timeout when pen goes up */
++ if (is_pden(wm))
++ wm->pen_probably_down = 0;
++ else
++ dev_dbg(wm->dev, "adc sample timeout");
++ return RC_PENUP;
++ }
++
++ /* read back y data */
++ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (pil)
++ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ else
++ data->p = DEFAULT_PRESSURE;
++
++ if (wm->mach_ops && wm->mach_ops->post_sample)
++ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
++
++ /* check we have correct sample */
++ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
++ goto err;
++ if (pil && !(data->p & WM97XX_ADCSEL_PRES))
++ goto err;
++
++ if (!(data->x & WM97XX_PEN_DOWN)) {
++ wm->pen_probably_down = 0;
++ return RC_PENUP;
++ }
++ return RC_VALID;
++err:
++ return RC_PENUP;
++}
++
++/*
++ * Sample the WM9712 touchscreen in polling mode
++ */
++static int wm9712_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
++{
++ int rc;
++
++ if (coord) {
++ rc = wm9712_poll_coord(wm, data);
++ if (rc != RC_VALID)
++ return rc;
++ } else {
++ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_X, &data->x);
++ if (rc != RC_VALID)
++ return rc;
++
++ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_Y, &data->y);
++ if (rc != RC_VALID)
++ return rc;
++
++ if (pil && !five_wire) {
++ rc = wm9712_poll_sample(wm, WM97XX_ADCSEL_PRES,
++ &data->p);
++ if (rc != RC_VALID)
++ return rc;
++ } else
++ data->p = DEFAULT_PRESSURE;
++ }
++ return RC_VALID;
++}
++
++/*
++ * Enable WM9712 continuous mode, i.e. touch data is streamed across
++ * an AC97 slot
++ */
++static int wm9712_acc_enable(struct wm97xx *wm, int enable)
++{
++ u16 dig1, dig2;
++ int ret = 0;
++
++ dig1 = wm->dig[1];
++ dig2 = wm->dig[2];
++
++ if (enable) {
++ /* continous mode */
++ if (wm->mach_ops->acc_startup) {
++ ret = wm->mach_ops->acc_startup(wm);
++ if (ret < 0)
++ return ret;
++ }
++ dig1 &= ~(WM97XX_CM_RATE_MASK | WM97XX_ADCSEL_MASK |
++ WM97XX_DELAY_MASK | WM97XX_SLT_MASK);
++ dig1 |= WM97XX_CTC | WM97XX_COO | WM97XX_SLEN |
++ WM97XX_DELAY(delay) |
++ WM97XX_SLT(wm->acc_slot) |
++ WM97XX_RATE(wm->acc_rate);
++ if (pil)
++ dig1 |= WM97XX_ADCSEL_PRES;
++ dig2 |= WM9712_PDEN;
++ } else {
++ dig1 &= ~(WM97XX_CTC | WM97XX_COO | WM97XX_SLEN);
++ dig2 &= ~WM9712_PDEN;
++ if (wm->mach_ops->acc_shutdown)
++ wm->mach_ops->acc_shutdown(wm);
++ }
++
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER1, dig1);
++ wm97xx_reg_write(wm, AC97_WM97XX_DIGITISER2, dig2);
++ return 0;
++}
++
++struct wm97xx_codec_drv wm9712_codec = {
++ .id = WM9712_ID2,
++ .name = "wm9712",
++ .poll_sample = wm9712_poll_sample,
++ .poll_touch = wm9712_poll_touch,
++ .acc_enable = wm9712_acc_enable,
++ .phy_init = wm9712_phy_init,
++ .dig_enable = wm9712_dig_enable,
++ .dig_restore = wm9712_dig_restore,
++ .aux_prepare = wm9712_aux_prepare,
++};
++EXPORT_SYMBOL_GPL(wm9712_codec);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
++MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
++MODULE_LICENSE("GPL");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch b/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch
new file mode 100644
index 0000000000..a9dfa18557
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch
@@ -0,0 +1,490 @@
+From 05b2a361eedb5461e902c73ebc6e30f9916b3a8a Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:19 +0300
+Subject: [PATCH 33/64] Add chip driver for WM9713 touchscreen
+
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Cc: Stanley Cai <stanley.cai@intel.com>
+Cc: Rodolfo Giometti <giometti@enneenne.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Cc: Ian Molton <spyro@f2s.com>
+Cc: Vince Sanders <vince@kyllikki.org>
+Cc: Andrew Zabolotny <zap@homelink.ru>
+---
+ drivers/input/touchscreen/wm9713.c | 459 ++++++++++++++++++++++++++++++++++++
+ 1 files changed, 459 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/wm9713.c
+
+diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
+new file mode 100644
+index 0000000..5067e59
+--- /dev/null
++++ b/drivers/input/touchscreen/wm9713.c
+@@ -0,0 +1,459 @@
++/*
++ * wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
++ *
++ * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
++ * Parts Copyright : Ian Molton <spyro@f2s.com>
++ * Andrew Zabolotny <zap@homelink.ru>
++ * Russell King <rmk@arm.linux.org.uk>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/input.h>
++#include <linux/delay.h>
++#include <linux/bitops.h>
++#include <linux/wm97xx.h>
++
++#define TS_NAME "wm97xx"
++#define WM9713_VERSION "0.53"
++#define DEFAULT_PRESSURE 0xb0c0
++
++/*
++ * Module parameters
++ */
++
++/*
++ * Set internal pull up for pen detect.
++ *
++ * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
++ * i.e. pull up resistance = 64k Ohms / rpu.
++ *
++ * Adjust this value if you are having problems with pen detect not
++ * detecting any down event.
++ */
++static int rpu = 8;
++module_param(rpu, int, 0);
++MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
++
++/*
++ * Set current used for pressure measurement.
++ *
++ * Set pil = 2 to use 400uA
++ * pil = 1 to use 200uA and
++ * pil = 0 to disable pressure measurement.
++ *
++ * This is used to increase the range of values returned by the adc
++ * when measureing touchpanel pressure.
++ */
++static int pil;
++module_param(pil, int, 0);
++MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
++
++/*
++ * Set threshold for pressure measurement.
++ *
++ * Pen down pressure below threshold is ignored.
++ */
++static int pressure = DEFAULT_PRESSURE & 0xfff;
++module_param(pressure, int, 0);
++MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
++
++/*
++ * Set adc sample delay.
++ *
++ * For accurate touchpanel measurements, some settling time may be
++ * required between the switch matrix applying a voltage across the
++ * touchpanel plate and the ADC sampling the signal.
++ *
++ * This delay can be set by setting delay = n, where n is the array
++ * position of the delay in the array delay_table below.
++ * Long delays > 1ms are supported for completeness, but are not
++ * recommended.
++ */
++static int delay = 4;
++module_param(delay, int, 0);
++MODULE_PARM_DESC(delay, "Set adc sample delay.");
++
++/*
++ * Set adc mask function.
++ *
++ * Sources of glitch noise, such as signals driving an LCD display, may feed
++ * through to the touch screen plates and affect measurement accuracy. In
++ * order to minimise this, a signal may be applied to the MASK pin to delay or
++ * synchronise the sampling.
++ *
++ * 0 = No delay or sync
++ * 1 = High on pin stops conversions
++ * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
++ * 3 = Edge triggered, edge on pin starts conversion after delay param
++ */
++static int mask;
++module_param(mask, int, 0);
++MODULE_PARM_DESC(mask, "Set adc mask function.");
++
++/*
++ * Coordinate Polling Enable.
++ *
++ * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
++ * for every poll.
++ */
++static int coord;
++module_param(coord, int, 0);
++MODULE_PARM_DESC(coord, "Polling coordinate mode");
++
++/*
++ * ADC sample delay times in uS
++ */
++static const int delay_table[] = {
++ 21, /* 1 AC97 Link frames */
++ 42, /* 2 */
++ 84, /* 4 */
++ 167, /* 8 */
++ 333, /* 16 */
++ 667, /* 32 */
++ 1000, /* 48 */
++ 1333, /* 64 */
++ 2000, /* 96 */
++ 2667, /* 128 */
++ 3333, /* 160 */
++ 4000, /* 192 */
++ 4667, /* 224 */
++ 5333, /* 256 */
++ 6000, /* 288 */
++ 0 /* No delay, switch matrix always on */
++};
++
++/*
++ * Delay after issuing a POLL command.
++ *
++ * The delay is 3 AC97 link frames + the touchpanel settling delay
++ */
++static inline void poll_delay(int d)
++{
++ udelay(3 * AC97_LINK_FRAME + delay_table[d]);
++}
++
++/*
++ * set up the physical settings of the WM9713
++ */
++static void wm9713_phy_init(struct wm97xx *wm)
++{
++ u16 dig1 = 0, dig2, dig3;
++
++ /* default values */
++ dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
++ dig3 = WM9712_RPU(1);
++
++ /* rpu */
++ if (rpu) {
++ dig3 &= 0xffc0;
++ dig3 |= WM9712_RPU(rpu);
++ dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n",
++ 64000 / rpu);
++ }
++
++ /* touchpanel pressure */
++ if (pil == 2) {
++ dig3 |= WM9712_PIL;
++ dev_info(wm->dev,
++ "setting pressure measurement current to 400uA.");
++ } else if (pil)
++ dev_info(wm->dev,
++ "setting pressure measurement current to 200uA.");
++ if (!pil)
++ pressure = 0;
++
++ /* sample settling delay */
++ if (delay < 0 || delay > 15) {
++ dev_info(wm->dev, "supplied delay out of range.");
++ delay = 4;
++ dev_info(wm->dev, "setting adc sample delay to %d u Secs.",
++ delay_table[delay]);
++ }
++ dig2 &= 0xff0f;
++ dig2 |= WM97XX_DELAY(delay);
++
++ /* mask */
++ dig3 |= ((mask & 0x3) << 4);
++ if (coord)
++ dig3 |= WM9713_WAIT;
++
++ wm->misc = wm97xx_reg_read(wm, 0x5a);
++
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
++ wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
++}
++
++static void wm9713_dig_enable(struct wm97xx *wm, int enable)
++{
++ u16 val;
++
++ if (enable) {
++ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] |
++ WM97XX_PRP_DET_DIG);
++ wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
++ } else {
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] &
++ ~WM97XX_PRP_DET_DIG);
++ val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
++ wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
++ }
++}
++
++static void wm9713_dig_restore(struct wm97xx *wm)
++{
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
++}
++
++static void wm9713_aux_prepare(struct wm97xx *wm)
++{
++ memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
++}
++
++static inline int is_pden(struct wm97xx *wm)
++{
++ return wm->dig[2] & WM9713_PDEN;
++}
++
++/*
++ * Read a sample from the WM9713 adc in polling mode.
++ */
++static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
++{
++ u16 dig1;
++ int timeout = 5 * delay;
++
++ if (!wm->pen_probably_down) {
++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (!(data & WM97XX_PEN_DOWN))
++ return RC_PENUP;
++ wm->pen_probably_down = 1;
++ }
++
++ /* set up digitiser */
++ if (adcsel & 0x8000)
++ adcsel = 1 << ((adcsel & 0x7fff) + 3);
++
++ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
++ dig1 &= ~WM9713_ADCSEL_MASK;
++
++ if (wm->mach_ops && wm->mach_ops->pre_sample)
++ wm->mach_ops->pre_sample(adcsel);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | adcsel | WM9713_POLL);
++
++ /* wait 3 AC97 time slots + delay for conversion */
++ poll_delay(delay);
++
++ /* wait for POLL to go low */
++ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) &&
++ timeout) {
++ udelay(AC97_LINK_FRAME);
++ timeout--;
++ }
++
++ if (timeout <= 0) {
++ /* If PDEN is set, we can get a timeout when pen goes up */
++ if (is_pden(wm))
++ wm->pen_probably_down = 0;
++ else
++ dev_dbg(wm->dev, "adc sample timeout");
++ return RC_PENUP;
++ }
++
++ *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (wm->mach_ops && wm->mach_ops->post_sample)
++ wm->mach_ops->post_sample(adcsel);
++
++ /* check we have correct sample */
++ if ((*sample & WM97XX_ADCSRC_MASK) != ffs(adcsel >> 1) << 12) {
++ dev_dbg(wm->dev, "adc wrong sample, read %x got %x", adcsel,
++ *sample & WM97XX_ADCSRC_MASK);
++ return RC_PENUP;
++ }
++
++ if (!(*sample & WM97XX_PEN_DOWN)) {
++ wm->pen_probably_down = 0;
++ return RC_PENUP;
++ }
++
++ return RC_VALID;
++}
++
++/*
++ * Read a coordinate from the WM9713 adc in polling mode.
++ */
++static int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
++{
++ u16 dig1;
++ int timeout = 5 * delay;
++
++ if (!wm->pen_probably_down) {
++ u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (!(data & WM97XX_PEN_DOWN))
++ return RC_PENUP;
++ wm->pen_probably_down = 1;
++ }
++
++ /* set up digitiser */
++ dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
++ dig1 &= ~WM9713_ADCSEL_MASK;
++ if (pil)
++ dig1 |= WM97XX_ADCSEL_PRES;
++
++ if (wm->mach_ops && wm->mach_ops->pre_sample)
++ wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1,
++ dig1 | WM9713_POLL | WM9713_COO);
++
++ /* wait 3 AC97 time slots + delay for conversion */
++ poll_delay(delay);
++ data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ /* wait for POLL to go low */
++ while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL)
++ && timeout) {
++ udelay(AC97_LINK_FRAME);
++ timeout--;
++ }
++
++ if (timeout <= 0) {
++ /* If PDEN is set, we can get a timeout when pen goes up */
++ if (is_pden(wm))
++ wm->pen_probably_down = 0;
++ else
++ dev_dbg(wm->dev, "adc sample timeout");
++ return RC_PENUP;
++ }
++
++ /* read back data */
++ data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ if (pil)
++ data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
++ else
++ data->p = DEFAULT_PRESSURE;
++
++ if (wm->mach_ops && wm->mach_ops->post_sample)
++ wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
++
++ /* check we have correct sample */
++ if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
++ goto err;
++ if (pil && !(data->p & WM97XX_ADCSEL_PRES))
++ goto err;
++
++ if (!(data->x & WM97XX_PEN_DOWN)) {
++ wm->pen_probably_down = 0;
++ return RC_PENUP;
++ }
++ return RC_VALID;
++err:
++ return RC_PENUP;
++}
++
++/*
++ * Sample the WM9713 touchscreen in polling mode
++ */
++static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
++{
++ int rc;
++
++ if (coord) {
++ rc = wm9713_poll_coord(wm, data);
++ if (rc != RC_VALID)
++ return rc;
++ } else {
++ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_X, &data->x);
++ if (rc != RC_VALID)
++ return rc;
++ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_Y, &data->y);
++ if (rc != RC_VALID)
++ return rc;
++ if (pil) {
++ rc = wm9713_poll_sample(wm, WM9713_ADCSEL_PRES,
++ &data->p);
++ if (rc != RC_VALID)
++ return rc;
++ } else
++ data->p = DEFAULT_PRESSURE;
++ }
++ return RC_VALID;
++}
++
++/*
++ * Enable WM9713 continuous mode, i.e. touch data is streamed across
++ * an AC97 slot
++ */
++static int wm9713_acc_enable(struct wm97xx *wm, int enable)
++{
++ u16 dig1, dig2, dig3;
++ int ret = 0;
++
++ dig1 = wm->dig[0];
++ dig2 = wm->dig[1];
++ dig3 = wm->dig[2];
++
++ if (enable) {
++ /* continous mode */
++ if (wm->mach_ops->acc_startup &&
++ (ret = wm->mach_ops->acc_startup(wm)) < 0)
++ return ret;
++
++ dig1 &= ~WM9713_ADCSEL_MASK;
++ dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X |
++ WM9713_ADCSEL_Y;
++ if (pil)
++ dig1 |= WM9713_ADCSEL_PRES;
++ dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK |
++ WM97XX_CM_RATE_MASK);
++ dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) |
++ WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate);
++ dig3 |= WM9713_PDEN;
++ } else {
++ dig1 &= ~(WM9713_CTC | WM9713_COO);
++ dig2 &= ~WM97XX_SLEN;
++ dig3 &= ~WM9713_PDEN;
++ if (wm->mach_ops->acc_shutdown)
++ wm->mach_ops->acc_shutdown(wm);
++ }
++
++ wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
++ wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
++ return ret;
++}
++
++struct wm97xx_codec_drv wm9713_codec = {
++ .id = WM9713_ID2,
++ .name = "wm9713",
++ .poll_sample = wm9713_poll_sample,
++ .poll_touch = wm9713_poll_touch,
++ .acc_enable = wm9713_acc_enable,
++ .phy_init = wm9713_phy_init,
++ .dig_enable = wm9713_dig_enable,
++ .dig_restore = wm9713_dig_restore,
++ .aux_prepare = wm9713_aux_prepare,
++};
++EXPORT_SYMBOL_GPL(wm9713_codec);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
++MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
++MODULE_LICENSE("GPL");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch b/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch
new file mode 100644
index 0000000000..0391cfcd83
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch
@@ -0,0 +1,329 @@
+From 821604bad5ce1ef942eeb420afd9ea2c5c92875e Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:19 +0300
+Subject: [PATCH 34/64] Driver for WM97xx touchscreens in streaming mode on Mainstone
+
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+Signed-off-by: Graeme Gregory <gg@opensource.wolfsonmicro.com>
+Signed-off-by: Mike Arthur <mike.arthur@wolfsonmicro.com>
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Cc: Stanley Cai <stanley.cai@intel.com>
+Cc: Rodolfo Giometti <giometti@enneenne.com>
+Cc: Russell King <rmk@arm.linux.org.uk>
+Cc: Marc Kleine-Budde <mkl@pengutronix.de>
+Cc: Ian Molton <spyro@f2s.com>
+Cc: Vince Sanders <vince@kyllikki.org>
+Cc: Andrew Zabolotny <zap@homelink.ru>
+---
+ drivers/input/touchscreen/mainstone-wm97xx.c | 298 ++++++++++++++++++++++++++
+ 1 files changed, 298 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/mainstone-wm97xx.c
+
+diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
+new file mode 100644
+index 0000000..8e1c35d
+--- /dev/null
++++ b/drivers/input/touchscreen/mainstone-wm97xx.c
+@@ -0,0 +1,298 @@
++/*
++ * mainstone-wm97xx.c -- Mainstone Continuous Touch screen driver for
++ * Wolfson WM97xx AC97 Codecs.
++ *
++ * Copyright 2004, 2007 Wolfson Microelectronics PLC.
++ * Author: Liam Girdwood
++ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
++ * Parts Copyright : Ian Molton <spyro@f2s.com>
++ * Andrew Zabolotny <zap@homelink.ru>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * Notes:
++ * This is a wm97xx extended touch driver to capture touch
++ * data in a continuous manner on the Intel XScale archictecture
++ *
++ * Features:
++ * - codecs supported:- WM9705, WM9712, WM9713
++ * - processors supported:- Intel XScale PXA25x, PXA26x, PXA27x
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/version.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/wm97xx.h>
++#include <linux/io.h>
++#include <asm/arch/pxa-regs.h>
++
++#define VERSION "0.13"
++
++struct continuous {
++ u16 id; /* codec id */
++ u8 code; /* continuous code */
++ u8 reads; /* number of coord reads per read cycle */
++ u32 speed; /* number of coords per second */
++};
++
++#define WM_READS(sp) ((sp / HZ) + 1)
++
++static const struct continuous cinfo[] = {
++ {WM9705_ID2, 0, WM_READS(94), 94},
++ {WM9705_ID2, 1, WM_READS(188), 188},
++ {WM9705_ID2, 2, WM_READS(375), 375},
++ {WM9705_ID2, 3, WM_READS(750), 750},
++ {WM9712_ID2, 0, WM_READS(94), 94},
++ {WM9712_ID2, 1, WM_READS(188), 188},
++ {WM9712_ID2, 2, WM_READS(375), 375},
++ {WM9712_ID2, 3, WM_READS(750), 750},
++ {WM9713_ID2, 0, WM_READS(94), 94},
++ {WM9713_ID2, 1, WM_READS(120), 120},
++ {WM9713_ID2, 2, WM_READS(154), 154},
++ {WM9713_ID2, 3, WM_READS(188), 188},
++};
++
++/* continuous speed index */
++static int sp_idx;
++static u16 last, tries;
++
++/*
++ * Pen sampling frequency (Hz) in continuous mode.
++ */
++static int cont_rate = 200;
++module_param(cont_rate, int, 0);
++MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)");
++
++/*
++ * Pen down detection.
++ *
++ * This driver can either poll or use an interrupt to indicate a pen down
++ * event. If the irq request fails then it will fall back to polling mode.
++ */
++static int pen_int;
++module_param(pen_int, int, 0);
++MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)");
++
++/*
++ * Pressure readback.
++ *
++ * Set to 1 to read back pen down pressure
++ */
++static int pressure;
++module_param(pressure, int, 0);
++MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)");
++
++/*
++ * AC97 touch data slot.
++ *
++ * Touch screen readback data ac97 slot
++ */
++static int ac97_touch_slot = 5;
++module_param(ac97_touch_slot, int, 0);
++MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number");
++
++
++/* flush AC97 slot 5 FIFO on pxa machines */
++#ifdef CONFIG_PXA27x
++static void wm97xx_acc_pen_up(struct wm97xx *wm)
++{
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(1);
++
++ while (MISR & (1 << 2))
++ MODR;
++}
++#else
++static void wm97xx_acc_pen_up(struct wm97xx *wm)
++{
++ int count = 16;
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(1);
++
++ while (count < 16) {
++ MODR;
++ count--;
++ }
++}
++#endif
++
++static int wm97xx_acc_pen_down(struct wm97xx *wm)
++{
++ u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES;
++ int reads = 0;
++
++ /* data is never immediately available after pen down irq */
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(1);
++
++ if (tries > 5) {
++ tries = 0;
++ return RC_PENUP;
++ }
++
++ x = MODR;
++ if (x == last) {
++ tries++;
++ return RC_AGAIN;
++ }
++ last = x;
++ do {
++ if (reads)
++ x = MODR;
++ y = MODR;
++ if (pressure)
++ p = MODR;
++
++ /* are samples valid */
++ if ((x & 0x7000) != WM97XX_ADCSEL_X ||
++ (y & 0x7000) != WM97XX_ADCSEL_Y ||
++ (p & 0x7000) != WM97XX_ADCSEL_PRES)
++ goto up;
++
++ /* coordinate is good */
++ tries = 0;
++ input_report_abs(wm->input_dev, ABS_X, x & 0xfff);
++ input_report_abs(wm->input_dev, ABS_Y, y & 0xfff);
++ input_report_abs(wm->input_dev, ABS_PRESSURE, p & 0xfff);
++ input_sync(wm->input_dev);
++ reads++;
++ } while (reads < cinfo[sp_idx].reads);
++up:
++ return RC_PENDOWN | RC_AGAIN;
++}
++
++static int wm97xx_acc_startup(struct wm97xx *wm)
++{
++ int idx = 0;
++
++ /* check we have a codec */
++ if (wm->ac97 == NULL)
++ return -ENODEV;
++
++ /* Go you big red fire engine */
++ for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) {
++ if (wm->id != cinfo[idx].id)
++ continue;
++ sp_idx = idx;
++ if (cont_rate <= cinfo[idx].speed)
++ break;
++ }
++ wm->acc_rate = cinfo[sp_idx].code;
++ wm->acc_slot = ac97_touch_slot;
++ dev_info(wm->dev,
++ "mainstone accelerated touchscreen driver, %d samples/sec\n",
++ cinfo[sp_idx].speed);
++
++ /* codec specific irq config */
++ if (pen_int) {
++ switch (wm->id) {
++ case WM9705_ID2:
++ wm->pen_irq = IRQ_GPIO(4);
++ set_irq_type(IRQ_GPIO(4), IRQT_BOTHEDGE);
++ break;
++ case WM9712_ID2:
++ case WM9713_ID2:
++ /* enable pen down interrupt */
++ /* use PEN_DOWN GPIO 13 to assert IRQ on GPIO line 2 */
++ wm->pen_irq = MAINSTONE_AC97_IRQ;
++ wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
++ WM97XX_GPIO_POL_HIGH,
++ WM97XX_GPIO_STICKY,
++ WM97XX_GPIO_WAKE);
++ wm97xx_config_gpio(wm, WM97XX_GPIO_2, WM97XX_GPIO_OUT,
++ WM97XX_GPIO_POL_HIGH,
++ WM97XX_GPIO_NOTSTICKY,
++ WM97XX_GPIO_NOWAKE);
++ break;
++ default:
++ dev_err(wm->dev,
++ "pen down irq not supported on this device\n");
++ pen_int = 0;
++ break;
++ }
++ }
++
++ return 0;
++}
++
++static void wm97xx_acc_shutdown(struct wm97xx *wm)
++{
++ /* codec specific deconfig */
++ if (pen_int) {
++ switch (wm->id & 0xffff) {
++ case WM9705_ID2:
++ wm->pen_irq = 0;
++ break;
++ case WM9712_ID2:
++ case WM9713_ID2:
++ /* disable interrupt */
++ wm->pen_irq = 0;
++ break;
++ }
++ }
++}
++
++static void wm97xx_irq_enable(struct wm97xx *wm, int enable)
++{
++ if (enable)
++ enable_irq(wm->pen_irq);
++ else
++ disable_irq(wm->pen_irq);
++}
++
++static struct wm97xx_mach_ops mainstone_mach_ops = {
++ .acc_enabled = 1,
++ .acc_pen_up = wm97xx_acc_pen_up,
++ .acc_pen_down = wm97xx_acc_pen_down,
++ .acc_startup = wm97xx_acc_startup,
++ .acc_shutdown = wm97xx_acc_shutdown,
++ .irq_enable = wm97xx_irq_enable,
++};
++
++static int mainstone_wm97xx_probe(struct platform_device *pdev)
++{
++ struct wm97xx *wm = platform_get_drvdata(pdev);
++ return wm97xx_register_mach_ops(wm, &mainstone_mach_ops);
++}
++
++static int mainstone_wm97xx_remove(struct platform_device *pdev)
++{
++ struct wm97xx *wm = platform_get_drvdata(pdev);
++ wm97xx_unregister_mach_ops(wm);
++ return 0;
++}
++
++static struct platform_driver mainstone_wm97xx_driver = {
++ .probe = mainstone_wm97xx_probe,
++ .remove = mainstone_wm97xx_remove,
++ .driver = {
++ .name = "wm97xx-touch",
++ },
++};
++
++static int __init mainstone_wm97xx_init(void)
++{
++ return platform_driver_register(&mainstone_wm97xx_driver);
++}
++
++static void __exit mainstone_wm97xx_exit(void)
++{
++ platform_driver_unregister(&mainstone_wm97xx_driver);
++}
++
++module_init(mainstone_wm97xx_init);
++module_exit(mainstone_wm97xx_exit);
++
++/* Module information */
++MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
++MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
++MODULE_LICENSE("GPL");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch b/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch
new file mode 100644
index 0000000000..aa0918f43e
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch
@@ -0,0 +1,122 @@
+From eba6a504393932764a33aae64021827dd2c5c70c Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sat, 26 Jan 2008 21:14:18 +0300
+Subject: [PATCH 35/64] Build system and MAINTAINERS entry for WM97xx touchscreen drivers
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+---
+ MAINTAINERS | 10 +++++++
+ drivers/input/touchscreen/Kconfig | 52 ++++++++++++++++++++++++++++++++++++
+ drivers/input/touchscreen/Makefile | 7 +++++
+ 3 files changed, 69 insertions(+), 0 deletions(-)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 2340cfb..f02851c 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -4204,6 +4204,16 @@ L: linux-wireless@vger.kernel.org
+ W: http://oops.ghostprotocols.net:81/blog
+ S: Maintained
+
++WM97XX TOUCHSCREEN DRIVERS
++P: Mark Brown
++M: broonie@opensource.wolfsonmicro.com
++P: Liam Girdwood
++M: liam.girdwood@wolfsonmicro.com
++L: linux-input@vger.kernel.org
++T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
++W: http://opensource.wolfsonmicro.com/node/7
++S: Supported
++
+ X.25 NETWORK LAYER
+ P: Henner Eisen
+ M: eis@baty.hanse.de
+diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
+index 90e8e92..0be05a2 100644
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -158,6 +158,58 @@ config TOUCHSCREEN_TOUCHRIGHT
+ To compile this driver as a module, choose M here: the
+ module will be called touchright.
+
++config TOUCHSCREEN_WM97XX
++ tristate "Support for WM97xx AC97 touchscreen controllers"
++ depends on AC97_BUS
++
++config TOUCHSCREEN_WM9705
++ bool "WM9705 Touchscreen interface support"
++ depends on TOUCHSCREEN_WM97XX
++ help
++ Say Y here if you have a Wolfson Microelectronics WM9705 touchscreen
++ controller connected to your system.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called wm9705.
++
++config TOUCHSCREEN_WM9712
++ bool "WM9712 Touchscreen interface support"
++ depends on TOUCHSCREEN_WM97XX
++ help
++ Say Y here if you have a Wolfson Microelectronics WM9712 touchscreen
++ controller connected to your system.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called wm9712.
++
++config TOUCHSCREEN_WM9713
++ bool "WM9713 Touchscreen interface support"
++ depends on TOUCHSCREEN_WM97XX
++ help
++ Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen
++ controller connected to your system.
++
++ If unsure, say N.
++
++ To compile this driver as a module, choose M here: the
++ module will be called wm9713.
++
++config TOUCHSCREEN_WM97XX_MAINSTONE
++ tristate "WM97xx Mainstone accelerated touch"
++ depends on TOUCHSCREEN_WM97XX && ARCH_PXA
++ help
++ Say Y here for support for streaming mode with WM97xx touchscreens
++ on Mainstone systems.
++
++ If unsure, say N
++
++ To compile this driver as a module, choose M here: the
++ module will be called mainstone-wm97xx
++
+ config TOUCHSCREEN_TOUCHWIN
+ tristate "Touchwin serial touchscreen"
+ select SERIO
+diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
+index 35d4097..d38156e 100644
+--- a/drivers/input/touchscreen/Makefile
++++ b/drivers/input/touchscreen/Makefile
+@@ -4,6 +4,8 @@
+
+ # Each configuration option enables a list of files.
+
++wm97xx-ts-y := wm97xx-core.o
++
+ obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
+ obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o
+@@ -19,3 +21,8 @@ obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o
+ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
+ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_TSC2101) += tsc2101_ts.o
++obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
++obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
++wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
++wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
++wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch b/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch
new file mode 100644
index 0000000000..dd10b34586
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch
@@ -0,0 +1,35 @@
+From 9ea478cbd5473f52ca036cccc00dddad717d7861 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 30 Jan 2008 19:27:13 +0300
+Subject: [PATCH 36/64] Set id to -1 for wm97xx subdevices
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/input/touchscreen/wm97xx-core.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
+index 27a0a99..e066acc 100644
+--- a/drivers/input/touchscreen/wm97xx-core.c
++++ b/drivers/input/touchscreen/wm97xx-core.c
+@@ -592,7 +592,7 @@ static int wm97xx_probe(struct device *dev)
+ wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
+
+ /* register our battery device */
+- wm->battery_dev = platform_device_alloc("wm97xx-battery", 0);
++ wm->battery_dev = platform_device_alloc("wm97xx-battery", -1);
+ if (!wm->battery_dev)
+ goto batt_err;
+ platform_set_drvdata(wm->battery_dev, wm);
+@@ -603,7 +603,7 @@ static int wm97xx_probe(struct device *dev)
+
+ /* register our extended touch device (for machine specific
+ * extensions) */
+- wm->touch_dev = platform_device_alloc("wm97xx-touch", 0);
++ wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
+ if (!wm->touch_dev)
+ goto touch_err;
+ platform_set_drvdata(wm->touch_dev, wm);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch b/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch
new file mode 100644
index 0000000000..010194dd96
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch
@@ -0,0 +1,41 @@
+From d2888c7643b07687b14a839239cbe7fc5bf565e6 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Mon, 14 Jan 2008 23:24:26 +0300
+Subject: [PATCH 37/64] Don't lock the codec list in snd_soc_dapm_new_widgets()
+
+snd_soc_dapm_new_widgets() takes the codec lock when adding new widgets,
+causing lockdep warnings when applications later call down through ALSA
+to adjust controls. Since widgets are only added during probe this lock
+should be unneeded so don't take it.
+
+Thanks to Dmitry Baryshkov <dbaryshkov@gmail.com> for reporting this issue.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Cc: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ sound/soc/soc-dapm.c | 2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
+index 29a546f..e46cdc5 100644
+--- a/sound/soc/soc-dapm.c
++++ b/sound/soc/soc-dapm.c
+@@ -963,7 +963,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
+ {
+ struct snd_soc_dapm_widget *w;
+
+- mutex_lock(&codec->mutex);
+ list_for_each_entry(w, &codec->dapm_widgets, list)
+ {
+ if (w->new)
+@@ -998,7 +997,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
+ }
+
+ dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
+- mutex_unlock(&codec->mutex);
+ return 0;
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch b/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch
new file mode 100644
index 0000000000..7a3eb61a27
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch
@@ -0,0 +1,57 @@
+From 5bae1fab16c7b14a458aa90e5654fe3a1d8d960f Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Sun, 20 Jan 2008 00:06:06 +0300
+Subject: [PATCH 38/64] Don't lock the codec list in snd_soc_dapm_new_widgets()
+
+On Wed, Jan 16, 2008 at 02:40:55AM +0300, Dmitry wrote:
+
+> I'm sorry, but I tested this patch only now. And I just got another
+> message from lockdep:
+
+Could you give this patch a try, please?
+---
+ sound/soc/soc-core.c | 7 +++++--
+ 1 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index e6a67b5..7f3ed9f 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1090,7 +1090,6 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
+ struct snd_soc_machine *machine = socdev->machine;
+ int ret = 0, i, ac97 = 0, err = 0;
+
+- mutex_lock(&codec->mutex);
+ for(i = 0; i < machine->num_links; i++) {
+ if (socdev->machine->dai_link[i].init) {
+ err = socdev->machine->dai_link[i].init(codec);
+@@ -1116,12 +1115,14 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
+ goto out;
+ }
+
++ mutex_lock(&codec->mutex);
+ #ifdef CONFIG_SND_SOC_AC97_BUS
+ if (ac97) {
+ ret = soc_ac97_dev_register(codec);
+ if (ret < 0) {
+ printk(KERN_ERR "asoc: AC97 device register failed\n");
+ snd_card_free(codec->card);
++ mutex_unlock(&codec->mutex);
+ goto out;
+ }
+ }
+@@ -1134,8 +1135,10 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
+ err = device_create_file(socdev->dev, &dev_attr_codec_reg);
+ if (err < 0)
+ printk(KERN_WARNING "asoc: failed to add codec sysfs entries\n");
+-out:
++
+ mutex_unlock(&codec->mutex);
++
++out:
+ return ret;
+ }
+ EXPORT_SYMBOL_GPL(snd_soc_register_card);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch b/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch
new file mode 100644
index 0000000000..c09c208c6a
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0039-Add-generic-framework-for-managing-clocks.patch
@@ -0,0 +1,446 @@
+From 62c9a23cfa7181369637d0b61a8e90c83c562f03 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 03:01:06 +0300
+Subject: [PATCH 39/64] Add generic framework for managing clocks.
+
+Provide a generic framework that platform may choose
+to support clocks api. In particular this provides
+platform-independant struct clk definition, a full
+implementation of clocks api and a set of functions
+for registering and unregistering clocks in a safe way.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ include/linux/clklib.h | 85 ++++++++++++++
+ init/Kconfig | 7 +
+ kernel/Makefile | 1 +
+ kernel/clklib.c | 295 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 388 insertions(+), 0 deletions(-)
+ create mode 100644 include/linux/clklib.h
+ create mode 100644 kernel/clklib.c
+
+diff --git a/include/linux/clklib.h b/include/linux/clklib.h
+new file mode 100644
+index 0000000..4bd9b4a
+--- /dev/null
++++ b/include/linux/clklib.h
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (C) 2008 Dmitry Baryshkov
++ *
++ * This file is released under the GPL v2.
++ */
++
++#ifndef CLKLIB_H
++#define CLKLIB_H
++
++#include <linux/list.h>
++
++struct clk {
++ struct list_head node;
++ struct clk *parent;
++
++ const char *name;
++ struct module *owner;
++
++ int users;
++ unsigned long rate;
++ int delay;
++
++ int (*can_get) (struct clk *, struct device *);
++ int (*set_parent) (struct clk *, struct clk *);
++ int (*enable) (struct clk *);
++ void (*disable) (struct clk *);
++ unsigned long (*getrate) (struct clk*);
++ int (*setrate) (struct clk *, unsigned long);
++ long (*roundrate) (struct clk *, unsigned long);
++
++ void *priv;
++};
++
++int clk_register(struct clk *clk);
++void clk_unregister(struct clk *clk);
++static void __maybe_unused clks_register(struct clk *clks, size_t num)
++{
++ int i;
++ for (i = 0; i < num; i++) {
++ clk_register(&clks[i]);
++ }
++}
++
++
++int clk_alloc_function(const char *parent, struct clk *clk);
++
++struct clk_function {
++ const char *parent;
++ struct clk *clk;
++};
++
++#define CLK_FUNC(_clock, _function, _can_get, _data, _format) \
++ { \
++ .parent = _clock, \
++ .clk = &(struct clk) { \
++ .name= _function, \
++ .owner = THIS_MODULE, \
++ .can_get = _can_get, \
++ .priv = _data, \
++ .format = _format, \
++ }, \
++ }
++
++static int __maybe_unused clk_alloc_functions(
++ struct clk_function *funcs,
++ int num)
++{
++ int i;
++ int rc;
++
++ for (i = 0; i < num; i++) {
++ rc = clk_alloc_function(funcs[i].parent, funcs[i].clk);
++
++ if (rc) {
++ printk(KERN_ERR "Error allocating %s.%s function.\n",
++ funcs[i].parent,
++ funcs[i].clk->name);
++ return rc;
++ }
++ }
++
++ return 0;
++}
++
++#endif
+diff --git a/init/Kconfig b/init/Kconfig
+index b9d11a8..05b62ba 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -435,6 +435,13 @@ config CC_OPTIMIZE_FOR_SIZE
+ config SYSCTL
+ bool
+
++config HAVE_CLOCK_LIB
++ bool
++ help
++ Platforms select clocklib if they use this infrastructure
++ for managing their clocks both built into SoC and provided
++ by external devices.
++
+ menuconfig EMBEDDED
+ bool "Configure standard kernel features (for small systems)"
+ help
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 6d9a87c..0b2ade7 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -58,6 +58,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
+ obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+ obj-$(CONFIG_MARKERS) += marker.o
+ obj-$(CONFIG_LATENCYTOP) += latencytop.o
++obj-$(CONFIG_HAVE_CLOCK_LIB) += clklib.o
+
+ ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
+ # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
+diff --git a/kernel/clklib.c b/kernel/clklib.c
+new file mode 100644
+index 0000000..203af3d
+--- /dev/null
++++ b/kernel/clklib.c
+@@ -0,0 +1,295 @@
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/clk.h>
++#include <linux/clklib.h>
++#include <linux/spinlock.h>
++#include <linux/err.h>
++#include <linux/delay.h>
++
++static LIST_HEAD(clocks);
++static DEFINE_SPINLOCK(clocks_lock);
++
++static int __clk_register(struct clk *clk)
++{
++ if (clk->parent &&
++ !try_module_get(clk->parent->owner))
++ return -EINVAL;
++
++ list_add_tail(&clk->node, &clocks);
++
++ return 0;
++}
++
++int clk_register(struct clk *clk)
++{
++ unsigned long flags;
++ int rc;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ rc = __clk_register(clk);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rc;
++}
++EXPORT_SYMBOL(clk_register);
++
++void clk_unregister(struct clk *clk)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++ list_del(&clk->node);
++ if (clk->parent)
++ module_put(clk->parent->owner);
++ spin_unlock_irqrestore(&clocks_lock, flags);
++}
++EXPORT_SYMBOL(clk_unregister);
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++ struct clk *p, *clk = ERR_PTR(-ENOENT);
++ unsigned long flags;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ list_for_each_entry(p, &clocks, node) {
++ if (strcmp(id, p->name) == 0 &&
++ (!p->can_get || p->can_get(p, dev)) &&
++ try_module_get(p->owner)) {
++ clk = p;
++ break;
++ }
++ }
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return clk;
++}
++EXPORT_SYMBOL(clk_get);
++
++void clk_put(struct clk *clk)
++{
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ module_put(clk->owner);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++}
++EXPORT_SYMBOL(clk_put);
++
++int clk_set_parent(struct clk *clk, struct clk *parent)
++{
++ int rc;
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return -EINVAL;
++
++ if (!clk->set_parent)
++ return -EINVAL;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ rc = clk->set_parent(clk, parent);
++ if (!rc)
++ clk->parent = parent;
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rc;
++}
++EXPORT_SYMBOL(clk_set_parent);
++
++static int __clk_enable(struct clk *clk)
++{
++ int rc = 0;
++
++ if (clk->parent) {
++ rc = __clk_enable(clk->parent);
++
++ if (rc)
++ return rc;
++ }
++
++ if (clk->users++ == 0)
++ if (clk->enable)
++ rc = clk->enable(clk);
++
++ if (clk->delay)
++ udelay(clk->delay);
++
++ return rc;
++}
++
++int clk_enable(struct clk *clk)
++{
++ unsigned long flags;
++ int rc;
++
++ if (!clk || IS_ERR(clk))
++ return -EINVAL;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ rc = __clk_enable(clk);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rc;
++}
++EXPORT_SYMBOL(clk_enable);
++
++static void __clk_disable(struct clk *clk)
++{
++ if (clk->users <= 0) {
++ WARN_ON(1);
++ return;
++ }
++
++ if (--clk->users == 0)
++ if (clk->disable)
++ clk->disable(clk);
++
++ if (clk->parent)
++ __clk_disable(clk->parent);
++}
++
++void clk_disable(struct clk *clk)
++{
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ __clk_disable(clk);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++}
++EXPORT_SYMBOL(clk_disable);
++
++static unsigned long __clk_get_rate(struct clk *clk)
++{
++ unsigned long rate = 0;
++
++ for (;;) {
++ if (rate || !clk)
++ return rate;
++
++ if (clk->getrate)
++ rate = clk->getrate(clk);
++ else if (clk->rate)
++ rate = clk->rate;
++ else
++ clk = clk->parent;
++ }
++}
++
++unsigned long clk_get_rate(struct clk *clk)
++{
++ unsigned long rate = 0;
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return -EINVAL;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ rate = __clk_get_rate(clk);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rate;
++}
++EXPORT_SYMBOL(clk_get_rate);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++ long res;
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return -EINVAL;
++
++ if (!clk->roundrate)
++ return -EINVAL;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ res = clk->roundrate(clk, rate);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return res;
++}
++EXPORT_SYMBOL(clk_round_rate);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++ int rc;
++ unsigned long flags;
++
++ if (!clk || IS_ERR(clk))
++ return -EINVAL;
++
++ if (!clk->setrate)
++ return -EINVAL;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ rc = clk->setrate(clk, rate);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rc;
++}
++EXPORT_SYMBOL(clk_set_rate);
++
++int clk_alloc_function(const char *parent, struct clk *clk)
++{
++ int rc = 0;
++ unsigned long flags;
++ struct clk *pclk;
++ bool found = false;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ list_for_each_entry(pclk, &clocks, node) {
++ if (strcmp(parent, pclk->name) == 0 &&
++ try_module_get(pclk->owner)) {
++ found = true;
++ break;
++ }
++ }
++
++ if (!found) {
++ rc = -ENODEV;
++ goto out;
++ }
++
++ clk->parent = pclk;
++
++ __clk_register(clk);
++ /*
++ * We locked parent owner during search
++ * and also in __clk_register. Free one reference
++ */
++ module_put(pclk->owner);
++
++out:
++ if (rc) {
++ kfree(clk);
++ }
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return rc;
++}
++EXPORT_SYMBOL(clk_alloc_function);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch
new file mode 100644
index 0000000000..160b274f4f
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0040-Clocklib-debugfs-support.patch
@@ -0,0 +1,108 @@
+From cae12d96586dac77d223559d686487ea2d457a41 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 03:01:05 +0300
+Subject: [PATCH 40/64] Clocklib debugfs support
+
+Provide /sys/kernel/debug/clock to ease debugging.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ include/linux/clklib.h | 5 +++
+ kernel/clklib.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 73 insertions(+), 0 deletions(-)
+
+diff --git a/include/linux/clklib.h b/include/linux/clklib.h
+index 4bd9b4a..f916693 100644
+--- a/include/linux/clklib.h
++++ b/include/linux/clklib.h
+@@ -28,6 +28,11 @@ struct clk {
+ int (*setrate) (struct clk *, unsigned long);
+ long (*roundrate) (struct clk *, unsigned long);
+
++ /*
++ * format any additional info
++ */
++ int (*format) (struct clk *, struct seq_file *);
++
+ void *priv;
+ };
+
+diff --git a/kernel/clklib.c b/kernel/clklib.c
+index 203af3d..b782220 100644
+--- a/kernel/clklib.c
++++ b/kernel/clklib.c
+@@ -293,3 +293,71 @@ out:
+ return rc;
+ }
+ EXPORT_SYMBOL(clk_alloc_function);
++
++#ifdef CONFIG_DEBUG_FS
++
++#include <linux/debugfs.h>
++#include <linux/seq_file.h>
++static void dump_clocks(struct seq_file *s, struct clk *parent, int nest)
++{
++ struct clk *clk;
++ int i;
++
++ list_for_each_entry(clk, &clocks, node) {
++ if (clk->parent == parent) {
++ for (i = 0; i < nest; i++)
++ seq_putc(s, ' ');
++ seq_puts(s, clk->name);
++
++ i = nest + strlen(clk->name);
++ if (i >= 16)
++ i = 15;
++ for (; i < 16; i++)
++ seq_putc(s, ' ');
++ seq_printf(s, "%c use=%d rate=%lu KHz",
++ clk->set_parent ? '*' : ' ',
++ clk->users,
++ __clk_get_rate(clk));
++ if (clk->format)
++ clk->format(clk, s);
++ seq_putc(s, '\n');
++
++ dump_clocks(s, clk, nest + 1);
++ }
++ }
++}
++
++static int clocklib_show(struct seq_file *s, void *unused)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&clocks_lock, flags);
++
++ dump_clocks(s, NULL, 0);
++
++ spin_unlock_irqrestore(&clocks_lock, flags);
++
++ return 0;
++}
++
++static int clocklib_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, clocklib_show, NULL);
++}
++
++static struct file_operations clocklib_operations = {
++ .open = clocklib_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release,
++};
++
++static int __init clocklib_debugfs_init(void)
++{
++ debugfs_create_file("clock", S_IFREG | S_IRUGO,
++ NULL, NULL, &clocklib_operations);
++ return 0;
++}
++subsys_initcall(clocklib_debugfs_init);
++
++#endif /* DEBUG_FS */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch b/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch
new file mode 100644
index 0000000000..9c95c67e78
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch
@@ -0,0 +1,593 @@
+From 2a143b9546b01fd6c58ebaac7eb46568a17d6a41 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Tue, 12 Feb 2008 04:58:59 +0300
+Subject: [PATCH 41/64] From 80a359e60c2aec59ccf4fca0a7fd20495f82b1d2 Mon Sep 17 00:00:00 2001
+ In-Reply-To: <20080207005839.GA28509@doriath.ww600.siemens.net>
+ References: <20080207005839.GA28509@doriath.ww600.siemens.net>
+ Date: Thu, 7 Feb 2008 03:35:08 +0300
+ Subject: [PATCH 3/5] Use clocklib for ARM pxa sub-arch.
+ Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/mach-pxa/clock.c | 108 ++++++--------------------------------------
+ arch/arm/mach-pxa/clock.h | 58 +++++++++++++-----------
+ arch/arm/mach-pxa/pxa25x.c | 64 +++++++++++++++-----------
+ arch/arm/mach-pxa/pxa27x.c | 61 +++++++++++++-----------
+ arch/arm/mach-pxa/pxa3xx.c | 91 +++++++++++++++++++++----------------
+ 6 files changed, 169 insertions(+), 214 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 423e953..47f3c73 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -347,6 +347,7 @@ config ARCH_PXA
+ select GENERIC_CLOCKEVENTS
+ select TICK_ONESHOT
+ select HAVE_GPIO_LIB
++ select HAVE_CLOCK_LIB
+ help
+ Support for Intel/Marvell's PXA2xx/PXA3xx processor line.
+
+diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
+index 83ef5ec..3296b02 100644
+--- a/arch/arm/mach-pxa/clock.c
++++ b/arch/arm/mach-pxa/clock.c
+@@ -8,6 +8,7 @@
+ #include <linux/err.h>
+ #include <linux/string.h>
+ #include <linux/clk.h>
++#include <linux/clklib.h>
+ #include <linux/spinlock.h>
+ #include <linux/platform_device.h>
+ #include <linux/delay.h>
+@@ -19,123 +20,42 @@
+ #include "generic.h"
+ #include "clock.h"
+
+-static LIST_HEAD(clocks);
+-static DEFINE_MUTEX(clocks_mutex);
+-static DEFINE_SPINLOCK(clocks_lock);
+-
+-struct clk *clk_get(struct device *dev, const char *id)
+-{
+- struct clk *p, *clk = ERR_PTR(-ENOENT);
+-
+- mutex_lock(&clocks_mutex);
+- list_for_each_entry(p, &clocks, node) {
+- if (strcmp(id, p->name) == 0 &&
+- (p->dev == NULL || p->dev == dev)) {
+- clk = p;
+- break;
+- }
+- }
+- mutex_unlock(&clocks_mutex);
+-
+- return clk;
+-}
+-EXPORT_SYMBOL(clk_get);
+-
+-void clk_put(struct clk *clk)
++static int clk_gpio27_enable(struct clk *clk)
+ {
+-}
+-EXPORT_SYMBOL(clk_put);
+-
+-int clk_enable(struct clk *clk)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&clocks_lock, flags);
+- if (clk->enabled++ == 0)
+- clk->ops->enable(clk);
+- spin_unlock_irqrestore(&clocks_lock, flags);
+-
+- if (clk->delay)
+- udelay(clk->delay);
++ pxa_gpio_mode(GPIO11_3_6MHz_MD);
+
+ return 0;
+ }
+-EXPORT_SYMBOL(clk_enable);
+-
+-void clk_disable(struct clk *clk)
+-{
+- unsigned long flags;
+-
+- WARN_ON(clk->enabled == 0);
+-
+- spin_lock_irqsave(&clocks_lock, flags);
+- if (--clk->enabled == 0)
+- clk->ops->disable(clk);
+- spin_unlock_irqrestore(&clocks_lock, flags);
+-}
+-EXPORT_SYMBOL(clk_disable);
+-
+-unsigned long clk_get_rate(struct clk *clk)
+-{
+- unsigned long rate;
+-
+- rate = clk->rate;
+- if (clk->ops->getrate)
+- rate = clk->ops->getrate(clk);
+-
+- return rate;
+-}
+-EXPORT_SYMBOL(clk_get_rate);
+-
+-
+-static void clk_gpio27_enable(struct clk *clk)
+-{
+- pxa_gpio_mode(GPIO11_3_6MHz_MD);
+-}
+
+ static void clk_gpio27_disable(struct clk *clk)
+ {
++ /* FIXME: disable clock */
+ }
+
+-static const struct clkops clk_gpio27_ops = {
+- .enable = clk_gpio27_enable,
+- .disable = clk_gpio27_disable,
+-};
+-
+-
+-void clk_cken_enable(struct clk *clk)
++int clk_cken_enable(struct clk *clk)
+ {
+- CKEN |= 1 << clk->cken;
++ int cken = ((struct clk_cken_priv *)clk->priv)->cken;
++ CKEN |= 1 << cken;
++
++ return 0;
+ }
+
+ void clk_cken_disable(struct clk *clk)
+ {
+- CKEN &= ~(1 << clk->cken);
++ int cken = ((struct clk_cken_priv *)clk->priv)->cken;
++ CKEN &= ~(1 << cken);
+ }
+
+-const struct clkops clk_cken_ops = {
+- .enable = clk_cken_enable,
+- .disable = clk_cken_disable,
+-};
+-
+ static struct clk common_clks[] = {
+ {
+ .name = "GPIO27_CLK",
+- .ops = &clk_gpio27_ops,
+ .rate = 3686400,
++ .owner = THIS_MODULE,
++ .enable = clk_gpio27_enable,
++ .disable = clk_gpio27_disable,
+ },
+ };
+
+-void clks_register(struct clk *clks, size_t num)
+-{
+- int i;
+-
+- mutex_lock(&clocks_mutex);
+- for (i = 0; i < num; i++)
+- list_add(&clks[i].node, &clocks);
+- mutex_unlock(&clocks_mutex);
+-}
+-
+ static int __init clk_init(void)
+ {
+ clks_register(common_clks, ARRAY_SIZE(common_clks));
+diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
+index bc6b77e..5d0d067 100644
+--- a/arch/arm/mach-pxa/clock.h
++++ b/arch/arm/mach-pxa/clock.h
+@@ -1,43 +1,47 @@
+-struct clk;
++#include <linux/clklib.h>
++#include <linux/seq_file.h>
+
+-struct clkops {
+- void (*enable)(struct clk *);
+- void (*disable)(struct clk *);
+- unsigned long (*getrate)(struct clk *);
++struct clk_cken_priv {
++ unsigned int cken;
+ };
+
+-struct clk {
+- struct list_head node;
+- const char *name;
+- struct device *dev;
+- const struct clkops *ops;
+- unsigned long rate;
+- unsigned int cken;
+- unsigned int delay;
+- unsigned int enabled;
+-};
+-
+-#define INIT_CKEN(_name, _cken, _rate, _delay, _dev) \
++#define INIT_CKEN(_name, _cken, _rate, _delay) \
+ { \
+ .name = _name, \
+- .dev = _dev, \
+- .ops = &clk_cken_ops, \
++ .enable = clk_cken_enable, \
++ .disable = clk_cken_disable, \
+ .rate = _rate, \
+- .cken = CKEN_##_cken, \
+ .delay = _delay, \
++ .priv = &(struct clk_cken_priv) { \
++ .cken = CKEN_##_cken, \
++ }, \
+ }
+
+-#define INIT_CK(_name, _cken, _ops, _dev) \
++#define INIT_CK(_name, _cken, _getrate) \
+ { \
+ .name = _name, \
+- .dev = _dev, \
+- .ops = _ops, \
+- .cken = CKEN_##_cken, \
++ .enable = clk_cken_enable, \
++ .disable = clk_cken_disable, \
++ .getrate = _getrate, \
++ .priv = &(struct clk_cken_priv) { \
++ .cken = CKEN_##_cken, \
++ }, \
+ }
+
+-extern const struct clkops clk_cken_ops;
+-
+-void clk_cken_enable(struct clk *clk);
++int clk_cken_enable(struct clk *clk);
+ void clk_cken_disable(struct clk *clk);
+
+ void clks_register(struct clk *clks, size_t num);
++
++static int __maybe_unused clk_dev_can_get(struct clk *clk, struct device *dev)
++{
++ return (dev == clk->priv);
++}
++
++static int __maybe_unused clk_dev_format(struct clk *clk, struct seq_file *s)
++{
++ BUG_ON(!clk->priv);
++ seq_puts(s, "for device ");
++ seq_puts(s, ((struct device *)clk->priv)->bus_id);
++ return 0;
++}
+diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
+index 5988d99..ed3719b 100644
+--- a/arch/arm/mach-pxa/pxa25x.c
++++ b/arch/arm/mach-pxa/pxa25x.c
+@@ -100,40 +100,50 @@ static unsigned long clk_pxa25x_lcd_getrate(struct clk *clk)
+ return pxa25x_get_memclk_frequency_10khz() * 10000;
+ }
+
+-static const struct clkops clk_pxa25x_lcd_ops = {
+- .enable = clk_cken_enable,
+- .disable = clk_cken_disable,
+- .getrate = clk_pxa25x_lcd_getrate,
+-};
+-
+ /*
+ * 3.6864MHz -> OST, GPIO, SSP, PWM, PLLs (95.842MHz, 147.456MHz)
+ * 95.842MHz -> MMC 19.169MHz, I2C 31.949MHz, FICP 47.923MHz, USB 47.923MHz
+ * 147.456MHz -> UART 14.7456MHz, AC97 12.288MHz, I2S 5.672MHz (allegedly)
+ */
+-static struct clk pxa25x_hwuart_clk =
+- INIT_CKEN("UARTCLK", HWUART, 14745600, 1, &pxa_device_hwuart.dev)
+-;
++static struct clk pxa25x_hwuart_clk[] = {
++ INIT_CKEN("HWUARTCLK", HWUART, 14745600, 1),
++ {
++ .parent = &pxa25x_hwuart_clk[0],
++ .name = "UARTCLK",
++ .can_get = clk_dev_can_get,
++ .priv = &pxa_device_hwuart.dev,
++ },
++};
+
+ static struct clk pxa25x_clks[] = {
+- INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
+- INIT_CKEN("UARTCLK", FFUART, 14745600, 1, &pxa_device_ffuart.dev),
+- INIT_CKEN("UARTCLK", BTUART, 14745600, 1, &pxa_device_btuart.dev),
+- INIT_CKEN("UARTCLK", STUART, 14745600, 1, NULL),
+- INIT_CKEN("UDCCLK", USB, 47923000, 5, &pxa_device_udc.dev),
+- INIT_CKEN("MMCCLK", MMC, 19169000, 0, &pxa_device_mci.dev),
+- INIT_CKEN("I2CCLK", I2C, 31949000, 0, &pxa_device_i2c.dev),
+-
+- INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev),
+- INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev),
+- INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev),
++ INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_getrate),
++ INIT_CKEN("FFUARTCLK", FFUART, 14745600, 1),
++ INIT_CKEN("BTUARTCLK", BTUART, 14745600, 1),
++ INIT_CKEN("STUARTCLK", STUART, 14745600, 1),
++ INIT_CKEN("UDCCLK", USB, 47923000, 5),
++ INIT_CKEN("MMCCLK", MMC, 19169000, 0),
++ INIT_CKEN("I2CCLK", I2C, 31949000, 0),
++
++ INIT_CKEN("SSP_CLK", SSP, 3686400, 0),
++ INIT_CKEN("NSSPCLK", NSSP, 3686400, 0),
++ INIT_CKEN("ASSPCLK", ASSP, 3686400, 0),
+
+ /*
+- INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+- INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL),
+- INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL),
++ INIT_CKEN("PWMCLK", PWM0, 3686400, 0),
++ INIT_CKEN("PWMCLK", PWM0, 3686400, 0),
++ INIT_CKEN("I2SCLK", I2S, 14745600, 0),
+ */
+- INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
++ INIT_CKEN("FICPCLK", FICP, 47923000, 0),
++};
++
++static struct clk_function __initdata pxa25x_clk_funcs[] = {
++ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format),
++ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL),
++ CLK_FUNC("SSP_CLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_ssp.dev, clk_dev_format),
++ CLK_FUNC("NSSPCLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_nssp.dev, clk_dev_format),
++ CLK_FUNC("ASSPCLK", "SSPCLK", clk_dev_can_get, &pxa25x_device_assp.dev, clk_dev_format),
+ };
+
+ #ifdef CONFIG_PM
+@@ -313,11 +323,13 @@ static int __init pxa25x_init(void)
+ int ret = 0;
+
+ /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */
+- if (cpu_is_pxa25x())
+- clks_register(&pxa25x_hwuart_clk, 1);
++ if (cpu_is_pxa25x()) {
++ clks_register(pxa25x_hwuart_clk, ARRAY_SIZE(pxa25x_hwuart_clk));
++ }
+
+ if (cpu_is_pxa21x() || cpu_is_pxa25x()) {
+ clks_register(pxa25x_clks, ARRAY_SIZE(pxa25x_clks));
++ clk_alloc_functions(pxa25x_clk_funcs, ARRAY_SIZE(pxa25x_clk_funcs));
+
+ if ((ret = pxa_init_dma(16)))
+ return ret;
+diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
+index 30ca4fd..c51e7b2 100644
+--- a/arch/arm/mach-pxa/pxa27x.c
++++ b/arch/arm/mach-pxa/pxa27x.c
+@@ -126,44 +126,48 @@ static unsigned long clk_pxa27x_lcd_getrate(struct clk *clk)
+ return pxa27x_get_lcdclk_frequency_10khz() * 10000;
+ }
+
+-static const struct clkops clk_pxa27x_lcd_ops = {
+- .enable = clk_cken_enable,
+- .disable = clk_cken_disable,
+- .getrate = clk_pxa27x_lcd_getrate,
+-};
+-
+ static struct clk pxa27x_clks[] = {
+- INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_ops, &pxa_device_fb.dev),
+- INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_ops, NULL),
++ INIT_CK("LCDCLK", LCD, &clk_pxa27x_lcd_getrate),
++ INIT_CK("CAMCLK", CAMERA, &clk_pxa27x_lcd_getrate),
+
+- INIT_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+- INIT_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+- INIT_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
++ INIT_CKEN("FFUARTCLK", FFUART, 14857000, 1),
++ INIT_CKEN("BTUARTCLK", BTUART, 14857000, 1),
++ INIT_CKEN("STUARTCLK", STUART, 14857000, 1),
+
+- INIT_CKEN("I2SCLK", I2S, 14682000, 0, &pxa_device_i2s.dev),
+- INIT_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
+- INIT_CKEN("UDCCLK", USB, 48000000, 5, &pxa_device_udc.dev),
+- INIT_CKEN("MMCCLK", MMC, 19500000, 0, &pxa_device_mci.dev),
+- INIT_CKEN("FICPCLK", FICP, 48000000, 0, &pxa_device_ficp.dev),
++ INIT_CKEN("I2SCLK", I2S, 14682000, 0),
++ INIT_CKEN("I2CCLK", I2C, 32842000, 0),
++ INIT_CKEN("UDCCLK", USB, 48000000, 5),
++ INIT_CKEN("MMCCLK", MMC, 19500000, 0),
++ INIT_CKEN("FICPCLK", FICP, 48000000, 0),
+
+- INIT_CKEN("USBCLK", USBHOST, 48000000, 0, &pxa27x_device_ohci.dev),
+- INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0, &pxa27x_device_i2c_power.dev),
+- INIT_CKEN("KBDCLK", KEYPAD, 32768, 0, NULL),
++ INIT_CKEN("USBCLK", USBHOST, 48000000, 0),
++ INIT_CKEN("I2CCLK", PWRI2C, 13000000, 0),
++ INIT_CKEN("KBDCLK", KEYPAD, 32768, 0),
+
+- INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
+- INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
+- INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
++ INIT_CKEN("SSP1CLK", SSP1, 13000000, 0),
++ INIT_CKEN("SSP2CLK", SSP2, 13000000, 0),
++ INIT_CKEN("SSP3CLK", SSP3, 13000000, 0),
+
+ /*
+- INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL),
+- INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL),
+- INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL),
+- INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL),
+- INIT_CKEN("IMCLK", IM, 0, 0, NULL),
+- INIT_CKEN("MEMCLK", MEMC, 0, 0, NULL),
++ INIT_CKEN("PWMCLK", PWM0, 13000000, 0),
++ INIT_CKEN("MSLCLK", MSL, 48000000, 0),
++ INIT_CKEN("USIMCLK", USIM, 48000000, 0),
++ INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0),
++ INIT_CKEN("IMCLK", IM, 0, 0),
++ INIT_CKEN("MEMCLK", MEMC, 0, 0),
+ */
+ };
+
++static struct clk_function __initdata pxa27x_clk_funcs[] = {
++ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format),
++ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL),
++ CLK_FUNC("SSP1CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp1.dev, clk_dev_format),
++ CLK_FUNC("SSP2CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp2.dev, clk_dev_format),
++ CLK_FUNC("SSP3CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp3.dev, clk_dev_format),
++};
++
+ #ifdef CONFIG_PM
+
+ #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+@@ -453,6 +457,7 @@ static int __init pxa27x_init(void)
+ int ret = 0;
+ if (cpu_is_pxa27x()) {
+ clks_register(pxa27x_clks, ARRAY_SIZE(pxa27x_clks));
++ clk_alloc_functions(pxa27x_clk_funcs, ARRAY_SIZE(pxa27x_clk_funcs));
+
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
+index ccab9da..0f8bbf3 100644
+--- a/arch/arm/mach-pxa/pxa3xx.c
++++ b/arch/arm/mach-pxa/pxa3xx.c
+@@ -122,27 +122,31 @@ static unsigned long clk_pxa3xx_hsio_getrate(struct clk *clk)
+ return hsio_clk;
+ }
+
+-static void clk_pxa3xx_cken_enable(struct clk *clk)
++static int clk_pxa3xx_cken_enable(struct clk *clk)
+ {
+- unsigned long mask = 1ul << (clk->cken & 0x1f);
++ int cken = ((struct clk_cken_priv *)clk->priv)->cken;
++ unsigned long mask = 1ul << (cken & 0x1f);
+
+ local_irq_disable();
+
+- if (clk->cken < 32)
++ if (cken < 32)
+ CKENA |= mask;
+ else
+ CKENB |= mask;
+
+ local_irq_enable();
++
++ return 0;
+ }
+
+ static void clk_pxa3xx_cken_disable(struct clk *clk)
+ {
+- unsigned long mask = 1ul << (clk->cken & 0x1f);
++ int cken = ((struct clk_cken_priv *)clk->priv)->cken;
++ unsigned long mask = 1ul << (cken & 0x1f);
+
+ local_irq_disable();
+
+- if (clk->cken < 32)
++ if (cken < 32)
+ CKENA &= ~mask;
+ else
+ CKENB &= ~mask;
+@@ -150,55 +154,63 @@ static void clk_pxa3xx_cken_disable(struct clk *clk)
+ local_irq_enable();
+ }
+
+-static const struct clkops clk_pxa3xx_cken_ops = {
+- .enable = clk_pxa3xx_cken_enable,
+- .disable = clk_pxa3xx_cken_disable,
+-};
+-
+-static const struct clkops clk_pxa3xx_hsio_ops = {
+- .enable = clk_pxa3xx_cken_enable,
+- .disable = clk_pxa3xx_cken_disable,
+- .getrate = clk_pxa3xx_hsio_getrate,
+-};
+-
+-#define PXA3xx_CKEN(_name, _cken, _rate, _delay, _dev) \
++#define PXA3xx_CKEN(_name, _cken, _rate, _delay) \
+ { \
+ .name = _name, \
+- .dev = _dev, \
+- .ops = &clk_pxa3xx_cken_ops, \
++ .enable = clk_pxa3xx_cken_enable, \
++ .disable = clk_pxa3xx_cken_disable, \
+ .rate = _rate, \
+- .cken = CKEN_##_cken, \
+ .delay = _delay, \
++ .priv = &(struct clk_cken_priv) { \
++ .cken = CKEN_##_cken, \
++ }, \
+ }
+
+-#define PXA3xx_CK(_name, _cken, _ops, _dev) \
++#define PXA3xx_CK(_name, _cken, _getrate) \
+ { \
+ .name = _name, \
+- .dev = _dev, \
+- .ops = _ops, \
+- .cken = CKEN_##_cken, \
++ .enable = clk_pxa3xx_cken_enable, \
++ .disable = clk_pxa3xx_cken_disable, \
++ .getrate = _getrate, \
++ .priv = &(struct clk_cken_priv) { \
++ .cken = CKEN_##_cken, \
++ }, \
+ }
+
+ static struct clk pxa3xx_clks[] = {
+- PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_ops, &pxa_device_fb.dev),
+- PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_ops, NULL),
++ PXA3xx_CK("LCDCLK", LCD, &clk_pxa3xx_hsio_getrate),
++ PXA3xx_CK("CAMCLK", CAMERA, &clk_pxa3xx_hsio_getrate),
+
+- PXA3xx_CKEN("UARTCLK", FFUART, 14857000, 1, &pxa_device_ffuart.dev),
+- PXA3xx_CKEN("UARTCLK", BTUART, 14857000, 1, &pxa_device_btuart.dev),
+- PXA3xx_CKEN("UARTCLK", STUART, 14857000, 1, NULL),
++ PXA3xx_CKEN("FFUARTCLK", FFUART, 14857000, 1),
++ PXA3xx_CKEN("BTUARTCLK", BTUART, 14857000, 1),
++ PXA3xx_CKEN("STUARTCLK", STUART, 14857000, 1),
+
+- PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0, &pxa_device_i2c.dev),
+- PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5, &pxa_device_udc.dev),
+- PXA3xx_CKEN("USBCLK", USBH, 48000000, 0, &pxa27x_device_ohci.dev),
++ PXA3xx_CKEN("I2CCLK", I2C, 32842000, 0),
++ PXA3xx_CKEN("UDCCLK", UDC, 48000000, 5),
++ PXA3xx_CKEN("USBCLK", USBH, 48000000, 0),
+
+- PXA3xx_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev),
+- PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
+- PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
+- PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
++ PXA3xx_CKEN("SSP1CLK", SSP1, 13000000, 0),
++ PXA3xx_CKEN("SSP2CLK", SSP2, 13000000, 0),
++ PXA3xx_CKEN("SSP3CLK", SSP3, 13000000, 0),
++ PXA3xx_CKEN("SSP4CLK", SSP4, 13000000, 0),
++
++ PXA3xx_CKEN("MMC1CLK", MMC1, 19500000, 0),
++ PXA3xx_CKEN("MMC2CLK", MMC2, 19500000, 0),
++ PXA3xx_CKEN("MMC3CLK", MMC3, 19500000, 0),
++};
+
+- PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
+- PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev),
+- PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
++static struct clk_function __initdata pxa3xx_clk_funcs[] = {
++ CLK_FUNC("FFUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_ffuart.dev, clk_dev_format),
++ CLK_FUNC("BTUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_btuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "UARTCLK", clk_dev_can_get, &pxa_device_stuart.dev, clk_dev_format),
++ CLK_FUNC("STUARTCLK", "SIRCLK", NULL, NULL, NULL),
++ CLK_FUNC("SSP1CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp1.dev, clk_dev_format),
++ CLK_FUNC("SSP2CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp2.dev, clk_dev_format),
++ CLK_FUNC("SSP3CLK", "SSPCLK", clk_dev_can_get, &pxa27x_device_ssp3.dev, clk_dev_format),
++ CLK_FUNC("SSP4CLK", "SSPCLK", clk_dev_can_get, &pxa3xx_device_ssp4.dev, clk_dev_format),
++ CLK_FUNC("MMC1CLK", "MMCCLK", clk_dev_can_get, &pxa_device_mci.dev, clk_dev_format),
++ CLK_FUNC("MMC2CLK", "MMCCLK", clk_dev_can_get, &pxa3xx_device_mci2.dev, clk_dev_format),
++ CLK_FUNC("MMC3CLK", "MMCCLK", clk_dev_can_get, &pxa3xx_device_mci3.dev, clk_dev_format),
+ };
+
+ #ifdef CONFIG_PM
+@@ -255,6 +267,7 @@ static int __init pxa3xx_init(void)
+
+ if (cpu_is_pxa3xx()) {
+ clks_register(pxa3xx_clks, ARRAY_SIZE(pxa3xx_clks));
++ clk_alloc_functions(pxa3xx_clk_funcs, ARRAY_SIZE(pxa3xx_clk_funcs));
+
+ if ((ret = pxa_init_dma(32)))
+ return ret;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch b/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch
new file mode 100644
index 0000000000..a605735df0
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch
@@ -0,0 +1,26 @@
+From 70dfe7e736467af6242c61092cb64f44d2fd50e3 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 03:01:05 +0300
+Subject: [PATCH 42/64] Use correct clock for IrDA on pxa
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/net/irda/pxaficp_ir.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
+index 8c09344..36d2ec0 100644
+--- a/drivers/net/irda/pxaficp_ir.c
++++ b/drivers/net/irda/pxaficp_ir.c
+@@ -814,7 +814,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
+ si->dev = &pdev->dev;
+ si->pdata = pdev->dev.platform_data;
+
+- si->sir_clk = clk_get(&pdev->dev, "UARTCLK");
++ si->sir_clk = clk_get(&pdev->dev, "SIRCLK");
+ si->fir_clk = clk_get(&pdev->dev, "FICPCLK");
+ if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) {
+ err = PTR_ERR(IS_ERR(si->sir_clk) ? si->sir_clk : si->fir_clk);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch b/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch
new file mode 100644
index 0000000000..22b8414b2d
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch
@@ -0,0 +1,153 @@
+From 3932e0f5c4c05200c030b60606ed2eb83550f4bb Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 03:01:04 +0300
+Subject: [PATCH 43/64] Use clocklib for sa1100 sub-arch.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/mach-sa1100/clock.c | 95 ++---------------------------------------
+ 2 files changed, 6 insertions(+), 90 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 47f3c73..fa47201 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -370,6 +370,7 @@ config ARCH_SA1100
+ select ARCH_MTD_XIP
+ select GENERIC_GPIO
+ select GENERIC_TIME
++ select HAVE_CLOCK_LIB
+ help
+ Support for StrongARM 11x0 based boards.
+
+diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
+index fc97fe5..6b3cc51 100644
+--- a/arch/arm/mach-sa1100/clock.c
++++ b/arch/arm/mach-sa1100/clock.c
+@@ -8,83 +8,13 @@
+ #include <linux/err.h>
+ #include <linux/string.h>
+ #include <linux/clk.h>
++#include <linux/clklib.h>
+ #include <linux/spinlock.h>
+ #include <linux/mutex.h>
+
+ #include <asm/hardware.h>
+
+-/*
+- * Very simple clock implementation - we only have one clock to
+- * deal with at the moment, so we only match using the "name".
+- */
+-struct clk {
+- struct list_head node;
+- unsigned long rate;
+- const char *name;
+- unsigned int enabled;
+- void (*enable)(void);
+- void (*disable)(void);
+-};
+-
+-static LIST_HEAD(clocks);
+-static DEFINE_MUTEX(clocks_mutex);
+-static DEFINE_SPINLOCK(clocks_lock);
+-
+-struct clk *clk_get(struct device *dev, const char *id)
+-{
+- struct clk *p, *clk = ERR_PTR(-ENOENT);
+-
+- mutex_lock(&clocks_mutex);
+- list_for_each_entry(p, &clocks, node) {
+- if (strcmp(id, p->name) == 0) {
+- clk = p;
+- break;
+- }
+- }
+- mutex_unlock(&clocks_mutex);
+-
+- return clk;
+-}
+-EXPORT_SYMBOL(clk_get);
+-
+-void clk_put(struct clk *clk)
+-{
+-}
+-EXPORT_SYMBOL(clk_put);
+-
+-int clk_enable(struct clk *clk)
+-{
+- unsigned long flags;
+-
+- spin_lock_irqsave(&clocks_lock, flags);
+- if (clk->enabled++ == 0)
+- clk->enable();
+- spin_unlock_irqrestore(&clocks_lock, flags);
+- return 0;
+-}
+-EXPORT_SYMBOL(clk_enable);
+-
+-void clk_disable(struct clk *clk)
+-{
+- unsigned long flags;
+-
+- WARN_ON(clk->enabled == 0);
+-
+- spin_lock_irqsave(&clocks_lock, flags);
+- if (--clk->enabled == 0)
+- clk->disable();
+- spin_unlock_irqrestore(&clocks_lock, flags);
+-}
+-EXPORT_SYMBOL(clk_disable);
+-
+-unsigned long clk_get_rate(struct clk *clk)
+-{
+- return clk->rate;
+-}
+-EXPORT_SYMBOL(clk_get_rate);
+-
+-
+-static void clk_gpio27_enable(void)
++static int clk_gpio27_enable(struct clk *clk)
+ {
+ /*
+ * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+@@ -93,9 +23,11 @@ static void clk_gpio27_enable(void)
+ GAFR |= GPIO_32_768kHz;
+ GPDR |= GPIO_32_768kHz;
+ TUCR = TUCR_3_6864MHz;
++
++ return 0;
+ }
+
+-static void clk_gpio27_disable(void)
++static void clk_gpio27_disable(struct clk *clk)
+ {
+ TUCR = 0;
+ GPDR &= ~GPIO_32_768kHz;
+@@ -109,23 +41,6 @@ static struct clk clk_gpio27 = {
+ .disable = clk_gpio27_disable,
+ };
+
+-int clk_register(struct clk *clk)
+-{
+- mutex_lock(&clocks_mutex);
+- list_add(&clk->node, &clocks);
+- mutex_unlock(&clocks_mutex);
+- return 0;
+-}
+-EXPORT_SYMBOL(clk_register);
+-
+-void clk_unregister(struct clk *clk)
+-{
+- mutex_lock(&clocks_mutex);
+- list_del(&clk->node);
+- mutex_unlock(&clocks_mutex);
+-}
+-EXPORT_SYMBOL(clk_unregister);
+-
+ static int __init clk_init(void)
+ {
+ clk_register(&clk_gpio27);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch b/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch
new file mode 100644
index 0000000000..5ca8228604
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0044-fix-tmio_mmc-debug-compilation.patch
@@ -0,0 +1,26 @@
+From 03fdebde257197c13c0d10882e16a2a888ab4e0a Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sat, 2 Feb 2008 20:23:01 +0300
+Subject: [PATCH 44/64] fix tmio_mmc debug compilation
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/mmc/host/tmio_mmc.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
+index 735c386..b0d38e2 100644
+--- a/drivers/mmc/host/tmio_mmc.c
++++ b/drivers/mmc/host/tmio_mmc.c
+@@ -329,7 +329,7 @@ static irqreturn_t tmio_mmc_irq(int irq, void *devid)
+ if (!ireg) {
+ disable_mmc_irqs(ctl, status & ~irq_mask);
+ #ifdef CONFIG_MMC_DEBUG
+- WARN("tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
++ printk(KERN_WARNING "tmio_mmc: Spurious MMC irq, disabling! 0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
+ debug_status(status);
+ #endif
+ goto out;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch b/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch
new file mode 100644
index 0000000000..10f483b89d
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0045-Update-tmio_ohci.patch
@@ -0,0 +1,416 @@
+From fe3c05491370965eb821aedc95f771b86ebab3ab Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:01:44 +0300
+Subject: [PATCH 45/64] Update tmio_ohci:
+ Ports management.
+ Basic support for ohci suspend/resume.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/mfd/tc6393xb.c | 40 ++++++++
+ drivers/usb/host/ohci-tmio.c | 206 +++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 235 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+index 9439f39..5d17687 100644
+--- a/drivers/mfd/tc6393xb.c
++++ b/drivers/mfd/tc6393xb.c
+@@ -224,6 +224,44 @@ static int tc6393xb_ohci_enable(struct platform_device *ohci)
+ return 0;
+ }
+
++static int tc6393xb_ohci_suspend(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.usbcken = 0;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_ohci_resume(struct platform_device *ohci)
++{
++ struct platform_device *dev = to_platform_device(ohci->dev.parent);
++ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ union tc6393xb_scr_ccr ccr;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ ccr.raw = ioread16(&scr->ccr);
++ ccr.bits.usbcken = 1;
++ iowrite16(ccr.raw, &scr->ccr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
+ static int tc6393xb_fb_disable(struct platform_device *fb)
+ {
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+@@ -423,6 +461,8 @@ static struct mfd_cell tc6393xb_cells[] = {
+ .name = "tmio-ohci",
+ .enable = tc6393xb_ohci_enable,
+ .disable = tc6393xb_ohci_disable,
++ .suspend = tc6393xb_ohci_suspend,
++ .resume = tc6393xb_ohci_resume,
+ .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
+ .resources = tc6393xb_ohci_resources,
+ },
+diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
+index be609f3..65e3cd3 100644
+--- a/drivers/usb/host/ohci-tmio.c
++++ b/drivers/usb/host/ohci-tmio.c
+@@ -75,10 +75,13 @@ struct tmio_uhccr {
+ u8 x07[3];
+ } __attribute__((packed));
+
++#define MAX_TMIO_OHCI_PORTS 3
++
+ #define UHCCR_PM_GKEN 0x0001
+ #define UHCCR_PM_CKRNEN 0x0002
+ #define UHCCR_PM_USBPW1 0x0004
+ #define UHCCR_PM_USBPW2 0x0008
++#define UHCCR_PM_USBPW3 0x0008
+ #define UHCCR_PM_PMEE 0x0100
+ #define UHCCR_PM_PMES 0x8000
+
+@@ -86,44 +89,96 @@ struct tmio_uhccr {
+
+ struct tmio_hcd {
+ struct tmio_uhccr __iomem *ccr;
++ spinlock_t lock; /* protects RMW cycles and disabled_ports data */
++ bool disabled_ports[MAX_TMIO_OHCI_PORTS];
+ };
+
+ #define hcd_to_tmio(hcd) ((struct tmio_hcd *)(hcd_to_ohci(hcd) + 1))
+ #define ohci_to_tmio(ohci) ((struct tmio_hcd *)(ohci + 1))
+
++struct indexed_device_attribute{
++ struct device_attribute dev_attr;
++ int index;
++};
++#define to_indexed_dev_attr(_dev_attr) \
++ container_of(_dev_attr, struct indexed_device_attribute, dev_attr)
++
++#define INDEXED_ATTR(_name, _mode, _show, _store, _index) \
++ { .dev_attr = __ATTR(_name ## _index, _mode, _show, _store), \
++ .index = _index }
++
++#define INDEXED_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
++struct indexed_device_attribute dev_attr_##_name ## _index \
++ = INDEXED_ATTR(_name, _mode, _show, _store, _index)
++
++static bool disabled_tmio_ports[MAX_TMIO_OHCI_PORTS];
++module_param_array(disabled_tmio_ports, bool, NULL, 0644);
++MODULE_PARM_DESC(disabled_tmio_ports,
++ "disable specified TC6393 usb ports (default: all enabled)");
++
+ /*-------------------------------------------------------------------------*/
+
++static void tmio_write_pm(struct platform_device *dev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ struct tmio_uhccr __iomem *ccr = tmio->ccr;
++ u16 pm;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tmio->lock, flags);
++
++ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN |
++ UHCCR_PM_PMEE | UHCCR_PM_PMES;
++
++ if (tmio->disabled_ports[0])
++ pm |= UHCCR_PM_USBPW1;
++ if (tmio->disabled_ports[1])
++ pm |= UHCCR_PM_USBPW2;
++ if (tmio->disabled_ports[2])
++ pm |= UHCCR_PM_USBPW3;
++
++ iowrite16(pm, &ccr->pm);
++ spin_unlock_irqrestore(&tmio->lock, flags);
++}
++
+ static void tmio_stop_hc(struct platform_device *dev)
+ {
+ struct mfd_cell *cell = mfd_get_cell(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+ struct tmio_uhccr __iomem *ccr = tmio->ccr;
+ u16 pm;
+
+- pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN | UHCCR_PM_USBPW1 | UHCCR_PM_USBPW2;
++ pm = UHCCR_PM_GKEN | UHCCR_PM_CKRNEN;
++ switch (ohci->num_ports) {
++ default:
++ dev_err(&dev->dev, "Unsupported amount of ports: %d\n", ohci->num_ports);
++ case 3:
++ pm |= UHCCR_PM_USBPW3;
++ case 2:
++ pm |= UHCCR_PM_USBPW2;
++ case 1:
++ pm |= UHCCR_PM_USBPW1;
++ }
+ iowrite8(0, &ccr->intc);
+ iowrite8(0, &ccr->ilme);
+ iowrite16(0, &ccr->basel);
+ iowrite16(0, &ccr->baseh);
+- iowrite16(pm, &ccr->pm);
++ iowrite16(pm, &ccr->pm);
+
+ cell->disable(dev);
+ }
+
+ static void tmio_start_hc(struct platform_device *dev)
+ {
+- struct mfd_cell *cell = mfd_get_cell(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+ struct tmio_uhccr __iomem *ccr = tmio->ccr;
+- u16 pm;
+ unsigned long base = hcd->rsrc_start;
+
+- pm = UHCCR_PM_CKRNEN | UHCCR_PM_GKEN | UHCCR_PM_PMEE | UHCCR_PM_PMES;
+- cell->enable(dev);
+-
+- iowrite16(pm, &ccr->pm);
++ tmio_write_pm(dev);
+ iowrite16(base, &ccr->basel);
+ iowrite16(base >> 16, &ccr->baseh);
+ iowrite8(1, &ccr->ilme);
+@@ -133,9 +188,56 @@ static void tmio_start_hc(struct platform_device *dev)
+ ioread8(&ccr->revid), hcd->rsrc_start, hcd->irq);
+ }
+
++static ssize_t tmio_disabled_port_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ int index = to_indexed_dev_attr(attr)->index;
++ return snprintf(buf, PAGE_SIZE, "%c",
++ tmio->disabled_ports[index-1]? 'Y': 'N');
++}
++
++static ssize_t tmio_disabled_port_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ int index = to_indexed_dev_attr(attr)->index;
++
++ if (!count)
++ return -EINVAL;
++
++ switch (buf[0]) {
++ case 'y': case 'Y': case '1':
++ tmio->disabled_ports[index-1] = true;
++ break;
++ case 'n': case 'N': case '0':
++ tmio->disabled_ports[index-1] = false;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ tmio_write_pm(to_platform_device(dev));
++
++ return 1;
++}
++
++
++static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR,
++ tmio_disabled_port_show, tmio_disabled_port_store, 1);
++static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR,
++ tmio_disabled_port_show, tmio_disabled_port_store, 2);
++static INDEXED_DEVICE_ATTR(disabled_usb_port, S_IRUGO | S_IWUSR,
++ tmio_disabled_port_show, tmio_disabled_port_store, 3);
++
+ static int usb_hcd_tmio_probe(const struct hc_driver *driver,
+ struct platform_device *dev)
+ {
++ struct mfd_cell *cell = mfd_get_cell(dev);
+ struct resource *config = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONFIG);
+ struct resource *regs = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_CONTROL);
+ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM);
+@@ -159,6 +261,12 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver,
+
+ tmio = hcd_to_tmio(hcd);
+
++ spin_lock_init(&tmio->lock);
++
++ memcpy(tmio->disabled_ports,
++ disabled_tmio_ports,
++ sizeof(disabled_tmio_ports));
++
+ tmio->ccr = ioremap(config->start, config->end - config->start + 1);
+ if (!tmio->ccr) {
+ retval = -ENOMEM;
+@@ -183,17 +291,46 @@ static int usb_hcd_tmio_probe(const struct hc_driver *driver,
+ if (retval)
+ goto err_dmabounce_register_dev;
+
++ retval = cell->enable(dev);
++ if (retval)
++ goto err_enable;
++
+ tmio_start_hc(dev);
+ ohci = hcd_to_ohci(hcd);
+ ohci_hcd_init(ohci);
+
+ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
++ if (retval)
++ goto err_add_hcd;
++
++ switch (ohci->num_ports) {
++ default:
++ dev_err(&dev->dev, "Unsupported amount of ports: %d\n",
++ ohci->num_ports);
++ case 3:
++ retval |= device_create_file(&dev->dev,
++ &dev_attr_disabled_usb_port3.dev_attr);
++ case 2:
++ retval |= device_create_file(&dev->dev,
++ &dev_attr_disabled_usb_port2.dev_attr);
++ case 1:
++ retval |= device_create_file(&dev->dev,
++ &dev_attr_disabled_usb_port1.dev_attr);
++ }
+
+ if (retval == 0)
+ return retval;
+
+- tmio_stop_hc(dev);
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr);
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr);
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr);
++
++ usb_remove_hcd(hcd);
+
++err_add_hcd:
++ tmio_stop_hc(dev);
++ cell->disable(dev);
++err_enable:
+ dmabounce_unregister_dev(&dev->dev);
+ err_dmabounce_register_dev:
+ dma_release_declared_memory(&dev->dev);
+@@ -212,6 +349,9 @@ static void usb_hcd_tmio_remove(struct usb_hcd *hcd, struct platform_device *dev
+ {
+ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port3.dev_attr);
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port2.dev_attr);
++ device_remove_file(&dev->dev, &dev_attr_disabled_usb_port1.dev_attr);
+ usb_remove_hcd(hcd);
+ tmio_stop_hc(dev);
+ dmabounce_unregister_dev(&dev->dev);
+@@ -297,13 +437,22 @@ static u64 dma_mask = DMA_32BIT_MASK;
+ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)
+ {
+ struct resource *sram = platform_get_resource_byname(dev, IORESOURCE_MEM, TMIO_OHCI_SRAM);
++ int retval;
+
+ dev->dev.dma_mask = &dma_mask;
+ dev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
++ /* FIXME: move dmabounce checkers to tc6393xb core? */
+ dmabounce_register_checker(tmio_dmabounce_check, sram);
+
+- return usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev);
++ retval = usb_hcd_tmio_probe(&ohci_tmio_hc_driver, dev);
++
++ if (retval == 0)
++ return retval;
++
++ dmabounce_remove_checker(tmio_dmabounce_check, sram);
++
++ return retval;
+ }
+
+ static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
+@@ -323,14 +472,31 @@ static int ohci_hcd_tmio_drv_remove(struct platform_device *dev)
+ #ifdef CONFIG_PM
+ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
+ {
++ struct mfd_cell *cell = mfd_get_cell(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ struct tmio_uhccr __iomem *ccr = tmio->ccr;
++ unsigned long flags;
++ u8 misc;
++ int ret;
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+- tmio_stop_hc(dev);
++ spin_lock_irqsave(&tmio->lock, flags);
++
++ misc = ioread8(&ccr->misc);
++ misc |= 1 << 3; /* USSUSP */
++ iowrite8(misc, &ccr->misc);
++
++ spin_unlock_irqrestore(&tmio->lock, flags);
++
++ ret = cell->suspend(dev);
++ if (ret)
++ return ret;
++
+ hcd->state = HC_STATE_SUSPENDED;
+ dev->dev.power.power_state = PMSG_SUSPEND;
+
+@@ -339,15 +505,33 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s
+
+ static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
+ {
++ struct mfd_cell *cell = mfd_get_cell(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(dev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++ struct tmio_hcd *tmio = hcd_to_tmio(hcd);
++ struct tmio_uhccr __iomem *ccr = tmio->ccr;
++ unsigned long flags;
++ u8 misc;
++ int ret;
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
++ ret = cell->resume(dev);
++ if (ret)
++ return ret;
++
+ tmio_start_hc(dev);
+
++ spin_lock_irqsave(&tmio->lock, flags);
++
++ misc = ioread8(&ccr->misc);
++ misc &= ~(1 << 3); /* USSUSP */
++ iowrite8(misc, &ccr->misc);
++
++ spin_unlock_irqrestore(&tmio->lock, flags);
++
+ dev->dev.power.power_state = PMSG_ON;
+ usb_hcd_resume_root_hub(hcd);
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch b/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch
new file mode 100644
index 0000000000..c4b57cb2d1
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0046-patch-tc6393xb-cleanup.patch
@@ -0,0 +1,66 @@
+From edaab7ec86235871d8ad219a1d225ce12f67f8af Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:13:29 +0300
+Subject: [PATCH 46/64] patch tc6393xb-cleanup
+
+---
+ drivers/mfd/tc6393xb.c | 20 ++++++++++++--------
+ 1 files changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+index 5d17687..dfae61d 100644
+--- a/drivers/mfd/tc6393xb.c
++++ b/drivers/mfd/tc6393xb.c
+@@ -590,16 +590,8 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume)
+ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- int ret;
+ int i;
+
+- if (resume)
+- ret = tcpd->resume(dev);
+- else
+- ret = tcpd->enable(dev);
+- if (ret)
+- return ret;
+-
+ iowrite8(resume ?
+ tc6393xb->suspend_state.fer.raw :
+ 0, &scr->fer);
+@@ -664,6 +656,10 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
+ goto err_ioremap;
+ }
+
++ retval = tcpd->enable(dev);
++ if (retval)
++ goto err_enable;
++
+ retval = tc6393xb_hw_init(dev, 0);
+ if (retval)
+ goto err_hw_init;
+@@ -690,6 +686,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
+ tc6393xb_detach_irq(dev);
+
+ err_hw_init:
++ tcpd->disable(dev);
++err_enable:
+ iounmap(tc6393xb->scr);
+ err_ioremap:
+ release_resource(rscr);
+@@ -743,6 +741,12 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
+
+ static int tc6393xb_resume(struct platform_device *dev)
+ {
++ struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
++ int ret = tcpd->resume(dev);
++
++ if (ret)
++ return ret;
++
+ return tc6393xb_hw_init(dev, 1);
+ }
+ #else
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch b/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch
new file mode 100644
index 0000000000..54e88253d1
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch
@@ -0,0 +1,412 @@
+From c18b8e34c39ec0d395988318e6651076a748d6bd Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Tue, 12 Feb 2008 04:40:54 +0300
+Subject: [PATCH 47/64] tc6393xb: use bitmasks instead of bit-field structs
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/mfd/tc6393xb.c | 162 ++++++++++++++++++++++++-----------------
+ include/linux/mfd/tc6393xb.h | 63 +++-------------
+ 2 files changed, 107 insertions(+), 118 deletions(-)
+
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+index dfae61d..1a394e4 100644
+--- a/drivers/mfd/tc6393xb.c
++++ b/drivers/mfd/tc6393xb.c
+@@ -24,6 +24,31 @@
+ #include <linux/mfd/tmio.h>
+ #include <linux/mfd/tc6393xb.h>
+
++#define TC6393XB_FER_USBEN BIT(0) /* USB host enable */
++#define TC6393XB_FER_LCDCVEN BIT(1) /* polysilicon TFT enable */
++#define TC6393XB_FER_SLCDEN BIT(2) /* SLCD enable */
++
++enum pincontrol {
++ opendrain = 0,
++ tristate = 1,
++ pushpull = 2,
++ /* reserved = 3, */
++};
++
++#define TC6393XB_MCR_RDY_MASK (3 << 0)
++#define TC6393XB_MCR_RDY_OPENDRAIN (0 << 0)
++#define TC6393XB_MCR_RDY_TRISTATE (1 << 0)
++#define TC6393XB_MCR_RDY_PUSHPULL (2 << 0)
++#define TC6393XB_MCR_RDY_UNK BIT(2)
++#define TC6393XB_MCR_RDY_EN BIT(3)
++#define TC6393XB_MCR_INT_MASK (3 << 4)
++#define TC6393XB_MCR_INT_OPENDRAIN (0 << 4)
++#define TC6393XB_MCR_INT_TRISTATE (1 << 4)
++#define TC6393XB_MCR_INT_PUSHPULL (2 << 4)
++#define TC6393XB_MCR_INT_UNK BIT(6)
++#define TC6393XB_MCR_INT_EN BIT(7)
++/* bits 8 - 16 are unknown */
++
+ struct tc6393xb_scr {
+ u8 x00[8];
+ u8 revid; /* 0x08 Revision ID */
+@@ -74,8 +99,8 @@ struct tc6393xb {
+ spinlock_t lock; /* protects RMW cycles */
+
+ struct {
+- union tc6393xb_scr_fer fer;
+- union tc6393xb_scr_ccr ccr;
++ u8 fer;
++ u16 ccr;
+ u8 gpi_bcr[4];
+ } suspend_state;
+
+@@ -90,13 +115,13 @@ static int tc6393xb_mmc_enable(struct platform_device *mmc) {
+ struct platform_device *dev = to_platform_device(mmc->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.ck32ken = 1;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr |= TC6393XB_CCR_CK32K;
++ iowrite16(ccr, &scr->ccr);
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+@@ -106,13 +131,13 @@ static int tc6393xb_mmc_disable(struct platform_device *mmc) {
+ struct platform_device *dev = to_platform_device(mmc->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.ck32ken = 0;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr &= ~TC6393XB_CCR_CK32K;
++ iowrite16(ccr, &scr->ccr);
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+@@ -148,14 +173,17 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_fer fer;
++ u8 fer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- fer.raw = ioread8(&scr->fer);
+- fer.bits.slcden = on ? 1 : 0;
+- iowrite8(fer.raw, &scr->fer);
++ fer = ioread8(&scr->fer);
++ if (on)
++ fer |= TC6393XB_FER_SLCDEN;
++ else
++ fer &= ~TC6393XB_FER_SLCDEN;
++ iowrite8(fer, &scr->fer);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -181,19 +209,19 @@ static int tc6393xb_ohci_disable(struct platform_device *ohci)
+ struct platform_device *dev = to_platform_device(ohci->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
+- union tc6393xb_scr_fer fer;
++ u16 ccr;
++ u8 fer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- fer.raw = ioread8(&scr->fer);
+- fer.bits.usben = 0;
+- iowrite8(fer.raw, &scr->fer);
++ fer = ioread8(&scr->fer);
++ fer &= ~TC6393XB_FER_USBEN;
++ iowrite8(fer, &scr->fer);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.usbcken = 0;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr &= ~TC6393XB_CCR_USBCK;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -205,19 +233,19 @@ static int tc6393xb_ohci_enable(struct platform_device *ohci)
+ struct platform_device *dev = to_platform_device(ohci->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
+- union tc6393xb_scr_fer fer;
++ u16 ccr;
++ u8 fer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.usbcken = 1;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr |= TC6393XB_CCR_USBCK;
++ iowrite16(ccr, &scr->ccr);
+
+- fer.raw = ioread8(&scr->fer);
+- fer.bits.usben = 1;
+- iowrite8(fer.raw, &scr->fer);
++ fer = ioread8(&scr->fer);
++ fer |= TC6393XB_FER_USBEN;
++ iowrite8(fer, &scr->fer);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -229,14 +257,14 @@ static int tc6393xb_ohci_suspend(struct platform_device *ohci)
+ struct platform_device *dev = to_platform_device(ohci->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.usbcken = 0;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr &= ~TC6393XB_CCR_USBCK;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -248,14 +276,14 @@ static int tc6393xb_ohci_resume(struct platform_device *ohci)
+ struct platform_device *dev = to_platform_device(ohci->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.usbcken = 1;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr |= TC6393XB_CCR_USBCK;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -267,8 +295,8 @@ static int tc6393xb_fb_disable(struct platform_device *fb)
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
+- union tc6393xb_scr_fer fer;
++ u16 ccr;
++ u8 fer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+@@ -276,14 +304,13 @@ static int tc6393xb_fb_disable(struct platform_device *fb)
+ /*
+ * FIXME: is this correct or it should be moved to other _disable?
+ */
+- fer.raw = ioread8(&scr->fer);
+- fer.bits.slcden = 0;
+-/* fer.bits.lcdcven = 0; */
+- iowrite8(fer.raw, &scr->fer);
++ fer = ioread8(&scr->fer);
++ fer &= ~TC6393XB_FER_SLCDEN;
++ iowrite8(fer, &scr->fer);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.mclksel = disable;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_OFF;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -295,14 +322,14 @@ static int tc6393xb_fb_enable(struct platform_device *fb)
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.mclksel = m48MHz;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_48;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -314,14 +341,14 @@ static int tc6393xb_fb_suspend(struct platform_device *fb)
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.mclksel = disable;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_OFF;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -333,14 +360,14 @@ static int tc6393xb_fb_resume(struct platform_device *fb)
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+- union tc6393xb_scr_ccr ccr;
++ u16 ccr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+- ccr.raw = ioread16(&scr->ccr);
+- ccr.bits.mclksel = m48MHz;
+- iowrite16(ccr.raw, &scr->ccr);
++ ccr = ioread16(&scr->ccr);
++ ccr = (ccr & ~TC6393XB_CCR_MCLK_MASK) | TC6393XB_CCR_MCLK_48;
++ iowrite16(ccr, &scr->ccr);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+@@ -592,14 +619,15 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume)
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+ int i;
+
+- iowrite8(resume ?
+- tc6393xb->suspend_state.fer.raw :
+- 0, &scr->fer);
++ iowrite8(resume ? tc6393xb->suspend_state.fer : 0,
++ &scr->fer);
+ iowrite16(tcpd->scr_pll2cr, &scr->pll2cr);
+ iowrite16(resume?
+- tc6393xb->suspend_state.ccr.raw :
+- tcpd->scr_ccr.raw, &scr->ccr);
+- iowrite16(tcpd->scr_mcr.raw, &scr->mcr);
++ tc6393xb->suspend_state.ccr :
++ tcpd->scr_ccr, &scr->ccr);
++ iowrite16(TC6393XB_MCR_RDY_OPENDRAIN | TC6393XB_MCR_RDY_UNK | TC6393XB_MCR_RDY_EN |
++ TC6393XB_MCR_INT_OPENDRAIN | TC6393XB_MCR_INT_UNK | TC6393XB_MCR_INT_EN |
++ BIT(15), &scr->mcr);
+ iowrite16(tcpd->scr_gper, &scr->gper);
+ iowrite8(0, &scr->irr);
+ iowrite8(0xbf, &scr->imr);
+@@ -730,8 +758,8 @@ static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
+ int i;
+
+
+- tc6393xb->suspend_state.ccr.raw = ioread16(&scr->ccr);
+- tc6393xb->suspend_state.fer.raw = ioread8(&scr->fer);
++ tc6393xb->suspend_state.ccr = ioread16(&scr->ccr);
++ tc6393xb->suspend_state.fer = ioread8(&scr->fer);
+ for (i = 0; i < 4; i++)
+ tc6393xb->suspend_state.gpi_bcr[i] =
+ ioread8(scr->gpi_bcr + i);
+diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
+index e699294..2c69f63 100644
+--- a/include/linux/mfd/tc6393xb.h
++++ b/include/linux/mfd/tc6393xb.h
+@@ -20,60 +20,21 @@
+ #include <linux/mfd-core.h>
+ #include <linux/mfd/tmio.h>
+
+-union tc6393xb_scr_fer {
+- u8 raw;
+-struct {
+- unsigned usben:1; /* D0 USB enable */
+- unsigned lcdcven:1; /* D1 polysylicon TFT enable */
+- unsigned slcden:1; /* D2 SLCD enable */
+-} __attribute__ ((packed)) bits;
+-} __attribute__ ((packed));
+-
+-union tc6393xb_scr_ccr {
+- u16 raw;
+-struct {
+- unsigned ck32ken:1; /* D0 SD host clock enable */
+- unsigned usbcken:1; /* D1 USB host clock enable */
+- unsigned x00:2;
+- unsigned sharp:1; /* D4 ??? set in Sharp's code */
+- unsigned x01:3;
+- enum { disable = 0,
+- m12MHz = 1,
+- m24MHz = 2,
+- m48MHz = 3,
+- } mclksel:3; /* D10-D8 LCD controller clock */
+- unsigned x02:1;
+- enum { h24MHz = 0,
+- h48MHz = 1,
+- } hclksel:2; /* D13-D12 host bus clock */
+- unsigned x03:2;
+-} __attribute__ ((packed)) bits;
+-} __attribute__ ((packed));
+-
+-enum pincontrol {
+- opendrain = 0,
+- tristate = 1,
+- pushpull = 2,
+- /* reserved = 3, */
+-};
+-
+-union tc6393xb_scr_mcr {
+- u16 raw;
+-struct {
+- enum pincontrol rdyst:2; /* D1-D0 HRDY control */
+- unsigned x00:1;
+- unsigned aren:1; /* D3 HRDY pull up resistance cut off */
+- enum pincontrol intst:2; /* D5-D4 #HINT control */
+- unsigned x01:1;
+- unsigned aien:1; /* D7 #HINT pull up resitance cut off */
+- unsigned x02:8;
+-} __attribute__ ((packed)) bits;
+-} __attribute__ ((packed));
++#define TC6393XB_CCR_CK32K BIT(0)
++#define TC6393XB_CCR_USBCK BIT(1)
++#define TC6393XB_CCR_UNK1 BIT(4)
++#define TC6393XB_CCR_MCLK_MASK (7 << 8)
++#define TC6393XB_CCR_MCLK_OFF (0 << 8)
++#define TC6393XB_CCR_MCLK_12 (1 << 8)
++#define TC6393XB_CCR_MCLK_24 (2 << 8)
++#define TC6393XB_CCR_MCLK_48 (3 << 8)
++#define TC6393XB_CCR_HCLK_MASK (3 << 12)
++#define TC6393XB_CCR_HCLK_24 (0 << 12)
++#define TC6393XB_CCR_HCLK_48 (1 << 12)
+
+ struct tc6393xb_platform_data {
+ u16 scr_pll2cr; /* PLL2 Control */
+- union tc6393xb_scr_ccr scr_ccr; /* Clock Control */
+- union tc6393xb_scr_mcr scr_mcr; /* Mode Control */
++ u16 scr_ccr; /* Clock Control */
+ u16 scr_gper; /* GP Enable */
+ u32 scr_gpo_doecr; /* GPO Data OE Control */
+ u32 scr_gpo_dsr; /* GPO Data Set */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch
new file mode 100644
index 0000000000..ef47d6cc21
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0048-tc6393xb-GPIO-support.patch
@@ -0,0 +1,225 @@
+From 4fb4d83c7090ea21619bb652f2ea9b5c8c0c453e Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 01:42:58 +0300
+Subject: [PATCH 48/64] tc6393xb GPIO support
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/mfd/tc6393xb.c | 124 ++++++++++++++++++++++++++++++++++++++++--
+ include/linux/mfd/tc6393xb.h | 2 +-
+ 2 files changed, 119 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+index 1a394e4..9001687 100644
+--- a/drivers/mfd/tc6393xb.c
++++ b/drivers/mfd/tc6393xb.c
+@@ -49,6 +49,8 @@ enum pincontrol {
+ #define TC6393XB_MCR_INT_EN BIT(7)
+ /* bits 8 - 16 are unknown */
+
++#include <asm/gpio.h>
++
+ struct tc6393xb_scr {
+ u8 x00[8];
+ u8 revid; /* 0x08 Revision ID */
+@@ -96,6 +98,8 @@ struct tc6393xb_scr {
+ struct tc6393xb {
+ struct tc6393xb_scr __iomem *scr;
+
++ struct gpio_chip gpio;
++
+ spinlock_t lock; /* protects RMW cycles */
+
+ struct {
+@@ -513,6 +517,96 @@ static struct mfd_cell tc6393xb_cells[] = {
+
+ /*--------------------------------------------------------------------------*/
+
++static int tc6393xb_gpio_get(struct gpio_chip *chip,
++ unsigned offset)
++{
++ struct tc6393xb *tc6393xb = container_of(chip,
++ struct tc6393xb, gpio);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ u32 mask = 1 << offset;
++
++ return tmio_ioread32(scr->gpo_dsr) & mask;
++}
++
++static void __tc6393xb_gpio_set(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct tc6393xb *tc6393xb = container_of(chip,
++ struct tc6393xb, gpio);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ u32 dsr;
++
++ dsr = tmio_ioread32(scr->gpo_dsr);
++ if (value)
++ dsr |= (1L << offset);
++ else
++ dsr &= ~(1L << offset);
++
++ tmio_iowrite32(dsr, scr->gpo_dsr);
++}
++
++static void tc6393xb_gpio_set(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct tc6393xb *tc6393xb = container_of(chip,
++ struct tc6393xb, gpio);
++ unsigned long flags;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ __tc6393xb_gpio_set(chip, offset, value);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++}
++
++static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
++ unsigned offset)
++{
++ struct tc6393xb *tc6393xb = container_of(chip,
++ struct tc6393xb, gpio);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned long flags;
++ u32 doecr;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ doecr = tmio_ioread32(scr->gpo_doecr);
++
++ doecr &= ~(1 << offset);
++
++ tmio_iowrite32(doecr, scr->gpo_doecr);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct tc6393xb *tc6393xb = container_of(chip,
++ struct tc6393xb, gpio);
++ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
++ unsigned long flags;
++ u32 doecr;
++
++ spin_lock_irqsave(&tc6393xb->lock, flags);
++
++ doecr = tmio_ioread32(scr->gpo_doecr);
++
++ doecr |= (1 << offset);
++
++ tmio_iowrite32(doecr, scr->gpo_doecr);
++
++ __tc6393xb_gpio_set(chip, offset, value);
++
++ spin_unlock_irqrestore(&tc6393xb->lock, flags);
++
++ return 0;
++}
++
++/*--------------------------------------------------------------------------*/
++
+ static void
+ tc6393xb_irq(unsigned int irq, struct irq_desc *desc)
+ {
+@@ -631,10 +725,8 @@ static int tc6393xb_hw_init(struct platform_device *dev, int resume)
+ iowrite16(tcpd->scr_gper, &scr->gper);
+ iowrite8(0, &scr->irr);
+ iowrite8(0xbf, &scr->imr);
+- iowrite16(tcpd->scr_gpo_dsr, scr->gpo_dsr + 0);
+- iowrite16(tcpd->scr_gpo_dsr >> 16, scr->gpo_dsr + 1);
+- iowrite16(tcpd->scr_gpo_doecr, scr->gpo_doecr + 0);
+- iowrite16(tcpd->scr_gpo_doecr >> 16, scr->gpo_doecr + 1);
++ tmio_iowrite32(tcpd->scr_gpo_dsr, &scr->gpo_dsr);
++ tmio_iowrite32(tcpd->scr_gpo_doecr, &scr->gpo_doecr);
+
+ if (resume)
+ for (i = 0; i < 4; i++)
+@@ -650,7 +742,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
+ struct tc6393xb *tc6393xb;
+ struct resource *iomem;
+ struct resource *rscr;
+- int retval;
++ int retval, temp;
+
+ iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!iomem)
+@@ -696,6 +788,18 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
+ ioread8(&tc6393xb->scr->revid),
+ (unsigned long) iomem->start, tc6393xb->irq);
+
++ tc6393xb->gpio.label = "tc6393xb";
++ tc6393xb->gpio.base = tcpd->gpio_base;
++ tc6393xb->gpio.ngpio = 16; /* FIXME: actually 32, but I'm not sure */
++ tc6393xb->gpio.set = tc6393xb_gpio_set;
++ tc6393xb->gpio.get = tc6393xb_gpio_get;
++ tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
++ tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
++
++ retval = gpiochip_add(&tc6393xb->gpio);
++ if (retval)
++ goto err_gpio_add;
++
+ if (tc6393xb->irq)
+ tc6393xb_attach_irq(dev);
+
+@@ -713,6 +817,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
+ if (tc6393xb->irq)
+ tc6393xb_detach_irq(dev);
+
++err_gpio_add:
++ temp = gpiochip_remove(&tc6393xb->gpio);
+ err_hw_init:
+ tcpd->disable(dev);
+ err_enable:
+@@ -734,6 +840,12 @@ static int __devexit tc6393xb_remove(struct platform_device *dev) {
+ if (tc6393xb->irq)
+ tc6393xb_detach_irq(dev);
+
++ ret = gpiochip_remove(&tc6393xb->gpio);
++ if (ret) {
++ dev_err(&dev->dev, "Can't remove gpio chip: %d\n", ret);
++ return ret;
++ }
++
+ ret = tcpd->disable(dev);
+
+ iounmap(tc6393xb->scr);
+@@ -804,7 +916,7 @@ static void __exit tc6393xb_exit(void)
+ platform_driver_unregister(&tc6393xb_driver);
+ }
+
+-module_init(tc6393xb_init);
++subsys_initcall(tc6393xb_init);
+ module_exit(tc6393xb_exit);
+
+ MODULE_LICENSE("GPL");
+diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
+index 2c69f63..97c4c7c 100644
+--- a/include/linux/mfd/tc6393xb.h
++++ b/include/linux/mfd/tc6393xb.h
+@@ -45,6 +45,7 @@ struct tc6393xb_platform_data {
+ int (*resume)(struct platform_device *dev);
+
+ int irq_base; /* a base for cascaded irq */
++ int gpio_base;
+
+ struct tmio_nand_data *nand_data;
+ struct tmio_fb_data *fb_data;
+@@ -54,7 +55,6 @@ extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on);
+ extern int tc6393xb_lcd_mode(struct platform_device *fb_dev,
+ struct fb_videomode *mode);
+
+-
+ /*
+ * Relative to irq_base
+ */
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch b/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch
new file mode 100644
index 0000000000..ff1186cb71
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0049-platform-support-for-TMIO-on-tosa.patch
@@ -0,0 +1,373 @@
+From 30588bdd5c5cdd9fbe269643f582862a76f09efb Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Tue, 12 Feb 2008 04:52:48 +0300
+Subject: [PATCH 49/64] platform support for TMIO on tosa
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 179 ++++++++++++++++++++++++++++++++++++++-
+ include/asm-arm/arch-pxa/irqs.h | 1 +
+ include/asm-arm/arch-pxa/tosa.h | 45 ++++++++--
+ sound/soc/pxa/tosa.c | 3 +-
+ 4 files changed, 216 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 5268e94..e2eec0f 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -18,7 +18,13 @@
+ #include <linux/major.h>
+ #include <linux/fs.h>
+ #include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
+ #include <linux/mmc/host.h>
++#include <linux/mfd/tc6393xb.h>
++#include <linux/mfd/tmio.h>
++#include <linux/mtd/nand.h>
++#include <linux/mtd/partitions.h>
+ #include <linux/pm.h>
+ #include <linux/delay.h>
+ #include <linux/gpio_keys.h>
+@@ -298,12 +304,183 @@ static struct platform_device tosaled_device = {
+ .id = -1,
+ };
+
++/*
++ * Toshiba Mobile IO Controller
++ */
++static struct resource tc6393xb_resources[] = {
++ [0] = {
++ .start = TOSA_LCDC_PHYS,
++ .end = TOSA_LCDC_PHYS + 0x3ffffff,
++ .flags = IORESOURCE_MEM,
++ },
++
++ [1] = {
++ .start = TOSA_IRQ_GPIO_TC6393XB_INT,
++ .end = TOSA_IRQ_GPIO_TC6393XB_INT,
++ .flags = IORESOURCE_IRQ,
++ },
++};
++
++
++static int tosa_tc6393xb_enable(struct platform_device *dev)
++{
++
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND);
++ reset_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */
++ pxa_gpio_mode(GPIO11_3_6MHz_MD);
++ pxa_gpio_mode(GPIO18_RDY_MD);
++ mdelay(1);
++ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND);
++ mdelay(10);
++ set_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */
++ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++
++ return 0;
++}
++
++static int tosa_tc6393xb_disable(struct platform_device *dev)
++{
++
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND);
++ reset_scoop_gpio(&tosascoop_device.dev, TOSA_SCOOP_TC6393XB_REST_IN); /* #PCLR */
++ pxa_gpio_mode(GPIO11_3_6MHz_MD|GPIO_OUT);
++ GPSR0 = GPIO_bit(GPIO11_3_6MHz);
++
++ return 0;
++}
++
++static int tosa_tc6393xb_resume(struct platform_device *dev)
++{
++
++ pxa_gpio_mode(GPIO11_3_6MHz_MD);
++ pxa_gpio_mode(GPIO18_RDY_MD);
++ mdelay(1);
++ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND);
++ mdelay(10);
++ set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++ mdelay(10);
++
++ return 0;
++}
++
++static int tosa_tc6393xb_suspend(struct platform_device *dev)
++{
++
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++ reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_TC6393XB_SUSPEND);
++ pxa_gpio_mode(GPIO11_3_6MHz_MD|GPIO_OUT);
++ GPSR0 = GPIO_bit(GPIO11_3_6MHz);
++
++ return 0;
++}
++
++static struct mtd_partition tosa_nand_partition[] = {
++ {
++ .name = "smf",
++ .offset = 0,
++ .size = 7 * 1024 * 1024,
++ },
++ {
++ .name = "root",
++ .offset = MTDPART_OFS_APPEND,
++ .size = 28 * 1024 * 1024,
++ },
++ {
++ .name = "home",
++ .offset = MTDPART_OFS_APPEND,
++ .size = MTDPART_SIZ_FULL,
++ },
++};
++
++static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
++
++static struct nand_bbt_descr tosa_tc6393xb_nand_bbt = {
++ .options = 0,
++ .offs = 4,
++ .len = 2,
++ .pattern = scan_ff_pattern
++};
++
++static struct tmio_nand_data tosa_tc6393xb_nand_config = {
++ .num_partitions = ARRAY_SIZE(tosa_nand_partition),
++ .partition = tosa_nand_partition,
++ .badblock_pattern = &tosa_tc6393xb_nand_bbt,
++};
++
++static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
++ {
++ .xres = 480,
++ .yres = 640,
++ .pixclock = 0x002cdf00,/* PLL divisor */
++ .left_margin = 0x004c,
++ .right_margin = 0x005b,
++ .upper_margin = 0x0001,
++ .lower_margin = 0x000d,
++ .hsync_len = 0x0002,
++ .vsync_len = 0x0001,
++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ .vmode = FB_VMODE_NONINTERLACED,
++ },{
++ .xres = 240,
++ .yres = 320,
++ .pixclock = 0x00e7f203,/* PLL divisor */
++ .left_margin = 0x0024,
++ .right_margin = 0x002f,
++ .upper_margin = 0x0001,
++ .lower_margin = 0x000d,
++ .hsync_len = 0x0002,
++ .vsync_len = 0x0001,
++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
++ .vmode = FB_VMODE_NONINTERLACED,
++ }
++};
++
++static struct tmio_fb_data tosa_tc6393xb_fb_config = {
++ .lcd_set_power = tc6393xb_lcd_set_power,
++ .lcd_mode = tc6393xb_lcd_mode,
++ .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode),
++ .modes = &tosa_tc6393xb_lcd_mode[0],
++};
++
++static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
++ .scr_pll2cr = 0x0cc1,
++ .scr_ccr = TC6393XB_CCR_UNK1 | TC6393XB_CCR_HCLK_48,
++ .scr_gper = 0x3300,
++ .scr_gpo_dsr = TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF_JC,
++ .scr_gpo_doecr = TOSA_TC6393XB_GPO_OE,
++
++ .irq_base = IRQ_BOARD_START,
++
++ .enable = tosa_tc6393xb_enable,
++ .disable = tosa_tc6393xb_disable,
++ .suspend = tosa_tc6393xb_suspend,
++ .resume = tosa_tc6393xb_resume,
++
++ .nand_data = &tosa_tc6393xb_nand_config,
++ .fb_data = &tosa_tc6393xb_fb_config,
++};
++
++
++struct platform_device tc6393xb_device = {
++ .name = "tc6393xb",
++ .id = -1,
++ .dev = {
++ .platform_data = &tosa_tc6393xb_setup,
++ },
++ .num_resources = ARRAY_SIZE(tc6393xb_resources),
++ .resource = tc6393xb_resources,
++};
++EXPORT_SYMBOL(tc6393xb_device);
++
+ static struct platform_device *devices[] __initdata = {
+ &tosascoop_device,
+ &tosascoop_jc_device,
+ &tosakbd_device,
+ &tosa_gpio_keys_device,
+ &tosaled_device,
++ &tc6393xb_device,
+ };
+
+ static void tosa_poweroff(void)
+@@ -332,7 +509,7 @@ static void __init tosa_init(void)
+ arm_pm_restart = tosa_restart;
+
+ pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
+- pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_TC6393XB_INT | GPIO_IN);
+ pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
+
+ /* setup sleep mode values */
+diff --git a/include/asm-arm/arch-pxa/irqs.h b/include/asm-arm/arch-pxa/irqs.h
+index b76ee6d..bf622d8 100644
+--- a/include/asm-arm/arch-pxa/irqs.h
++++ b/include/asm-arm/arch-pxa/irqs.h
+@@ -180,6 +180,7 @@
+ #define NR_IRQS (IRQ_LOCOMO_SPI_TEND + 1)
+ #elif defined(CONFIG_ARCH_LUBBOCK) || \
+ defined(CONFIG_MACH_LOGICPD_PXA270) || \
++ defined(CONFIG_MACH_TOSA) || \
+ defined(CONFIG_MACH_MAINSTONE)
+ #define NR_IRQS (IRQ_BOARD_END)
+ #else
+diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
+index c05e4fa..1b202b2 100644
+--- a/include/asm-arm/arch-pxa/tosa.h
++++ b/include/asm-arm/arch-pxa/tosa.h
+@@ -20,11 +20,35 @@
+ /* Jacket Scoop */
+ #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+
++#define TC6393XB_GPIO(i) (1 << (i))
++/*
++ * TC6393 GPIOs
++ */
++#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0)
++#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1)
++#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3)
++#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4)
++#define TOSA_TC6393XB_CHARGE_OFF TC6393XB_GPIO(6)
++#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7)
++#define TOSA_TC6393XB_BAT0_V_ON TC6393XB_GPIO(9)
++#define TOSA_TC6393XB_BAT1_V_ON TC6393XB_GPIO(10)
++#define TOSA_TC6393XB_BU_CHRG_ON TC6393XB_GPIO(11)
++#define TOSA_TC6393XB_BAT_SW_ON TC6393XB_GPIO(12)
++#define TOSA_TC6393XB_BAT0_TH_ON TC6393XB_GPIO(14)
++#define TOSA_TC6393XB_BAT1_TH_ON TC6393XB_GPIO(15)
++
++#define TOSA_TC6393XB_GPO_OE (TOSA_TC6393XB_TG_ON | TOSA_TC6393XB_L_MUTE | TOSA_TC6393XB_BL_C20MA | \
++ TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF | \
++ TOSA_TC6393XB_CHARGE_OFF_JC | TOSA_TC6393XB_BAT0_V_ON | \
++ TOSA_TC6393XB_BAT1_V_ON | TOSA_TC6393XB_BU_CHRG_ON | \
++ TOSA_TC6393XB_BAT_SW_ON | TOSA_TC6393XB_BAT0_TH_ON | \
++ TOSA_TC6393XB_BAT1_TH_ON)
++
+ /*
+ * SCOOP2 internal GPIOs
+ */
+ #define TOSA_SCOOP_PXA_VCORE1 SCOOP_GPCR_PA11
+-#define TOSA_SCOOP_TC6393_REST_IN SCOOP_GPCR_PA12
++#define TOSA_SCOOP_TC6393XB_REST_IN SCOOP_GPCR_PA12
+ #define TOSA_SCOOP_IR_POWERDWN SCOOP_GPCR_PA13
+ #define TOSA_SCOOP_SD_WP SCOOP_GPCR_PA14
+ #define TOSA_SCOOP_PWR_ON SCOOP_GPCR_PA15
+@@ -34,11 +58,11 @@
+ #define TOSA_SCOOP_AC_IN_OL SCOOP_GPCR_PA19
+
+ /* GPIO Direction 1 : output mode / 0:input mode */
+-#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393_REST_IN | \
++#define TOSA_SCOOP_IO_DIR ( TOSA_SCOOP_PXA_VCORE1 | TOSA_SCOOP_TC6393XB_REST_IN | \
+ TOSA_SCOOP_IR_POWERDWN | TOSA_SCOOP_PWR_ON | TOSA_SCOOP_AUD_PWR_ON |\
+ TOSA_SCOOP_BT_RESET | TOSA_SCOOP_BT_PWR_EN )
+ /* GPIO out put level when init 1: Hi */
+-#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393_REST_IN )
++#define TOSA_SCOOP_IO_OUT ( TOSA_SCOOP_TC6393XB_REST_IN )
+
+ /*
+ * SCOOP2 jacket GPIOs
+@@ -47,8 +71,8 @@
+ #define TOSA_SCOOP_JC_NOTE_LED SCOOP_GPCR_PA12
+ #define TOSA_SCOOP_JC_CHRG_ERR_LED SCOOP_GPCR_PA13
+ #define TOSA_SCOOP_JC_USB_PULLUP SCOOP_GPCR_PA14
+-#define TOSA_SCOOP_JC_TC6393_SUSPEND SCOOP_GPCR_PA15
+-#define TOSA_SCOOP_JC_TC3693_L3V_ON SCOOP_GPCR_PA16
++#define TOSA_SCOOP_JC_TC6393XB_SUSPEND SCOOP_GPCR_PA15
++#define TOSA_SCOOP_JC_TC6393XB_L3V_ON SCOOP_GPCR_PA16
+ #define TOSA_SCOOP_JC_WLAN_DETECT SCOOP_GPCR_PA17
+ #define TOSA_SCOOP_JC_WLAN_LED SCOOP_GPCR_PA18
+ #define TOSA_SCOOP_JC_CARD_LIMIT_SEL SCOOP_GPCR_PA19
+@@ -56,7 +80,7 @@
+ /* GPIO Direction 1 : output mode / 0:input mode */
+ #define TOSA_SCOOP_JC_IO_DIR ( TOSA_SCOOP_JC_BT_LED | TOSA_SCOOP_JC_NOTE_LED | \
+ TOSA_SCOOP_JC_CHRG_ERR_LED | TOSA_SCOOP_JC_USB_PULLUP | \
+- TOSA_SCOOP_JC_TC6393_SUSPEND | TOSA_SCOOP_JC_TC3693_L3V_ON | \
++ TOSA_SCOOP_JC_TC6393XB_SUSPEND | TOSA_SCOOP_JC_TC6393XB_L3V_ON | \
+ TOSA_SCOOP_JC_WLAN_LED | TOSA_SCOOP_JC_CARD_LIMIT_SEL )
+ /* GPIO out put level when init 1: Hi */
+ #define TOSA_SCOOP_JC_IO_OUT ( 0 )
+@@ -94,13 +118,13 @@
+ #define TOSA_GPIO_JACKET_DETECT (7)
+ #define TOSA_GPIO_nSD_DETECT (9)
+ #define TOSA_GPIO_nSD_INT (10)
+-#define TOSA_GPIO_TC6393_CLK (11)
++#define TOSA_GPIO_TC6393XB_CLK (11)
+ #define TOSA_GPIO_BAT1_CRG (12)
+ #define TOSA_GPIO_CF_CD (13)
+ #define TOSA_GPIO_BAT0_CRG (14)
+-#define TOSA_GPIO_TC6393_INT (15)
++#define TOSA_GPIO_TC6393XB_INT (15)
+ #define TOSA_GPIO_BAT0_LOW (17)
+-#define TOSA_GPIO_TC6393_RDY (18)
++#define TOSA_GPIO_TC6393XB_RDY (18)
+ #define TOSA_GPIO_ON_RESET (19)
+ #define TOSA_GPIO_EAR_IN (20)
+ #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */
+@@ -147,7 +171,7 @@
+ #define TOSA_IRQ_GPIO_BAT1_CRG IRQ_GPIO(TOSA_GPIO_BAT1_CRG)
+ #define TOSA_IRQ_GPIO_CF_CD IRQ_GPIO(TOSA_GPIO_CF_CD)
+ #define TOSA_IRQ_GPIO_BAT0_CRG IRQ_GPIO(TOSA_GPIO_BAT0_CRG)
+-#define TOSA_IRQ_GPIO_TC6393_INT IRQ_GPIO(TOSA_GPIO_TC6393_INT)
++#define TOSA_IRQ_GPIO_TC6393XB_INT IRQ_GPIO(TOSA_GPIO_TC6393XB_INT)
+ #define TOSA_IRQ_GPIO_BAT0_LOW IRQ_GPIO(TOSA_GPIO_BAT0_LOW)
+ #define TOSA_IRQ_GPIO_EAR_IN IRQ_GPIO(TOSA_GPIO_EAR_IN)
+ #define TOSA_IRQ_GPIO_CF_IRQ IRQ_GPIO(TOSA_GPIO_CF_IRQ)
+@@ -161,6 +185,7 @@
+
+ #define TOSA_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(TOSA_GPIO_MAIN_BAT_LOW)
+
++extern struct platform_device tc6393xb_device;
+ extern struct platform_device tosascoop_jc_device;
+ extern struct platform_device tosascoop_device;
+
+diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
+index 5504e30..21c51b5 100644
+--- a/sound/soc/pxa/tosa.c
++++ b/sound/soc/pxa/tosa.c
+@@ -32,7 +32,6 @@
+ #include <sound/soc-dapm.h>
+
+ #include <asm/mach-types.h>
+-#include <asm/hardware/tmio.h>
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/audio.h>
+@@ -138,10 +137,12 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
+ /* tosa dapm event handlers */
+ static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event)
+ {
++#if 0
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
+ else
+ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
++#endif
+ return 0;
+ }
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch b/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch
new file mode 100644
index 0000000000..c9b5ac29d4
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0050-tosa-update-for-tc6393xb-gpio.patch
@@ -0,0 +1,99 @@
+From f24c23ba56cdd072b332e8de3e0cff8a31e7e36a Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:03:19 +0300
+Subject: [PATCH 50/64] tosa update for tc6393xb gpio
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 6 +++++-
+ include/asm-arm/arch-pxa/tosa.h | 36 ++++++++++++++++++++++++------------
+ 2 files changed, 29 insertions(+), 13 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index e2eec0f..3e832dc 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -35,6 +35,7 @@
+ #include <asm/mach-types.h>
+ #include <asm/hardware.h>
+ #include <asm/irq.h>
++#include <asm/gpio.h>
+ #include <asm/system.h>
+ #include <asm/arch/pxa-regs.h>
+ #include <asm/arch/irda.h>
+@@ -448,10 +449,13 @@ static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
+ .scr_pll2cr = 0x0cc1,
+ .scr_ccr = TC6393XB_CCR_UNK1 | TC6393XB_CCR_HCLK_48,
+ .scr_gper = 0x3300,
+- .scr_gpo_dsr = TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF_JC,
++ .scr_gpo_dsr =
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CARD_VCC_ON) |
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF_JC),
+ .scr_gpo_doecr = TOSA_TC6393XB_GPO_OE,
+
+ .irq_base = IRQ_BOARD_START,
++ .gpio_base = TOSA_TC6393XB_GPIO_BASE,
+
+ .enable = tosa_tc6393xb_enable,
+ .disable = tosa_tc6393xb_disable,
+diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
+index 1b202b2..410fa9a 100644
+--- a/include/asm-arm/arch-pxa/tosa.h
++++ b/include/asm-arm/arch-pxa/tosa.h
+@@ -20,16 +20,21 @@
+ /* Jacket Scoop */
+ #define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
+
+-#define TC6393XB_GPIO(i) (1 << (i))
+ /*
+ * TC6393 GPIOs
+ */
+-#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0)
+-#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1)
+-#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3)
+-#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4)
++
++#define TOSA_TC6393XB_GPIO_BASE NR_BUILTIN_GPIO
++
++#define TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i))
++#define TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
++
++#define TOSA_TC6393XB_TG_ON TC6393XB_GPIO(0)
++#define TOSA_TC6393XB_L_MUTE TC6393XB_GPIO(1)
++#define TOSA_TC6393XB_BL_C20MA TC6393XB_GPIO(3)
++#define TOSA_TC6393XB_CARD_VCC_ON TC6393XB_GPIO(4)
+ #define TOSA_TC6393XB_CHARGE_OFF TC6393XB_GPIO(6)
+-#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7)
++#define TOSA_TC6393XB_CHARGE_OFF_JC TC6393XB_GPIO(7)
+ #define TOSA_TC6393XB_BAT0_V_ON TC6393XB_GPIO(9)
+ #define TOSA_TC6393XB_BAT1_V_ON TC6393XB_GPIO(10)
+ #define TOSA_TC6393XB_BU_CHRG_ON TC6393XB_GPIO(11)
+@@ -37,12 +42,19 @@
+ #define TOSA_TC6393XB_BAT0_TH_ON TC6393XB_GPIO(14)
+ #define TOSA_TC6393XB_BAT1_TH_ON TC6393XB_GPIO(15)
+
+-#define TOSA_TC6393XB_GPO_OE (TOSA_TC6393XB_TG_ON | TOSA_TC6393XB_L_MUTE | TOSA_TC6393XB_BL_C20MA | \
+- TOSA_TC6393XB_CARD_VCC_ON | TOSA_TC6393XB_CHARGE_OFF | \
+- TOSA_TC6393XB_CHARGE_OFF_JC | TOSA_TC6393XB_BAT0_V_ON | \
+- TOSA_TC6393XB_BAT1_V_ON | TOSA_TC6393XB_BU_CHRG_ON | \
+- TOSA_TC6393XB_BAT_SW_ON | TOSA_TC6393XB_BAT0_TH_ON | \
+- TOSA_TC6393XB_BAT1_TH_ON)
++#define TOSA_TC6393XB_GPO_OE ( \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_TG_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_L_MUTE) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BL_C20MA) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CARD_VCC_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_CHARGE_OFF_JC) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT0_V_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT1_V_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BU_CHRG_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT_SW_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT0_TH_ON) | \
++ TC6393XB_GPIO_BIT(TOSA_TC6393XB_BAT1_TH_ON))
+
+ /*
+ * SCOOP2 internal GPIOs
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch b/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch
new file mode 100644
index 0000000000..585f1af288
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch
@@ -0,0 +1,86 @@
+From 38ef1b452cc3138157b92d02b31cad439d12d0ca Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:03:34 +0300
+Subject: [PATCH 51/64] fix sound/soc/pxa/tosa.c to new gpio api
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ sound/soc/pxa/tosa.c | 33 ++++++++++++++++++++++++++-------
+ 1 files changed, 26 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
+index 21c51b5..b758de8 100644
+--- a/sound/soc/pxa/tosa.c
++++ b/sound/soc/pxa/tosa.c
+@@ -36,6 +36,7 @@
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/audio.h>
+ #include <asm/arch/tosa.h>
++#include <asm/gpio.h>
+
+ #include "../codecs/wm9712.h"
+ #include "pxa2xx-pcm.h"
+@@ -137,11 +138,11 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
+ /* tosa dapm event handlers */
+ static int tosa_hp_event(struct snd_soc_dapm_widget *w, int event)
+ {
+-#if 0
++#ifdef CONFIG_MFD_TC6393XB
+ if (SND_SOC_DAPM_EVENT_ON(event))
+- set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
++ gpio_set_value(TOSA_TC6393XB_L_MUTE, 1);
+ else
+- reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_L_MUTE);
++ gpio_set_value(TOSA_TC6393XB_L_MUTE, 0);
+ #endif
+ return 0;
+ }
+@@ -262,16 +263,31 @@ static int __init tosa_init(void)
+ if (!machine_is_tosa())
+ return -ENODEV;
+
++#ifdef CONFIG_MFD_TC6393XB
++ ret = gpio_request(TOSA_TC6393XB_L_MUTE, "Headphone Jack");
++ if (ret)
++ return ret;
++ gpio_direction_output(TOSA_TC6393XB_L_MUTE, 0);
++#endif
+ tosa_snd_device = platform_device_alloc("soc-audio", -1);
+- if (!tosa_snd_device)
+- return -ENOMEM;
++ if (!tosa_snd_device) {
++ ret = -ENOMEM;
++ goto err_alloc;
++ }
+
+ platform_set_drvdata(tosa_snd_device, &tosa_snd_devdata);
+ tosa_snd_devdata.dev = &tosa_snd_device->dev;
+ ret = platform_device_add(tosa_snd_device);
+
+- if (ret)
+- platform_device_put(tosa_snd_device);
++ if (!ret)
++ return 0;
++
++ platform_device_put(tosa_snd_device);
++
++err_alloc:
++#ifdef CONFIG_MFD_TC6393XB
++ gpio_free(TOSA_TC6393XB_L_MUTE);
++#endif
+
+ return ret;
+ }
+@@ -279,6 +295,9 @@ static int __init tosa_init(void)
+ static void __exit tosa_exit(void)
+ {
+ platform_device_unregister(tosa_snd_device);
++#ifdef CONFIG_MFD_TC6393XB
++ gpio_free(TOSA_TC6393XB_L_MUTE);
++#endif
+ }
+
+ module_init(tosa_init);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch b/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch
new file mode 100644
index 0000000000..ef5263c18e
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0052-tosa-platform-backlight-support.patch
@@ -0,0 +1,400 @@
+From c7537657bc33d4ee1616accd0259e160d57c5c1b Mon Sep 17 00:00:00 2001
+From: Ian Molton <spyro@f2s.com>
+Date: Wed, 9 Jan 2008 02:05:40 +0300
+Subject: [PATCH 52/64] tosa platform backlight support
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/video/backlight/Kconfig | 10 +
+ drivers/video/backlight/Makefile | 1 +
+ drivers/video/backlight/tosa_bl.c | 345 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 356 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/video/backlight/tosa_bl.c
+
+diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
+index 9609a6c..f47a601 100644
+--- a/drivers/video/backlight/Kconfig
++++ b/drivers/video/backlight/Kconfig
+@@ -59,6 +59,16 @@ config BACKLIGHT_CORGI
+ known as the Corgi backlight driver. If you have a Sharp Zaurus
+ SL-C7xx, SL-Cxx00 or SL-6000x say y. Most users can say n.
+
++config BACKLIGHT_TOSA
++ tristate "Sharp Tosa LCD/Backlight Driver (SL-6000)"
++ depends on BACKLIGHT_CLASS_DEVICE && MACH_TOSA
++ default y
++ select I2C
++ select I2C_PXA
++ select PXA_SSP
++ help
++ If you have a Sharp Zaurus SL-6000y enable this driver.
++
+ config BACKLIGHT_LOCOMO
+ tristate "Sharp LOCOMO LCD/Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE && SHARP_LOCOMO
+diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
+index 965a78b..e8a6a7c 100644
+--- a/drivers/video/backlight/Makefile
++++ b/drivers/video/backlight/Makefile
+@@ -5,6 +5,7 @@ obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
+
+ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
+ obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
++obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
+ obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
+ obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+ obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
+diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
+new file mode 100644
+index 0000000..11a89c6
+--- /dev/null
++++ b/drivers/video/backlight/tosa_bl.c
+@@ -0,0 +1,345 @@
++/*
++ * LCD / Backlight control code for Sharp SL-6000x (tosa)
++ *
++ * Copyright (c) 2005 Dirk Opfer
++ * Copyright (c) 2007 Dmitry Baryshkov
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/i2c.h>
++#include <linux/backlight.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/mfd/tc6393xb.h>
++
++#include <asm/hardware/scoop.h>
++#include <asm/mach/sharpsl_param.h>
++#include <asm/arch/ssp.h>
++#include <asm/arch/pxa-regs.h>
++#include <asm/arch/tosa.h>
++#include <asm/gpio.h>
++
++#define DAC_BASE 0x4e
++#define DAC_CH1 0
++#define DAC_CH2 1
++
++#define TG_REG0_VQV 0x0001
++#define TG_REG0_COLOR 0x0002
++#define TG_REG0_UD 0x0004
++#define TG_REG0_LR 0x0008
++#define COMADJ_DEFAULT 97
++
++static unsigned short normal_i2c[] = { DAC_BASE, I2C_CLIENT_END };
++I2C_CLIENT_INSMOD;
++
++struct tosa_bl_data {
++ struct i2c_client client;
++
++ int comadj;
++ spinlock_t nssp_lock;
++ struct ssp_dev nssp_dev;
++ struct ssp_state nssp_state;
++
++ struct backlight_device *bl_dev;
++};
++
++static struct i2c_driver tosa_bl_driver;
++
++static void pxa_nssp_output(struct tosa_bl_data *data, unsigned char reg, unsigned char value)
++{
++ unsigned long flag;
++ u32 dummy;
++ u32 dat = ( ((reg << 5) & 0xe0) | (value & 0x1f) );
++ spin_lock_irqsave(&data->nssp_lock, flag);
++
++ ssp_config(&data->nssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(128));
++ ssp_enable(&data->nssp_dev);
++
++ ssp_write_word(&data->nssp_dev,dat);
++
++ /* Read null data back from device to prevent SSP overflow */
++ ssp_read_word(&data->nssp_dev, &dummy);
++ ssp_disable(&data->nssp_dev);
++ spin_unlock_irqrestore(&data->nssp_lock, flag);
++
++}
++
++static void tosa_set_backlight(struct tosa_bl_data *data, int brightness)
++{
++ /* SetBacklightDuty */
++ i2c_smbus_write_byte_data(&data->client, DAC_CH2, (unsigned char)brightness);
++
++ /* SetBacklightVR */
++ if (brightness)
++ gpio_set_value(TOSA_TC6393XB_BL_C20MA, 1);
++ else
++ gpio_set_value(TOSA_TC6393XB_BL_C20MA, 0);
++
++ /* bl_enable GP04=1 otherwise GP04=0*/
++ pxa_nssp_output(data, TG_GPODR2, brightness ? 0x01 : 0x00);
++}
++
++static void tosa_lcd_tg_init(struct tosa_bl_data *data)
++{
++ dev_dbg(&data->bl_dev->dev, "tosa_lcd_init\n");
++
++ /* L3V On */
++ set_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++ mdelay(60);
++
++ /* TG On */
++ gpio_set_value(TOSA_TC6393XB_TG_ON, 0);
++ mdelay(60);
++
++ pxa_nssp_output(data, TG_TPOSCTL,0x00); /* delayed 0clk TCTL signal for VGA */
++ pxa_nssp_output(data, TG_GPOSR,0x02); /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
++}
++
++static void tosa_lcd_tg_on(struct tosa_bl_data *data/*, const struct fb_videomode *mode*/)
++{
++ const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
++
++ tosa_lcd_tg_init(data);
++
++ dev_dbg(&data->bl_dev->dev, "tosa_lcd_on\n");
++ pxa_nssp_output(data, TG_PNLCTL, value | (/*mode->yres == 320 ? 0 : */ TG_REG0_VQV));
++
++ /* TG LCD pannel power up */
++ pxa_nssp_output(data, TG_PINICTL,0x4);
++ mdelay(50);
++
++ /* TG LCD GVSS */
++ pxa_nssp_output(data, TG_PINICTL,0x0);
++ mdelay(50);
++
++ /* set common voltage */
++ i2c_smbus_write_byte_data(&data->client, DAC_CH1, data->comadj);
++}
++
++static void tosa_lcd_tg_off(struct tosa_bl_data *data)
++{
++ tosa_set_backlight(data, 0);
++ dev_dbg(&data->bl_dev->dev, "tosa_lcd_off\n");
++ /* TG LCD VHSA off */
++ pxa_nssp_output(data, TG_PINICTL,0x4);
++ mdelay(50);
++
++ /* TG LCD signal off */
++ pxa_nssp_output(data, TG_PINICTL,0x6);
++ mdelay(50);
++
++ /* TG Off */
++ gpio_set_value(TOSA_TC6393XB_TG_ON, 1);
++ mdelay(100);
++
++ /* L3V Off */
++ reset_scoop_gpio( &tosascoop_jc_device.dev,TOSA_SCOOP_JC_TC6393XB_L3V_ON);
++}
++
++
++static int tosa_bl_update_status(struct backlight_device *dev)
++{
++ struct backlight_properties *props = &dev->props;
++ struct tosa_bl_data *data = dev_get_drvdata(&dev->dev);
++ int new_power = max(props->power, props->fb_blank);
++
++ tosa_set_backlight(data, props->brightness);
++
++ if (new_power)
++ tosa_lcd_tg_off(data);
++ else
++ tosa_lcd_tg_on(data);
++
++ return 0;
++}
++
++static int tosa_bl_get_brightness(struct backlight_device *dev)
++{
++ struct backlight_properties *props = &dev->props;
++
++ return props->brightness;
++}
++
++static struct backlight_ops tosa_bl_ops = {
++ .get_brightness = tosa_bl_get_brightness,
++ .update_status = tosa_bl_update_status,
++};
++
++static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address,
++ int kind)
++{
++ int err = 0;
++ struct i2c_client *client;
++ struct tosa_bl_data *data;
++
++ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA ))
++ goto out;
++
++ if (!(data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL))) {
++ err = -ENOMEM;
++ goto out;
++ }
++
++ client = &data->client;
++ i2c_set_clientdata(client, data);
++
++ client->addr = address;
++ client->adapter = adapter;
++ client->driver = &tosa_bl_driver;
++
++ strlcpy(client->name, "tosa_bl", I2C_NAME_SIZE);
++
++ spin_lock_init(&data->nssp_lock);
++ data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
++
++ err = gpio_request(TOSA_TC6393XB_BL_C20MA, "backlight");
++ if (err) {
++ dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n");
++ goto err_gpio_bl;
++ }
++
++ err = gpio_request(TOSA_TC6393XB_TG_ON, "tg");
++ if (err) {
++ dev_dbg(&data->bl_dev->dev, "Unable to request gpio!\n");
++ goto err_gpio_tg;
++ }
++
++ err = ssp_init(&data->nssp_dev,2,0);
++ if (err) {
++ dev_err(&data->bl_dev->dev, "Unable to register NSSP handler!\n");
++ goto err_ssp_init;
++ }
++
++ /* Tell the i2c layer a new client has arrived */
++ err = i2c_attach_client(client);
++ if (err)
++ goto err_i2c_attach;
++
++ gpio_direction_output(TOSA_TC6393XB_BL_C20MA, 0);
++ gpio_direction_output(TOSA_TC6393XB_TG_ON, 1);
++
++ tosa_lcd_tg_init(data);
++
++ data->bl_dev = backlight_device_register("tosa_bl",
++ &client->dev, data, &tosa_bl_ops);
++ if (err)
++ goto err_bl_register;
++
++ data->bl_dev->props.brightness = 69;
++ data->bl_dev->props.max_brightness = 255;
++ data->bl_dev->props.power = FB_BLANK_UNBLANK;
++ backlight_update_status(data->bl_dev);
++
++
++ return 0;
++
++err_bl_register:
++ tosa_set_backlight(data, 0);
++ tosa_lcd_tg_off(data);
++
++ err = i2c_detach_client(client);
++ if (err)
++ return err;
++err_i2c_attach:
++ ssp_exit(&data->nssp_dev);
++err_ssp_init:
++ gpio_free(TOSA_TC6393XB_TG_ON);
++err_gpio_tg:
++ gpio_free(TOSA_TC6393XB_BL_C20MA);
++err_gpio_bl:
++ kfree(data);
++out:
++ return err;
++}
++
++static int tosa_bl_detach_client(struct i2c_client *client)
++{
++ int err = 0;
++ struct tosa_bl_data *data = i2c_get_clientdata(client);
++
++ backlight_device_unregister(data->bl_dev);
++
++ tosa_set_backlight(data, 0);
++ tosa_lcd_tg_off(data);
++
++ /* Try to detach the client from i2c space */
++ if ((err = i2c_detach_client(client)))
++ return err;
++
++ ssp_exit(&data->nssp_dev);
++
++ gpio_free(TOSA_TC6393XB_TG_ON);
++ gpio_free(TOSA_TC6393XB_BL_C20MA);
++
++ kfree(data);
++
++ return err;
++}
++
++#ifdef CONFIG_PM
++static int tosa_bl_suspend(struct i2c_client *client, pm_message_t mesg)
++{
++ struct tosa_bl_data *data = i2c_get_clientdata(client);
++
++ tosa_lcd_tg_off(data);
++ ssp_flush(&data->nssp_dev);
++ ssp_save_state(&data->nssp_dev,&data->nssp_state);
++
++ return 0;
++}
++
++static int tosa_bl_resume(struct i2c_client *client)
++{
++ struct tosa_bl_data *data = i2c_get_clientdata(client);
++
++ ssp_restore_state(&data->nssp_dev,&data->nssp_state);
++ ssp_enable(&data->nssp_dev);
++ tosa_bl_update_status(data->bl_dev);
++
++ return 0;
++}
++#else
++#define tosa_bl_suspend NULL
++#define tosa_bl_resume NULL
++#endif
++
++static int tosa_bl_attach_adapter(struct i2c_adapter *adapter)
++{
++ return i2c_probe(adapter, &addr_data, &tosa_bl_detect_client);
++}
++
++static struct i2c_driver tosa_bl_driver = {
++ .driver = {
++ .name = "tosa_bl",
++ },
++
++ .attach_adapter = tosa_bl_attach_adapter,
++ .detach_client = tosa_bl_detach_client,
++
++ .suspend = tosa_bl_suspend,
++ .resume = tosa_bl_resume,
++};
++
++static int __init tosa_bl_init(void)
++{
++ return i2c_add_driver(&tosa_bl_driver);
++}
++
++static void __exit tosa_bl_cleanup (void)
++{
++ i2c_del_driver(&tosa_bl_driver);
++}
++
++module_init(tosa_bl_init);
++module_exit(tosa_bl_cleanup);
++
++MODULE_DESCRIPTION("Tosa LCD device");
++MODULE_AUTHOR("Dirk Opfer, Dmitry Baryshkov");
++MODULE_LICENSE("GPL v2");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch b/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch
new file mode 100644
index 0000000000..0675342508
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0053-sound-soc-codecs-wm9712.c-28.patch
@@ -0,0 +1,56 @@
+From 47616d22f8f303dfd66cf3b9125af212194a0f3c Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 9 Jan 2008 02:08:17 +0300
+Subject: [PATCH 53/64] sound/soc/codecs/wm9712.c | 28 ++++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+Index: git/sound/soc/codecs/wm9712.c
+===================================================================
+---
+ sound/soc/codecs/wm9712.c | 28 ++++++++++++++++++----------
+ 1 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
+index 986b5d5..dfb31e1 100644
+--- a/sound/soc/codecs/wm9712.c
++++ b/sound/soc/codecs/wm9712.c
+@@ -606,18 +606,26 @@ static int wm9712_dapm_event(struct snd_soc_codec *codec, int event)
+
+ static int wm9712_reset(struct snd_soc_codec *codec, int try_warm)
+ {
+- if (try_warm && soc_ac97_ops.warm_reset) {
+- soc_ac97_ops.warm_reset(codec->ac97);
+- if (!(ac97_read(codec, 0) & 0x8000))
+- return 1;
+- }
++ int retry = 3;
+
+- soc_ac97_ops.reset(codec->ac97);
+- if (ac97_read(codec, 0) & 0x8000)
+- goto err;
+- return 0;
++ while (retry--)
++ {
++ if(try_warm && soc_ac97_ops.warm_reset) {
++ soc_ac97_ops.warm_reset(codec->ac97);
++ if(ac97_read(codec, 0) & 0x8000)
++ continue;
++ else
++ return 1;
++ }
++
++ soc_ac97_ops.reset(codec->ac97);
++ if(ac97_read(codec, 0) & 0x8000)
++ continue;
++ else
++ return 0;
++
++ }
+
+-err:
+ printk(KERN_ERR "WM9712 AC97 reset failed\n");
+ return -EIO;
+ }
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch b/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch
new file mode 100644
index 0000000000..be7300ab24
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0054-sound-soc-codecs-wm9712.c-2.patch
@@ -0,0 +1,28 @@
+From 08fbae2307163b3f0c3b704c4b00a9447752a45e Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Thu, 10 Jan 2008 17:56:58 +0300
+Subject: [PATCH 54/64] sound/soc/codecs/wm9712.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: git/sound/soc/codecs/wm9712.c
+===================================================================
+---
+ sound/soc/codecs/wm9712.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
+index dfb31e1..a3d9f96 100644
+--- a/sound/soc/codecs/wm9712.c
++++ b/sound/soc/codecs/wm9712.c
+@@ -647,7 +647,7 @@ static int wm9712_soc_resume(struct platform_device *pdev)
+ int i, ret;
+ u16 *cache = codec->reg_cache;
+
+- ret = wm9712_reset(codec, 1);
++ ret = wm9712_reset(codec, 0);
+ if (ret < 0){
+ printk(KERN_ERR "could not reset AC97 codec\n");
+ return ret;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch b/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch
new file mode 100644
index 0000000000..5bf691cbda
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch
@@ -0,0 +1,30 @@
+From bee8b808445a53a7dbb6c15a27064f14dec410c5 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 20 Jan 2008 03:01:41 +0300
+Subject: [PATCH 55/64] Add GPIO_POWERON to the list of devices that we support resume on.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 3e832dc..d1cf3dc 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -517,9 +517,9 @@ static void __init tosa_init(void)
+ pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
+
+ /* setup sleep mode values */
+- PWER = 0x00000002;
+- PFER = 0x00000000;
+- PRER = 0x00000002;
++ PWER = BIT(TOSA_GPIO_POWERON) | BIT(TOSA_GPIO_RESET);
++ PFER = 0;
++ PRER = BIT(TOSA_GPIO_POWERON) | BIT(TOSA_GPIO_RESET);
+ PGSR0 = 0x00000000;
+ PGSR1 = 0x00FF0002;
+ PGSR2 = 0x00014000;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch b/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch
new file mode 100644
index 0000000000..99220f9200
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch
@@ -0,0 +1,126 @@
+From e039614a0ce6df645f8fa4cbe32e4b21fe46a288 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 20 Jan 2008 02:44:03 +0300
+Subject: [PATCH 56/64] Support resetting by asserting GPIO pin
+
+This adds support for resetting via assertion of GPIO pin.
+This e.g. is used on Sharp Zaurus SL-6000.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/gpio.c | 43 +++++++++++++++++++++++++++++++++++++
+ arch/arm/mach-pxa/pm.c | 4 +-
+ include/asm-arm/arch-pxa/system.h | 10 ++++++++
+ 3 files changed, 55 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
+index 8638dd7..589da3b 100644
+--- a/arch/arm/mach-pxa/gpio.c
++++ b/arch/arm/mach-pxa/gpio.c
+@@ -19,6 +19,7 @@
+ #include <asm/hardware.h>
+ #include <asm/io.h>
+ #include <asm/arch/pxa-regs.h>
++#include <asm/arch/system.h>
+
+ #include "generic.h"
+
+@@ -194,4 +195,46 @@ void __init pxa_init_gpio(int gpio_nr)
+ pxa_gpio_chip[i/32].chip.ngpio = gpio_nr - i;
+ gpiochip_add(&pxa_gpio_chip[i/32].chip);
+ }
++
++ if (reset_gpio < gpio_nr)
++ init_reset_gpio();
++}
++
++int reset_gpio = -1;
++static int __init reset_gpio_setup(char *str)
++{
++ if (get_option(&str, &reset_gpio) != 1) {
++ printk(KERN_ERR "reset_gpio: bad value secified");
++ return 0;
++ }
++
++ return 1;
++}
++
++__setup("reset_gpio=", reset_gpio_setup);
++
++int init_reset_gpio(void)
++{
++ int rc = 0;
++ if (reset_gpio == -1)
++ goto out;
++
++ rc = gpio_request(reset_gpio, "reset generator");
++ if (rc) {
++ printk(KERN_ERR "Can't request reset_gpio\n");
++ goto out;
++ }
++
++ rc = gpio_direction_input(reset_gpio);
++ if (rc) {
++ printk(KERN_ERR "Can't configure reset_gpio for input\n");
++ gpio_free(reset_gpio);
++ goto out;
++ }
++
++out:
++ if (rc)
++ reset_gpio = -1;
++
++ return rc;
+ }
+diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
+index a941c71..64f37e5 100644
+--- a/arch/arm/mach-pxa/pm.c
++++ b/arch/arm/mach-pxa/pm.c
+@@ -40,8 +40,8 @@ int pxa_pm_enter(suspend_state_t state)
+
+ pxa_cpu_pm_fns->save(sleep_save);
+
+- /* Clear sleep reset status */
+- RCSR = RCSR_SMR;
++ /* Clear reset status */
++ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+
+ /* before sleeping, calculate and save a checksum */
+ for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
+diff --git a/include/asm-arm/arch-pxa/system.h b/include/asm-arm/arch-pxa/system.h
+index 1d56a3e..c075018 100644
+--- a/include/asm-arm/arch-pxa/system.h
++++ b/include/asm-arm/arch-pxa/system.h
+@@ -11,6 +11,7 @@
+ */
+
+ #include <asm/proc-fns.h>
++#include <asm/gpio.h>
+ #include "hardware.h"
+ #include "pxa-regs.h"
+
+@@ -19,12 +20,21 @@ static inline void arch_idle(void)
+ cpu_do_idle();
+ }
+
++extern int reset_gpio;
++
++int init_reset_gpio(void);
+
+ static inline void arch_reset(char mode)
+ {
++ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
++
+ if (mode == 's') {
+ /* Jump into ROM at address 0 */
+ cpu_reset(0);
++ } else if (mode == 'g' && reset_gpio != -1) {
++ /* Use GPIO reset */
++ gpio_direction_output(reset_gpio, 0);
++ gpio_set_value(reset_gpio, 1);
+ } else {
+ /* Initialize the watchdog and let it fire */
+ OWER = OWER_WME;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch b/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch
new file mode 100644
index 0000000000..441e1bba75
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0057-Clean-up-tosa-resetting.patch
@@ -0,0 +1,70 @@
+From a6f03929fa4d20cef339dbed7ef5cd1e040d0548 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 20 Jan 2008 02:48:07 +0300
+Subject: [PATCH 57/64] Clean up tosa resetting
+
+Use new gpio-assertion reset.
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 16 +++++++---------
+ 1 files changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index d1cf3dc..2b4aef7 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -41,6 +41,8 @@
+ #include <asm/arch/irda.h>
+ #include <asm/arch/mmc.h>
+ #include <asm/arch/udc.h>
++#include <asm/arch/pm.h>
++#include <asm/arch/system.h>
+
+ #include <asm/mach/arch.h>
+ #include <asm/mach/map.h>
+@@ -489,13 +491,7 @@ static struct platform_device *devices[] __initdata = {
+
+ static void tosa_poweroff(void)
+ {
+- RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
+-
+- pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT);
+- GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET);
+-
+- mdelay(1000);
+- arm_machine_restart('h');
++ arm_machine_restart('g');
+ }
+
+ static void tosa_restart(char mode)
+@@ -504,7 +500,7 @@ static void tosa_restart(char mode)
+ if((MSC0 & 0xffff0000) == 0x7ff00000)
+ MSC0 = (MSC0 & 0xffff) | 0x7ee00000;
+
+- tosa_poweroff();
++ arm_machine_restart('g');
+ }
+
+ static void __init tosa_init(void)
+@@ -512,7 +508,6 @@ static void __init tosa_init(void)
+ pm_power_off = tosa_poweroff;
+ arm_pm_restart = tosa_restart;
+
+- pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN);
+ pxa_gpio_mode(TOSA_GPIO_TC6393XB_INT | GPIO_IN);
+ pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN);
+
+@@ -544,6 +539,9 @@ static void __init fixup_tosa(struct machine_desc *desc,
+ mi->bank[0].start = 0xa0000000;
+ mi->bank[0].node = 0;
+ mi->bank[0].size = (64*1024*1024);
++
++ if (reset_gpio == -1)
++ reset_gpio = TOSA_GPIO_ON_RESET;
+ }
+
+ MACHINE_START(TOSA, "SHARP Tosa")
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch b/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch
new file mode 100644
index 0000000000..e965857dff
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0058-Fix-tosakbd-suspend.patch
@@ -0,0 +1,27 @@
+From 8b57c409802e5feef64c4bb7659570e06558c0f2 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 20 Jan 2008 02:24:43 +0300
+Subject: [PATCH 58/64] Fix tosakbd suspend
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/input/keyboard/tosakbd.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/input/keyboard/tosakbd.c b/drivers/input/keyboard/tosakbd.c
+index 3884d1e..306cbe8 100644
+--- a/drivers/input/keyboard/tosakbd.c
++++ b/drivers/input/keyboard/tosakbd.c
+@@ -210,6 +210,9 @@ static int tosakbd_suspend(struct platform_device *dev, pm_message_t state)
+
+ del_timer_sync(&tosakbd->timer);
+
++ PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT);
++ PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT);
++
+ return 0;
+ }
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch b/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch
new file mode 100644
index 0000000000..812b5bad41
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0059-patch-tosa-wakeup-test.patch
@@ -0,0 +1,46 @@
+From 00f6e9b946d1f653fc776d71c86a1f6a7534cd1d Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Fri, 25 Jan 2008 19:16:20 +0300
+Subject: [PATCH 59/64] patch tosa-wakeup-test
+
+---
+ arch/arm/mach-pxa/tosa.c | 18 +++++++++++++++++-
+ 1 files changed, 17 insertions(+), 1 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 2b4aef7..7008919 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -260,12 +260,28 @@ static struct platform_device tosakbd_device = {
+ };
+
+ static struct gpio_keys_button tosa_gpio_keys[] = {
++ /*
++ * Two following keys are directly tied to "ON" button of tosa. Why?
++ * The first one can be used as a wakeup source, the second can't:
++ * it's outside of permitted area.
++ */
++ {
++ .type = EV_PWR,
++ .code = KEY_RESERVED,
++ .gpio = TOSA_GPIO_POWERON,
++ .desc = "Poweron",
++ .wakeup = 1,
++ .active_low = 1,
++ },
+ {
+ .type = EV_PWR,
+ .code = KEY_SUSPEND,
+ .gpio = TOSA_GPIO_ON_KEY,
+ .desc = "On key",
+- .wakeup = 1,
++ /*
++ * can't be used as wakeup
++ * .wakeup = 1,
++ */
+ .active_low = 1,
+ },
+ {
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch b/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch
new file mode 100644
index 0000000000..f7420de040
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0060-Add-support-for-power_supply-on-tosa.patch
@@ -0,0 +1,623 @@
+From f6ec15733eb55e851c8ad19c2143d425558f6044 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Mon, 4 Feb 2008 20:11:58 +0300
+Subject: [PATCH 60/64] Add support for power_supply on tosa
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/Makefile | 2 +-
+ arch/arm/mach-pxa/tosa_power.c | 82 +++++++
+ drivers/leds/leds-tosa.c | 2 +-
+ drivers/power/Kconfig | 7 +
+ drivers/power/Makefile | 1 +
+ drivers/power/tosa_battery.c | 458 ++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 550 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/mach-pxa/tosa_power.c
+ create mode 100644 drivers/power/tosa_battery.c
+
+diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
+index f276d24..2b68254 100644
+--- a/arch/arm/mach-pxa/Makefile
++++ b/arch/arm/mach-pxa/Makefile
+@@ -21,7 +21,7 @@ obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o cor
+ obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
+ obj-$(CONFIG_MACH_AKITA) += akita-ioexp.o
+ obj-$(CONFIG_MACH_POODLE) += poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o
+-obj-$(CONFIG_MACH_TOSA) += tosa.o
++obj-$(CONFIG_MACH_TOSA) += tosa.o tosa_power.o
+ obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+
+ ifeq ($(CONFIG_MACH_ZYLONITE),y)
+diff --git a/arch/arm/mach-pxa/tosa_power.c b/arch/arm/mach-pxa/tosa_power.c
+new file mode 100644
+index 0000000..61ca7dc
+--- /dev/null
++++ b/arch/arm/mach-pxa/tosa_power.c
+@@ -0,0 +1,82 @@
++/*
++ * Battery and Power Management code for the Sharp SL-6000x
++ *
++ * Copyright (c) 2005 Dirk Opfer
++ * Copyright (c) 2008 Dmitry Baryshkov
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/power_supply.h>
++#include <linux/pda_power.h>
++#include <linux/platform_device.h>
++#include <linux/interrupt.h>
++
++#include <asm/arch/tosa.h>
++#include <asm/gpio.h>
++
++static int tosa_power_ac_online(void)
++{
++ return gpio_get_value(TOSA_GPIO_AC_IN) == 0;
++}
++
++static char *tosa_ac_supplied_to[] = {
++ "main-battery",
++ "backup-battery",
++ "jacket-battery",
++};
++
++static struct pda_power_pdata tosa_power_data = {
++ .is_ac_online = tosa_power_ac_online,
++ .supplied_to = tosa_ac_supplied_to,
++ .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to),
++};
++
++static struct resource tosa_power_resource[] = {
++ {
++ .name = "ac",
++ .start = gpio_to_irq(TOSA_GPIO_AC_IN),
++ .end = gpio_to_irq(TOSA_GPIO_AC_IN),
++ .flags = IORESOURCE_IRQ |
++ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ },
++};
++
++static struct platform_device tosa_power_device = {
++ .name = "pda-power",
++ .id = -1,
++ .dev.platform_data = &tosa_power_data,
++ .resource = tosa_power_resource,
++ .num_resources = ARRAY_SIZE(tosa_power_resource),
++};
++
++static int __init tosa_power_init(void)
++{
++ int ret = gpio_request(TOSA_GPIO_AC_IN, "ac");
++ if (ret)
++ goto err_gpio_req;
++
++ ret = gpio_direction_input(TOSA_GPIO_AC_IN);
++ if (ret)
++ goto err_gpio_in;
++
++ return platform_device_register(&tosa_power_device);
++
++err_gpio_in:
++ gpio_free(TOSA_GPIO_AC_IN);
++err_gpio_req:
++ return ret;
++}
++
++static void __exit tosa_power_exit(void)
++{
++ platform_device_unregister(&tosa_power_device);
++ gpio_free(TOSA_GPIO_AC_IN);
++}
++
++module_init(tosa_power_init);
++module_exit(tosa_power_exit);
+diff --git a/drivers/leds/leds-tosa.c b/drivers/leds/leds-tosa.c
+index fb2416a..b4498b5 100644
+--- a/drivers/leds/leds-tosa.c
++++ b/drivers/leds/leds-tosa.c
+@@ -46,7 +46,7 @@ static void tosaled_green_set(struct led_classdev *led_cdev,
+
+ static struct led_classdev tosa_amber_led = {
+ .name = "tosa:amber",
+- .default_trigger = "sharpsl-charge",
++ .default_trigger = "main-battery-charging",
+ .brightness_set = tosaled_amber_set,
+ };
+
+diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
+index 58c806e..e3a9c37 100644
+--- a/drivers/power/Kconfig
++++ b/drivers/power/Kconfig
+@@ -49,4 +49,11 @@ config BATTERY_OLPC
+ help
+ Say Y to enable support for the battery on the OLPC laptop.
+
++config BATTERY_TOSA
++ tristate "Sharp SL-6000 (tosa) battery"
++ depends on MACH_TOSA && MFD_TC6393XB
++ help
++ Say Y to enable support for the battery on the Sharp Zaurus
++ SL-6000 (tosa) models.
++
+ endif # POWER_SUPPLY
+diff --git a/drivers/power/Makefile b/drivers/power/Makefile
+index 6413ded..1e408fa 100644
+--- a/drivers/power/Makefile
++++ b/drivers/power/Makefile
+@@ -20,3 +20,4 @@ obj-$(CONFIG_APM_POWER) += apm_power.o
+ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
+ obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
+ obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
++obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
+diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
+new file mode 100644
+index 0000000..b0fd2f2
+--- /dev/null
++++ b/drivers/power/tosa_battery.c
+@@ -0,0 +1,458 @@
++/*
++ * Battery and Power Management code for the Sharp SL-6000x
++ *
++ * Copyright (c) 2005 Dirk Opfer
++ * Copyright (c) 2008 Dmitry Baryshkov
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/power_supply.h>
++#include <linux/wm97xx.h>
++#include <linux/delay.h>
++#include <linux/spinlock.h>
++#include <linux/interrupt.h>
++
++#include <asm/mach-types.h>
++#include <asm/gpio.h>
++#include <asm/arch/tosa.h>
++
++#define BAT_TO_VOLTS(v) ((v) * 1000000 / 414)
++#define BU_TO_VOLTS(v) ((v) * 1000000 / 1266)
++/*
++ * It's pretty strange value, but that's roughly what I get from
++ * zaurus maintainer menu
++ */
++//#define BAT_TO_TEMP(t) ((t) * 10000/2000)
++#define BAT_TO_TEMP(t) (t)
++
++static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
++static struct work_struct bat_work;
++
++struct tosa_bat {
++ int status;
++ struct power_supply psy;
++ int full_chrg;
++
++ struct mutex work_lock; /* protects data */
++ bool (*is_present)(struct tosa_bat *bat);
++ int gpio_full;
++ int gpio_charge_off;
++ int gpio_bat;
++ int adc_bat;
++ int gpio_temp;
++ int adc_temp;
++};
++
++static struct tosa_bat tosa_bat_main;
++static struct tosa_bat tosa_bat_jacket;
++
++static enum power_supply_property tosa_bat_main_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
++ POWER_SUPPLY_PROP_TEMP,
++ POWER_SUPPLY_PROP_PRESENT,
++};
++
++static enum power_supply_property tosa_bat_bu_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
++ POWER_SUPPLY_PROP_PRESENT,
++};
++
++static unsigned long tosa_read_bat(struct tosa_bat *bat)
++{
++ unsigned long value = 0;
++
++ if (bat->gpio_bat < 0 || bat->adc_bat < 0)
++ return 0;
++
++ mutex_lock(&bat_lock);
++ gpio_set_value(bat->gpio_bat, 1);
++ mdelay(5);
++ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_bat);
++ gpio_set_value(bat->gpio_bat, 0);
++ mutex_unlock(&bat_lock);
++ return value;
++}
++
++static unsigned long tosa_read_temp(struct tosa_bat *bat)
++{
++ unsigned long value = 0;
++
++ if (bat->gpio_temp < 0 || bat->adc_temp < 0)
++ return 0;
++
++ mutex_lock(&bat_lock);
++ gpio_set_value(bat->gpio_temp, 1);
++ mdelay(5);
++ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_temp);
++ gpio_set_value(bat->gpio_temp, 0);
++ mutex_unlock(&bat_lock);
++ return value;
++}
++
++static int tosa_bat_get_property(struct power_supply *psy,
++ enum power_supply_property psp,
++ union power_supply_propval *val)
++{
++ int ret = 0;
++ struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy);
++
++ if (bat->is_present && !bat->is_present(bat)
++ && psp != POWER_SUPPLY_PROP_PRESENT) {
++ return -ENODEV;
++ }
++
++ switch (psp) {
++ case POWER_SUPPLY_PROP_STATUS:
++ val->intval = bat->status;
++ break;
++ case POWER_SUPPLY_PROP_TECHNOLOGY:
++ val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
++ val->intval = BAT_TO_VOLTS(tosa_read_bat(bat));
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
++ if (bat->full_chrg == -1)
++ val->intval = -1;
++ else
++ val->intval = BAT_TO_VOLTS(bat->full_chrg);
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
++ val->intval = BAT_TO_VOLTS(1551);
++ break;
++ case POWER_SUPPLY_PROP_TEMP:
++ val->intval = BAT_TO_TEMP(tosa_read_temp(bat));
++ break;
++ case POWER_SUPPLY_PROP_PRESENT:
++ val->intval = bat->is_present ? bat->is_present(bat) : 1;
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++ return ret;
++}
++
++static int tosa_bu_get_property(struct power_supply *psy,
++ enum power_supply_property psp,
++ union power_supply_propval *val)
++{
++ int ret = 0;
++ struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy);
++
++ switch (psp) {
++ case POWER_SUPPLY_PROP_STATUS:
++ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
++ break;
++ case POWER_SUPPLY_PROP_TECHNOLOGY:
++ val->intval = POWER_SUPPLY_TECHNOLOGY_LiMn;
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
++ val->intval = 0;
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
++ val->intval = 3 * 1000000; /* 3 V */
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
++ /* I think so */
++ val->intval = BU_TO_VOLTS(tosa_read_bat(bat));
++ break;
++ case POWER_SUPPLY_PROP_PRESENT:
++ val->intval = 1;
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++ return ret;
++}
++
++static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) {
++ // FIXME
++ return 1;
++}
++
++static void tosa_bat_external_power_changed(struct power_supply *psy)
++{
++ schedule_work(&bat_work);
++}
++
++static irqreturn_t tosa_bat_full_isr(int irq, void *data)
++{
++ printk(KERN_ERR "bat_full irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
++ schedule_work(&bat_work);
++ return IRQ_HANDLED;
++}
++
++static void tosa_bat_update(struct tosa_bat *bat)
++{
++ int old = bat->status;
++ struct power_supply *psy = &bat->psy;
++
++ mutex_lock(&bat->work_lock);
++
++ if (bat->is_present && !bat->is_present(bat)) {
++ printk(KERN_DEBUG "%s not present\n", psy->name);
++ bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
++ bat->full_chrg = -1;
++ } else if (power_supply_am_i_supplied(psy)) {
++ if (gpio_get_value(bat->gpio_full)) {
++ printk(KERN_DEBUG "%s full\n", psy->name);
++
++ if (old == POWER_SUPPLY_STATUS_CHARGING || bat->full_chrg == -1)
++ bat->full_chrg = tosa_read_bat(bat);
++
++ gpio_set_value(bat->gpio_charge_off, 1);
++ bat->status = POWER_SUPPLY_STATUS_FULL;
++ } else {
++ printk(KERN_ERR "%s charge\n", psy->name);
++ gpio_set_value(bat->gpio_charge_off, 0);
++ bat->status = POWER_SUPPLY_STATUS_CHARGING;
++ }
++ } else {
++ printk(KERN_ERR "%s discharge\n", psy->name);
++ gpio_set_value(bat->gpio_charge_off, 1);
++ bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
++ }
++
++ if (old != bat->status)
++ power_supply_changed(psy);
++
++ mutex_unlock(&bat->work_lock);
++}
++
++static void tosa_bat_work(struct work_struct *work)
++{
++ tosa_bat_update(&tosa_bat_main);
++ tosa_bat_update(&tosa_bat_jacket);
++}
++
++
++static struct tosa_bat tosa_bat_main = {
++ .status = POWER_SUPPLY_STATUS_UNKNOWN,
++ .full_chrg = -1,
++ .psy = {
++ .name = "main-battery",
++ .type = POWER_SUPPLY_TYPE_BATTERY,
++ .properties = tosa_bat_main_props,
++ .num_properties = ARRAY_SIZE(tosa_bat_main_props),
++ .get_property = tosa_bat_get_property,
++ .external_power_changed = tosa_bat_external_power_changed,
++ .use_for_apm = 1,
++ },
++
++ .gpio_full = TOSA_GPIO_BAT0_CRG,
++ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF,
++ .gpio_bat = TOSA_TC6393XB_BAT0_V_ON,
++ .adc_bat = WM97XX_AUX_ID3,
++ .gpio_temp = TOSA_TC6393XB_BAT1_TH_ON,
++ .adc_temp = WM97XX_AUX_ID2,
++};
++
++static struct tosa_bat tosa_bat_jacket = {
++ .status = POWER_SUPPLY_STATUS_UNKNOWN,
++ .full_chrg = -1,
++ .psy = {
++ .name = "jacket-battery",
++ .type = POWER_SUPPLY_TYPE_BATTERY,
++ .properties = tosa_bat_main_props,
++ .num_properties = ARRAY_SIZE(tosa_bat_main_props),
++ .get_property = tosa_bat_get_property,
++ .external_power_changed = tosa_bat_external_power_changed,
++// .use_for_apm = 1,
++ },
++
++ .is_present = tosa_jacket_bat_is_present,
++ .gpio_full = TOSA_GPIO_BAT1_CRG,
++ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF_JC,
++ .gpio_bat = TOSA_TC6393XB_BAT1_V_ON,
++ .adc_bat = WM97XX_AUX_ID3,
++ .gpio_temp = TOSA_TC6393XB_BAT0_TH_ON,
++ .adc_temp = WM97XX_AUX_ID2,
++};
++
++static struct tosa_bat tosa_bat_bu = {
++ .status = POWER_SUPPLY_STATUS_UNKNOWN,
++ .full_chrg = -1,
++
++ .psy = {
++ .name = "backup-battery",
++ .type = POWER_SUPPLY_TYPE_BATTERY,
++ .properties = tosa_bat_bu_props,
++ .num_properties = ARRAY_SIZE(tosa_bat_bu_props),
++ .get_property = tosa_bu_get_property,
++ .external_power_changed = tosa_bat_external_power_changed,
++ },
++
++ .gpio_full = -1,
++ .gpio_charge_off = -1,
++ .gpio_bat = TOSA_TC6393XB_BU_CHRG_ON,
++ .adc_bat = WM97XX_AUX_ID4,
++ .gpio_temp = -1,
++ .adc_temp = -1,
++};
++
++static struct {
++ int gpio;
++ char *name;
++ bool output;
++ int value;
++} gpios[] = {
++ { TOSA_TC6393XB_CHARGE_OFF, "main charge off", 1, 1 },
++ { TOSA_TC6393XB_CHARGE_OFF_JC, "jacket charge off", 1, 1 },
++ { TOSA_TC6393XB_BAT_SW_ON, "battery switch", 1, 0 },
++ { TOSA_TC6393XB_BAT0_V_ON, "main battery", 1, 0 },
++ { TOSA_TC6393XB_BAT1_V_ON, "jacket battery", 1, 0 },
++ { TOSA_TC6393XB_BAT1_TH_ON, "main battery temp", 1, 0 },
++ { TOSA_TC6393XB_BAT0_TH_ON, "jacket battery temp", 1, 0 },
++ { TOSA_TC6393XB_BU_CHRG_ON, "backup battery", 1, 0 },
++ { TOSA_GPIO_BAT0_CRG, "main battery full", 0, 0 },
++ { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 },
++ { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 },
++ { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 },
++};
++
++#ifdef CONFIG_PM
++static int tosa_bat_suspend(struct device *dev, pm_message_t state)
++{
++ /* do nothing */
++ return 0;
++}
++
++static int tosa_bat_resume(struct device *dev)
++{
++ schedule_work(&bat_work);
++ return 0;
++}
++#else
++#define tosa_bat_suspend NULL
++#define tosa_bat_resume NULL
++#endif
++
++static int __devinit tosa_bat_probe(struct device *dev)
++{
++ int ret;
++ int i;
++
++ if (!machine_is_tosa())
++ return -ENODEV;
++
++ for (i = 0; i < ARRAY_SIZE(gpios); i++) {
++ ret = gpio_request(gpios[i].gpio, gpios[i].name);
++ if (ret) {
++ i --;
++ goto err_gpio;
++ }
++
++ if (gpios[i].output)
++ ret = gpio_direction_output(gpios[i].gpio,
++ gpios[i].value);
++ else
++ ret = gpio_direction_input(gpios[i].gpio);
++
++ if (ret)
++ goto err_gpio;
++ }
++
++ mutex_init(&tosa_bat_main.work_lock);
++ mutex_init(&tosa_bat_jacket.work_lock);
++
++ INIT_WORK(&bat_work, tosa_bat_work);
++
++ ret = power_supply_register(dev, &tosa_bat_main.psy);
++ if (ret)
++ goto err_psy_reg_main;
++ ret = power_supply_register(dev, &tosa_bat_jacket.psy);
++ if (ret)
++ goto err_psy_reg_jacket;
++ ret = power_supply_register(dev, &tosa_bat_bu.psy);
++ if (ret)
++ goto err_psy_reg_bu;
++
++ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG),
++ tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ "main full", &tosa_bat_main);
++ if (ret)
++ goto err_req_main;
++
++ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG),
++ tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ "jacket full", &tosa_bat_jacket);
++ if (!ret) {
++ schedule_work(&bat_work);
++ return 0;
++ }
++
++ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
++err_req_main:
++ power_supply_unregister(&tosa_bat_bu.psy);
++err_psy_reg_bu:
++ power_supply_unregister(&tosa_bat_jacket.psy);
++err_psy_reg_jacket:
++ power_supply_unregister(&tosa_bat_main.psy);
++err_psy_reg_main:
++
++ i --;
++err_gpio:
++ for (; i >= 0; i --)
++ gpio_free(gpios[i].gpio);
++
++ return ret;
++}
++
++static int __devexit tosa_bat_remove(struct device *dev)
++{
++ int i;
++
++ free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
++ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
++
++ power_supply_unregister(&tosa_bat_bu.psy);
++ power_supply_unregister(&tosa_bat_jacket.psy);
++ power_supply_unregister(&tosa_bat_main.psy);
++
++ for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i --)
++ gpio_free(gpios[i].gpio);
++
++ return 0;
++}
++
++static struct device_driver tosa_bat_driver = {
++ .name = "wm97xx-battery",
++ .bus = &wm97xx_bus_type,
++ .owner = THIS_MODULE,
++ .probe = tosa_bat_probe,
++ .remove = __devexit_p(tosa_bat_remove),
++ .suspend = tosa_bat_suspend,
++ .resume = tosa_bat_resume,
++};
++
++static int __init tosa_bat_init(void)
++{
++ return driver_register(&tosa_bat_driver);
++}
++
++static void __exit tosa_bat_exit(void)
++{
++ driver_unregister(&tosa_bat_driver);
++}
++
++module_init(tosa_bat_init);
++module_exit(tosa_bat_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Dmitry Baryshkov");
++MODULE_DESCRIPTION("Tosa battery driver");
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch b/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch
new file mode 100644
index 0000000000..2bcede36a9
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0061-tosa-bat-unify.patch
@@ -0,0 +1,342 @@
+From f05aa38af5bd5962ae04c4b128644e7f55451527 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Fri, 8 Feb 2008 01:14:48 +0300
+Subject: [PATCH 61/64] tosa-bat-unify
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/power/tosa_battery.c | 161 ++++++++++++++++++++---------------------
+ 1 files changed, 79 insertions(+), 82 deletions(-)
+
+diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
+index b0fd2f2..008e791 100644
+--- a/drivers/power/tosa_battery.c
++++ b/drivers/power/tosa_battery.c
+@@ -21,15 +21,6 @@
+ #include <asm/gpio.h>
+ #include <asm/arch/tosa.h>
+
+-#define BAT_TO_VOLTS(v) ((v) * 1000000 / 414)
+-#define BU_TO_VOLTS(v) ((v) * 1000000 / 1266)
+-/*
+- * It's pretty strange value, but that's roughly what I get from
+- * zaurus maintainer menu
+- */
+-//#define BAT_TO_TEMP(t) ((t) * 10000/2000)
+-#define BAT_TO_TEMP(t) (t)
+-
+ static DEFINE_MUTEX(bat_lock); /* protects gpio pins */
+ static struct work_struct bat_work;
+
+@@ -39,37 +30,27 @@ struct tosa_bat {
+ int full_chrg;
+
+ struct mutex work_lock; /* protects data */
++
+ bool (*is_present)(struct tosa_bat *bat);
+ int gpio_full;
+ int gpio_charge_off;
++
++ int technology;
++
+ int gpio_bat;
+ int adc_bat;
++ int adc_bat_divider;
++ int bat_max;
++ int bat_min;
++
+ int gpio_temp;
+ int adc_temp;
++ int adc_temp_divider;
+ };
+
+ static struct tosa_bat tosa_bat_main;
+ static struct tosa_bat tosa_bat_jacket;
+
+-static enum power_supply_property tosa_bat_main_props[] = {
+- POWER_SUPPLY_PROP_STATUS,
+- POWER_SUPPLY_PROP_TECHNOLOGY,
+- POWER_SUPPLY_PROP_VOLTAGE_NOW,
+- POWER_SUPPLY_PROP_VOLTAGE_MAX,
+- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+- POWER_SUPPLY_PROP_TEMP,
+- POWER_SUPPLY_PROP_PRESENT,
+-};
+-
+-static enum power_supply_property tosa_bat_bu_props[] = {
+- POWER_SUPPLY_PROP_STATUS,
+- POWER_SUPPLY_PROP_TECHNOLOGY,
+- POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+- POWER_SUPPLY_PROP_VOLTAGE_NOW,
+- POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+- POWER_SUPPLY_PROP_PRESENT,
+-};
+-
+ static unsigned long tosa_read_bat(struct tosa_bat *bat)
+ {
+ unsigned long value = 0;
+@@ -83,6 +64,9 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat)
+ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_bat);
+ gpio_set_value(bat->gpio_bat, 0);
+ mutex_unlock(&bat_lock);
++
++ value = value * 1000000 / bat->adc_bat_divider;
++
+ return value;
+ }
+
+@@ -99,6 +83,9 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat)
+ value = wm97xx_read_aux_adc(bat->psy.dev->parent->driver_data, bat->adc_temp);
+ gpio_set_value(bat->gpio_temp, 0);
+ mutex_unlock(&bat_lock);
++
++ value = value * 10000 / bat->adc_temp_divider;
++
+ return value;
+ }
+
+@@ -119,22 +106,25 @@ static int tosa_bat_get_property(struct power_supply *psy,
+ val->intval = bat->status;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+- val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
++ val->intval = bat->technology;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+- val->intval = BAT_TO_VOLTS(tosa_read_bat(bat));
++ val->intval = tosa_read_bat(bat);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX:
+ if (bat->full_chrg == -1)
+- val->intval = -1;
++ val->intval = bat->bat_max;
+ else
+- val->intval = BAT_TO_VOLTS(bat->full_chrg);
++ val->intval = bat->full_chrg;
++ break;
++ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
++ val->intval = bat->bat_max;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+- val->intval = BAT_TO_VOLTS(1551);
++ val->intval = bat->bat_min;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+- val->intval = BAT_TO_TEMP(tosa_read_temp(bat));
++ val->intval = tosa_read_temp(bat);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = bat->is_present ? bat->is_present(bat) : 1;
+@@ -146,40 +136,6 @@ static int tosa_bat_get_property(struct power_supply *psy,
+ return ret;
+ }
+
+-static int tosa_bu_get_property(struct power_supply *psy,
+- enum power_supply_property psp,
+- union power_supply_propval *val)
+-{
+- int ret = 0;
+- struct tosa_bat *bat = container_of(psy, struct tosa_bat, psy);
+-
+- switch (psp) {
+- case POWER_SUPPLY_PROP_STATUS:
+- val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+- break;
+- case POWER_SUPPLY_PROP_TECHNOLOGY:
+- val->intval = POWER_SUPPLY_TECHNOLOGY_LiMn;
+- break;
+- case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+- val->intval = 0;
+- break;
+- case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+- val->intval = 3 * 1000000; /* 3 V */
+- break;
+- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+- /* I think so */
+- val->intval = BU_TO_VOLTS(tosa_read_bat(bat));
+- break;
+- case POWER_SUPPLY_PROP_PRESENT:
+- val->intval = 1;
+- break;
+- default:
+- ret = -EINVAL;
+- break;
+- }
+- return ret;
+-}
+-
+ static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) {
+ // FIXME
+ return 1;
+@@ -241,6 +197,25 @@ static void tosa_bat_work(struct work_struct *work)
+ }
+
+
++static enum power_supply_property tosa_bat_main_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
++ POWER_SUPPLY_PROP_TEMP,
++ POWER_SUPPLY_PROP_PRESENT,
++};
++
++static enum power_supply_property tosa_bat_bu_props[] = {
++ POWER_SUPPLY_PROP_STATUS,
++ POWER_SUPPLY_PROP_TECHNOLOGY,
++ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
++ POWER_SUPPLY_PROP_VOLTAGE_NOW,
++ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
++ POWER_SUPPLY_PROP_PRESENT,
++};
++
+ static struct tosa_bat tosa_bat_main = {
+ .status = POWER_SUPPLY_STATUS_UNKNOWN,
+ .full_chrg = -1,
+@@ -256,10 +231,18 @@ static struct tosa_bat tosa_bat_main = {
+
+ .gpio_full = TOSA_GPIO_BAT0_CRG,
+ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF,
++
++ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
++
+ .gpio_bat = TOSA_TC6393XB_BAT0_V_ON,
+ .adc_bat = WM97XX_AUX_ID3,
++ .adc_bat_divider = 414,
++ .bat_max = 4310000,
++ .bat_min = 1551 * 100000 / 414,
++
+ .gpio_temp = TOSA_TC6393XB_BAT1_TH_ON,
+ .adc_temp = WM97XX_AUX_ID2,
++ .adc_temp_divider = 10000,
+ };
+
+ static struct tosa_bat tosa_bat_jacket = {
+@@ -278,10 +261,18 @@ static struct tosa_bat tosa_bat_jacket = {
+ .is_present = tosa_jacket_bat_is_present,
+ .gpio_full = TOSA_GPIO_BAT1_CRG,
+ .gpio_charge_off = TOSA_TC6393XB_CHARGE_OFF_JC,
++
++ .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
++
+ .gpio_bat = TOSA_TC6393XB_BAT1_V_ON,
+ .adc_bat = WM97XX_AUX_ID3,
++ .adc_bat_divider = 414,
++ .bat_max = 4310000,
++ .bat_min = 1551 * 100000 / 414,
++
+ .gpio_temp = TOSA_TC6393XB_BAT0_TH_ON,
+ .adc_temp = WM97XX_AUX_ID2,
++ .adc_temp_divider = 10000,
+ };
+
+ static struct tosa_bat tosa_bat_bu = {
+@@ -293,16 +284,22 @@ static struct tosa_bat tosa_bat_bu = {
+ .type = POWER_SUPPLY_TYPE_BATTERY,
+ .properties = tosa_bat_bu_props,
+ .num_properties = ARRAY_SIZE(tosa_bat_bu_props),
+- .get_property = tosa_bu_get_property,
++ .get_property = tosa_bat_get_property,
+ .external_power_changed = tosa_bat_external_power_changed,
+ },
+
+ .gpio_full = -1,
+ .gpio_charge_off = -1,
++
++ .technology = POWER_SUPPLY_TECHNOLOGY_LiMn,
++
+ .gpio_bat = TOSA_TC6393XB_BU_CHRG_ON,
+ .adc_bat = WM97XX_AUX_ID4,
++ .adc_bat_divider = 1266,
++
+ .gpio_temp = -1,
+ .adc_temp = -1,
++ .adc_temp_divider = -1,
+ };
+
+ static struct {
+@@ -326,13 +323,14 @@ static struct {
+ };
+
+ #ifdef CONFIG_PM
+-static int tosa_bat_suspend(struct device *dev, pm_message_t state)
++static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state)
+ {
+ /* do nothing */
++ flush_scheduled_work();
+ return 0;
+ }
+
+-static int tosa_bat_resume(struct device *dev)
++static int tosa_bat_resume(struct platform_device *dev)
+ {
+ schedule_work(&bat_work);
+ return 0;
+@@ -342,7 +340,7 @@ static int tosa_bat_resume(struct device *dev)
+ #define tosa_bat_resume NULL
+ #endif
+
+-static int __devinit tosa_bat_probe(struct device *dev)
++static int __devinit tosa_bat_probe(struct platform_device *dev)
+ {
+ int ret;
+ int i;
+@@ -372,13 +370,13 @@ static int __devinit tosa_bat_probe(struct device *dev)
+
+ INIT_WORK(&bat_work, tosa_bat_work);
+
+- ret = power_supply_register(dev, &tosa_bat_main.psy);
++ ret = power_supply_register(&dev->dev, &tosa_bat_main.psy);
+ if (ret)
+ goto err_psy_reg_main;
+- ret = power_supply_register(dev, &tosa_bat_jacket.psy);
++ ret = power_supply_register(&dev->dev, &tosa_bat_jacket.psy);
+ if (ret)
+ goto err_psy_reg_jacket;
+- ret = power_supply_register(dev, &tosa_bat_bu.psy);
++ ret = power_supply_register(&dev->dev, &tosa_bat_bu.psy);
+ if (ret)
+ goto err_psy_reg_bu;
+
+@@ -413,7 +411,7 @@ err_gpio:
+ return ret;
+ }
+
+-static int __devexit tosa_bat_remove(struct device *dev)
++static int __devexit tosa_bat_remove(struct platform_device *dev)
+ {
+ int i;
+
+@@ -430,10 +428,9 @@ static int __devexit tosa_bat_remove(struct device *dev)
+ return 0;
+ }
+
+-static struct device_driver tosa_bat_driver = {
+- .name = "wm97xx-battery",
+- .bus = &wm97xx_bus_type,
+- .owner = THIS_MODULE,
++static struct platform_driver tosa_bat_driver = {
++ .driver.name = "wm97xx-battery",
++ .driver.owner = THIS_MODULE,
+ .probe = tosa_bat_probe,
+ .remove = __devexit_p(tosa_bat_remove),
+ .suspend = tosa_bat_suspend,
+@@ -442,12 +439,12 @@ static struct device_driver tosa_bat_driver = {
+
+ static int __init tosa_bat_init(void)
+ {
+- return driver_register(&tosa_bat_driver);
++ return platform_driver_register(&tosa_bat_driver);
+ }
+
+ static void __exit tosa_bat_exit(void)
+ {
+- driver_unregister(&tosa_bat_driver);
++ platform_driver_unregister(&tosa_bat_driver);
+ }
+
+ module_init(tosa_bat_init);
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch b/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch
new file mode 100644
index 0000000000..e3a6b74772
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0062-tosa-bat-fix-charging.patch
@@ -0,0 +1,78 @@
+From 0b9f80ab540b2e51f6e86f6a1adec67761f9368d Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Fri, 8 Feb 2008 00:50:03 +0300
+Subject: [PATCH 62/64] tosa-bat-fix-charging
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/power/tosa_battery.c | 28 +++++++++++++++++++++-------
+ 1 files changed, 21 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
+index 008e791..2db9116 100644
+--- a/drivers/power/tosa_battery.c
++++ b/drivers/power/tosa_battery.c
+@@ -153,39 +153,53 @@ static irqreturn_t tosa_bat_full_isr(int irq, void *data)
+ return IRQ_HANDLED;
+ }
+
++static char *status_text[] = {
++ [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
++ [POWER_SUPPLY_STATUS_CHARGING] = "Charging",
++ [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
++ [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging",
++ [POWER_SUPPLY_STATUS_FULL] = "Full",
++};
++
+ static void tosa_bat_update(struct tosa_bat *bat)
+ {
+- int old = bat->status;
++ int old;
+ struct power_supply *psy = &bat->psy;
+
+ mutex_lock(&bat->work_lock);
+
++ old = bat->status;
++
+ if (bat->is_present && !bat->is_present(bat)) {
+- printk(KERN_DEBUG "%s not present\n", psy->name);
++ printk(KERN_NOTICE "%s not present\n", psy->name);
+ bat->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ bat->full_chrg = -1;
+ } else if (power_supply_am_i_supplied(psy)) {
++ if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) {
++ gpio_set_value(bat->gpio_charge_off, 0);
++ mdelay(15);
++ }
+ if (gpio_get_value(bat->gpio_full)) {
+- printk(KERN_DEBUG "%s full\n", psy->name);
+-
+ if (old == POWER_SUPPLY_STATUS_CHARGING || bat->full_chrg == -1)
+ bat->full_chrg = tosa_read_bat(bat);
+
+ gpio_set_value(bat->gpio_charge_off, 1);
+ bat->status = POWER_SUPPLY_STATUS_FULL;
+ } else {
+- printk(KERN_ERR "%s charge\n", psy->name);
+ gpio_set_value(bat->gpio_charge_off, 0);
+ bat->status = POWER_SUPPLY_STATUS_CHARGING;
+ }
+ } else {
+- printk(KERN_ERR "%s discharge\n", psy->name);
+ gpio_set_value(bat->gpio_charge_off, 1);
+ bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
+ }
+
+- if (old != bat->status)
++ if (old != bat->status) {
++ printk(KERN_NOTICE "%s %s -> %s\n", psy->name,
++ status_text[old],
++ status_text[bat->status]);
+ power_supply_changed(psy);
++ }
+
+ mutex_unlock(&bat->work_lock);
+ }
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch b/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch
new file mode 100644
index 0000000000..416cae44ec
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0063-patch-tosa-bat-jacket-detect.patch
@@ -0,0 +1,84 @@
+From 4ef7289137132959e3db5a1e77580ff9db185d90 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Fri, 8 Feb 2008 01:13:54 +0300
+Subject: [PATCH 63/64] patch tosa-bat-jacket-detect
+
+---
+ drivers/power/tosa_battery.c | 21 +++++++++++++++------
+ 1 files changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c
+index 2db9116..70beed2 100644
+--- a/drivers/power/tosa_battery.c
++++ b/drivers/power/tosa_battery.c
+@@ -137,8 +137,7 @@ static int tosa_bat_get_property(struct power_supply *psy,
+ }
+
+ static bool tosa_jacket_bat_is_present(struct tosa_bat *bat) {
+- // FIXME
+- return 1;
++ return gpio_get_value(TOSA_GPIO_JACKET_DETECT) == 0;
+ }
+
+ static void tosa_bat_external_power_changed(struct power_supply *psy)
+@@ -146,9 +145,9 @@ static void tosa_bat_external_power_changed(struct power_supply *psy)
+ schedule_work(&bat_work);
+ }
+
+-static irqreturn_t tosa_bat_full_isr(int irq, void *data)
++static irqreturn_t tosa_bat_gpio_isr(int irq, void *data)
+ {
+- printk(KERN_ERR "bat_full irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
++ printk(KERN_ERR "bat_gpio irq: %d\n", gpio_get_value(irq_to_gpio(irq)));
+ schedule_work(&bat_work);
+ return IRQ_HANDLED;
+ }
+@@ -334,6 +333,7 @@ static struct {
+ { TOSA_GPIO_BAT1_CRG, "jacket battery full", 0, 0 },
+ { TOSA_GPIO_BAT0_LOW, "main battery low", 0, 0 },
+ { TOSA_GPIO_BAT1_LOW, "jacket battery low", 0, 0 },
++ { TOSA_GPIO_JACKET_DETECT, "jacket detect", 0, 0 },
+ };
+
+ #ifdef CONFIG_PM
+@@ -395,19 +395,27 @@ static int __devinit tosa_bat_probe(struct platform_device *dev)
+ goto err_psy_reg_bu;
+
+ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG),
+- tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "main full", &tosa_bat_main);
+ if (ret)
+ goto err_req_main;
+
+ ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG),
+- tosa_bat_full_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "jacket full", &tosa_bat_jacket);
++ if (ret)
++ goto err_req_jacket;
++
++ ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT),
++ tosa_bat_gpio_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
++ "jacket detect", &tosa_bat_jacket);
+ if (!ret) {
+ schedule_work(&bat_work);
+ return 0;
+ }
+
++ free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
++err_req_jacket:
+ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
+ err_req_main:
+ power_supply_unregister(&tosa_bat_bu.psy);
+@@ -429,6 +437,7 @@ static int __devexit tosa_bat_remove(struct platform_device *dev)
+ {
+ int i;
+
++ free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
+ free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
+ free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
+
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch b/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch
new file mode 100644
index 0000000000..eeb92cfdd5
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0064-Export-modes-via-sysfs.patch
@@ -0,0 +1,27 @@
+From feeee5d22c00d9d1e2e06eb5610740be238749b9 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Thu, 7 Feb 2008 22:27:38 +0300
+Subject: [PATCH 64/64] Export modes via sysfs
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/video/tmiofb.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
+index 6b963a1..9389a77 100644
+--- a/drivers/video/tmiofb.c
++++ b/drivers/video/tmiofb.c
+@@ -800,6 +800,9 @@ static int tmiofb_probe(struct platform_device *dev)
+ if (retval)
+ goto err_set_par;*/
+
++ fb_videomode_to_modelist(data->modes, data->num_modes,
++ &info->modelist);
++
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err_register_framebuffer;
+--
+1.5.3.8
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch b/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch
new file mode 100644
index 0000000000..5db0cc6ba0
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0065-wm97xx-core-fixes.patch
@@ -0,0 +1,49 @@
+From 2544412fc47dc13f4f3935cb4c2fd500d217e905 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 13 Feb 2008 02:00:15 +0300
+Subject: [PATCH] wm97xx-core fixes
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/input/touchscreen/wm97xx-core.c | 8 ++++----
+ include/linux/wm97xx.h | 1 -
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
+index 840d9ff..4cbb9e5 100644
+--- a/drivers/input/touchscreen/wm97xx-core.c
++++ b/drivers/input/touchscreen/wm97xx-core.c
+@@ -596,7 +596,7 @@ static int wm97xx_probe(struct device *dev)
+ }
+ platform_set_drvdata(wm->battery_dev, wm);
+ wm->battery_dev->dev.parent = dev;
+- ret = platform_device_register(wm->battery_dev);
++ ret = platform_device_add(wm->battery_dev);
+ if (ret < 0)
+ goto batt_reg_err;
+
+@@ -609,7 +609,7 @@ static int wm97xx_probe(struct device *dev)
+ }
+ platform_set_drvdata(wm->touch_dev, wm);
+ wm->touch_dev->dev.parent = dev;
+- ret = platform_device_register(wm->touch_dev);
++ ret = platform_device_add(wm->touch_dev);
+ if (ret < 0)
+ goto touch_reg_err;
+
+@@ -619,10 +619,12 @@ static int wm97xx_probe(struct device *dev)
+ platform_device_put(wm->touch_dev);
+ touch_err:
+ platform_device_unregister(wm->battery_dev);
++ wm->battery_dev = NULL;
+ batt_reg_err:
+ platform_device_put(wm->battery_dev);
+ batt_err:
+ input_unregister_device(wm->input_dev);
++ wm->input_dev = NULL;
+ kfree(wm);
+ return ret;
+ }
+--
+1.5.4.1
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch b/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch
new file mode 100644
index 0000000000..42320be50b
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0066-tmiofb_probe-should-be-__devinit.patch
@@ -0,0 +1,26 @@
+From b6a63ad546cc26519a342f3fdd7b1def49ca33ee Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 13 Feb 2008 02:00:14 +0300
+Subject: [PATCH] tmiofb_probe should be __devinit
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/video/tmiofb.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
+index 9389a77..958ee8a 100644
+--- a/drivers/video/tmiofb.c
++++ b/drivers/video/tmiofb.c
+@@ -704,7 +704,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)
+ return IRQ_HANDLED;
+ }
+
+-static int tmiofb_probe(struct platform_device *dev)
++static int __devinit tmiofb_probe(struct platform_device *dev)
+ {
+ struct mfd_cell *cell = mfd_get_cell(dev);
+ struct tmio_fb_data *data = cell->driver_data;
+--
+1.5.4.1
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch b/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch
new file mode 100644
index 0000000000..42b69d9377
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0067-modeswitching.patch
@@ -0,0 +1,225 @@
+From aded2e51a7a2113dae6431c858df1d95fb312851 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Wed, 13 Feb 2008 19:34:08 +0300
+Subject: [PATCH] modeswitching
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ arch/arm/mach-pxa/tosa.c | 33 +++++++++++++++++++++++++++++++-
+ drivers/mfd/tc6393xb.c | 2 +-
+ drivers/video/backlight/tosa_bl.c | 38 +++++++++++++++++++++++++++++++++---
+ drivers/video/tmiofb.c | 8 +++---
+ include/asm-arm/arch-pxa/tosa.h | 2 +
+ include/linux/mfd/tc6393xb.h | 2 +-
+ include/linux/mfd/tmio.h | 2 +-
+ 7 files changed, 75 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
+index 94c9915..6631de2 100644
+--- a/arch/arm/mach-pxa/tosa.c
++++ b/arch/arm/mach-pxa/tosa.c
+@@ -455,9 +455,40 @@ static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
+ }
+ };
+
++static DEFINE_SPINLOCK(tosa_lcd_mode_lock);
++
++static const struct fb_videomode *tosa_lcd_mode = &tosa_tc6393xb_lcd_mode[0];
++
++static int tosa_lcd_set_mode(struct platform_device *fb_dev,
++ const struct fb_videomode *mode)
++{
++ int rc;
++ unsigned long flags;
++
++ spin_lock_irqsave(&tosa_lcd_mode_lock, flags);
++ rc = tc6393xb_lcd_mode(fb_dev, mode);
++ if (!rc)
++ tosa_lcd_mode = mode;
++ spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags);
++
++ return rc;
++}
++
++const struct fb_videomode *tosa_lcd_get_mode(void)
++{
++ unsigned long flags;
++ const struct fb_videomode *mode;
++
++ spin_lock_irqsave(&tosa_lcd_mode_lock, flags);
++ mode = tosa_lcd_mode;
++ spin_unlock_irqrestore(&tosa_lcd_mode_lock, flags);
++
++ return mode;
++}
++
+ static struct tmio_fb_data tosa_tc6393xb_fb_config = {
+ .lcd_set_power = tc6393xb_lcd_set_power,
+- .lcd_mode = tc6393xb_lcd_mode,
++ .lcd_mode = tosa_lcd_set_mode,
+ .num_modes = ARRAY_SIZE(tosa_tc6393xb_lcd_mode),
+ .modes = &tosa_tc6393xb_lcd_mode[0],
+ };
+diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
+index 9001687..21190f3 100644
+--- a/drivers/mfd/tc6393xb.c
++++ b/drivers/mfd/tc6393xb.c
+@@ -196,7 +196,7 @@ int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
+ EXPORT_SYMBOL(tc6393xb_lcd_set_power);
+
+ int tc6393xb_lcd_mode(struct platform_device *fb_dev,
+- struct fb_videomode *mode) {
++ const struct fb_videomode *mode) {
+ struct tc6393xb *tc6393xb =
+ platform_get_drvdata(to_platform_device(fb_dev->dev.parent));
+ struct tc6393xb_scr __iomem *scr = tc6393xb->scr;
+diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c
+index 9ef0bfb..45fc6ae 100644
+--- a/drivers/video/backlight/tosa_bl.c
++++ b/drivers/video/backlight/tosa_bl.c
+@@ -48,6 +48,9 @@ struct tosa_bl_data {
+ struct ssp_dev nssp_dev;
+ struct ssp_state nssp_state;
+
++ /* listen for mode changes */
++ struct notifier_block fb_notif;
++
+ struct backlight_device *bl_dev;
+ };
+
+@@ -103,14 +106,19 @@ static void tosa_lcd_tg_init(struct tosa_bl_data *data)
+ pxa_nssp_output(data, TG_GPOSR,0x02); /* GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL */
+ }
+
+-static void tosa_lcd_tg_on(struct tosa_bl_data *data/*, const struct fb_videomode *mode*/)
++static void tosa_lcd_tg_on(struct tosa_bl_data *data)
+ {
+- const int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
++ const struct fb_videomode *mode = tosa_lcd_get_mode();
++
++ int value = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
++
++ if (mode->yres == 640)
++ value |= TG_REG0_VQV;
+
+ tosa_lcd_tg_init(data);
+
+- dev_dbg(&data->bl_dev->dev, "tosa_lcd_on\n");
+- pxa_nssp_output(data, TG_PNLCTL, value | (/*mode->yres == 320 ? 0 : */ TG_REG0_VQV));
++ dev_dbg(&data->bl_dev->dev, "tosa_lcd_on: %04x (%d)\n", value, mode->yres);
++ pxa_nssp_output(data, TG_PNLCTL, value);
+
+ /* TG LCD pannel power up */
+ pxa_nssp_output(data, TG_PINICTL,0x4);
+@@ -173,6 +181,20 @@ static struct backlight_ops tosa_bl_ops = {
+ .update_status = tosa_bl_update_status,
+ };
+
++static int fb_notifier_callback(struct notifier_block *self,
++ unsigned long event, void *_data)
++{
++ struct tosa_bl_data *bl_data =
++ container_of(self, struct tosa_bl_data, fb_notif);
++
++ if (event != FB_EVENT_MODE_CHANGE && event != FB_EVENT_MODE_CHANGE_ALL)
++ return 0;
++
++ tosa_bl_update_status(bl_data->bl_dev);
++
++ return 0;
++}
++
+ static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address,
+ int kind)
+ {
+@@ -238,9 +260,15 @@ static int tosa_bl_detect_client(struct i2c_adapter *adapter, int address,
+ data->bl_dev->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(data->bl_dev);
+
++ data->fb_notif.notifier_call = fb_notifier_callback;
++ err = fb_register_client(&data->fb_notif);
++ if (err)
++ goto err_fb_register;
+
+ return 0;
+
++err_fb_register:
++ backlight_device_unregister(data->bl_dev);
+ err_bl_register:
+ tosa_set_backlight(data, 0);
+ tosa_lcd_tg_off(data);
+@@ -265,6 +293,8 @@ static int tosa_bl_detach_client(struct i2c_client *client)
+ int err = 0;
+ struct tosa_bl_data *data = i2c_get_clientdata(client);
+
++ fb_unregister_client(&data->fb_notif);
++
+ backlight_device_unregister(data->bl_dev);
+
+ tosa_set_backlight(data, 0);
+diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
+index 958ee8a..cc75df9 100644
+--- a/drivers/video/tmiofb.c
++++ b/drivers/video/tmiofb.c
+@@ -618,17 +618,17 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+
+ static int tmiofb_set_par(struct fb_info *info)
+ {
+-/* struct fb_var_screeninfo *var = &info->var;
++ struct fb_var_screeninfo *var = &info->var;
+ struct fb_videomode *mode;
+
+ mode = tmiofb_find_mode(info, var);
+ if (!mode)
+ return -EINVAL;
+
+- if (info->mode == mode)
+- return 0;
++/* if (info->mode == mode)
++ return 0;*/
+
+- info->mode = mode; */
++ info->mode = mode;
+ info->fix.line_length = info->mode->xres * 2;
+
+ tmiofb_hw_mode(to_platform_device(info->device));
+diff --git a/include/asm-arm/arch-pxa/tosa.h b/include/asm-arm/arch-pxa/tosa.h
+index 410fa9a..624c636 100644
+--- a/include/asm-arm/arch-pxa/tosa.h
++++ b/include/asm-arm/arch-pxa/tosa.h
+@@ -230,4 +230,6 @@ extern struct platform_device tosascoop_device;
+ #define TOSA_KEY_MAIL KEY_MAIL
+ #endif
+
++const struct fb_videomode *tosa_lcd_get_mode(void);
++
+ #endif /* _ASM_ARCH_TOSA_H_ */
+diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
+index 97c4c7c..8ab9e91 100644
+--- a/include/linux/mfd/tc6393xb.h
++++ b/include/linux/mfd/tc6393xb.h
+@@ -53,7 +53,7 @@ struct tc6393xb_platform_data {
+
+ extern int tc6393xb_lcd_set_power(struct platform_device *fb_dev, bool on);
+ extern int tc6393xb_lcd_mode(struct platform_device *fb_dev,
+- struct fb_videomode *mode);
++ const struct fb_videomode *mode);
+
+ /*
+ * Relative to irq_base
+diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
+index b6d4aac..fe7ff2d 100644
+--- a/include/linux/mfd/tmio.h
++++ b/include/linux/mfd/tmio.h
+@@ -19,7 +19,7 @@ struct tmio_fb_data {
+ int (*lcd_set_power)(struct platform_device *fb_dev,
+ bool on);
+ int (*lcd_mode)(struct platform_device *fb_dev,
+- struct fb_videomode *mode);
++ const struct fb_videomode *mode);
+ int num_modes;
+ struct fb_videomode *modes;
+ };
+--
+1.5.4.1
+
diff --git a/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch b/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch
new file mode 100644
index 0000000000..e90e3751c0
--- /dev/null
+++ b/packages/linux/linux-rp-2.6.24/tosa/0068-Preliminary-tosa-denoiser.patch
@@ -0,0 +1,239 @@
+From f7dad1cd9c1bd3fce5d228e0b644a51baea50cd9 Mon Sep 17 00:00:00 2001
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Fri, 15 Feb 2008 15:35:07 +0300
+Subject: [PATCH] Preliminary tosa denoiser
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+---
+ drivers/input/touchscreen/Kconfig | 12 ++
+ drivers/input/touchscreen/Makefile | 1 +
+ drivers/input/touchscreen/tosa-wm97xx.c | 182 +++++++++++++++++++++++++++++++
+ 3 files changed, 195 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/input/touchscreen/tosa-wm97xx.c
+
+diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
+index 0be05a2..938aed2 100644
+--- a/drivers/input/touchscreen/Kconfig
++++ b/drivers/input/touchscreen/Kconfig
+@@ -210,6 +210,18 @@ config TOUCHSCREEN_WM97XX_MAINSTONE
+ To compile this driver as a module, choose M here: the
+ module will be called mainstone-wm97xx
+
++config TOUCHSCREEN_WM97XX_TOSA
++ tristate "WM97xx Tosa denoiser"
++ depends on TOUCHSCREEN_WM97XX && MACH_TOSA
++ help
++ Say Y here for support for touchscreen denoising on
++ Sharl Zaurus SL-6000 (tosa) system.
++
++ If unsure, say N
++
++ To compile this driver as a module, choose M here: the
++ module will be called tosa-wm97xx
++
+ config TOUCHSCREEN_TOUCHWIN
+ tristate "Touchwin serial touchscreen"
+ select SERIO
+diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
+index d38156e..d86278b 100644
+--- a/drivers/input/touchscreen/Makefile
++++ b/drivers/input/touchscreen/Makefile
+@@ -23,6 +23,7 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
+ obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
+ obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
+ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
++obj-$(CONFIG_TOUCHSCREEN_WM97XX_TOSA) += tosa-wm97xx.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o
+ wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o
+diff --git a/drivers/input/touchscreen/tosa-wm97xx.c b/drivers/input/touchscreen/tosa-wm97xx.c
+new file mode 100644
+index 0000000..8fd542b
+--- /dev/null
++++ b/drivers/input/touchscreen/tosa-wm97xx.c
+@@ -0,0 +1,182 @@
++/*
++ * tosa_ts.c -- Touchscreen driver for Sharp SL-6000 (Tosa).
++ *
++ * Copyright 2008 Dmitry Baryshkov
++ * Copyright 2006 Wolfson Microelectronics PLC.
++ * Author: Mike Arthur
++ * linux@wolfsonmicro.com
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * Revision history
++ * 1st Sep 2006 Initial version.
++ *
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/wm97xx.h>
++#include <linux/fb.h>
++
++#include <asm/arch/tosa.h>
++#include <asm/gpio.h>
++
++static unsigned long hsync_time = 0;
++
++static void calc_hsync_time(const struct fb_videomode *mode)
++{
++ /* The 25 and 44 'magic numbers' are from Sharp's 2.4 patches */
++ if (mode->yres == 640) {
++ hsync_time = 25;
++ } else if (mode->yres == 320) {
++ hsync_time = 44;
++ } else {
++ printk(KERN_ERR "unknown video mode res specified: %dx%d!", mode->xres, mode->yres);
++ WARN_ON(1);
++ }
++
++ printk(KERN_ERR "tosa-wm97xx: using %lu hsync time\n", hsync_time);
++}
++
++static int fb_notifier_callback(struct notifier_block *self,
++ unsigned long event, void *_data)
++{
++ if (event != FB_EVENT_MODE_CHANGE && event != FB_EVENT_MODE_CHANGE_ALL)
++ return 0;
++
++ calc_hsync_time(tosa_lcd_get_mode());
++
++ return 0;
++}
++
++static void tosa_lcd_wait_hsync(void)
++{
++ /* Waits for a rising edge on the VGA line */
++ while (gpio_get_value(TOSA_GPIO_VGA_LINE) == 0);
++ while (gpio_get_value(TOSA_GPIO_VGA_LINE) != 0);
++}
++
++/* Taken from the Sharp 2.4 kernel code */
++#define CCNT(a) asm volatile ("mrc p14, 0, %0, C1, C1, 0" : "=r"(a))
++#define CCNT_ON() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(1))
++#define CCNT_OFF() asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(0))
++
++/* On the Sharp SL-6000 (Tosa), due to a noisy LCD, we need to perform a wait
++ * before sampling the Y axis of the touchscreen */
++static void tosa_lcd_sync_on(int adcsel)
++{
++ unsigned long timer1 = 0, timer2 = 0, wait_time = 0;
++ if (adcsel & WM97XX_ADCSEL_Y) {
++ CCNT_ON();
++ wait_time = hsync_time;
++
++ if (wait_time) {
++
++ /* wait for LCD rising edge */
++ tosa_lcd_wait_hsync();
++ /* get clock */
++ CCNT(timer1);
++ CCNT(timer2);
++
++ while ((timer2 - timer1) < wait_time) {
++ CCNT(timer2);
++ }
++ }
++ }
++}
++
++static void tosa_lcd_sync_off(int adcsel)
++{
++ if (adcsel & WM97XX_ADCSEL_Y)
++ CCNT_OFF();
++}
++
++static struct wm97xx_mach_ops tosa_mach_ops = {
++ .pre_sample = tosa_lcd_sync_on,
++ .post_sample = tosa_lcd_sync_off,
++};
++
++static int __devinit tosa_ts_probe(struct platform_device *dev) {
++ struct wm97xx *wm = platform_get_drvdata(dev);
++ struct notifier_block *notif;
++ int err = -ENOMEM;
++
++ notif = kzalloc(sizeof(struct notifier_block), GFP_KERNEL);
++ if (!notif)
++ goto err_alloc;
++
++ notif->notifier_call = fb_notifier_callback;
++
++ err = gpio_request(TOSA_GPIO_VGA_LINE, "hsync");
++ if (err)
++ goto err_gpio;
++
++ err = gpio_direction_input(TOSA_GPIO_VGA_LINE);
++ if (err)
++ goto err_gpio;
++
++ platform_set_drvdata(dev, notif);
++
++ err = fb_register_client(notif);
++ if (err)
++ goto err_register;
++
++ err = wm97xx_register_mach_ops(wm, &tosa_mach_ops);
++ if (err)
++ goto err_wm97xx;
++
++ calc_hsync_time(tosa_lcd_get_mode());
++
++ return 0;
++
++err_wm97xx:
++ fb_unregister_client(notif);
++err_register:
++ gpio_free(TOSA_GPIO_VGA_LINE);
++err_gpio:
++ kfree(notif);
++err_alloc:
++ return err;
++}
++
++
++static int __devexit tosa_ts_remove(struct platform_device *dev) {
++ struct wm97xx *wm = platform_get_drvdata(dev);
++
++ wm97xx_unregister_mach_ops(wm);
++
++ fb_unregister_client(platform_get_drvdata(dev));
++ gpio_free(TOSA_GPIO_VGA_LINE);
++ kfree(platform_get_drvdata(dev));
++
++ return 0;
++}
++
++static struct platform_driver tosa_ts_driver = {
++ .driver.name = "wm97xx-touch",
++ .driver.owner = THIS_MODULE,
++ .probe = tosa_ts_probe,
++ .remove = __devexit_p(tosa_ts_remove),
++};
++
++static int __init tosa_ts_init(void)
++{
++ return platform_driver_register(&tosa_ts_driver);
++}
++
++static void __exit tosa_ts_exit(void)
++{
++ platform_driver_unregister(&tosa_ts_driver);
++}
++
++module_init(tosa_ts_init);
++module_exit(tosa_ts_exit);
++
++/* Module information */
++MODULE_AUTHOR("Dmitry Baryshkov, Mike Arthur, mike@mikearthur.co.uk, www.wolfsonmicro.com");
++MODULE_DESCRIPTION("Sharp SL6000 Tosa Touch Screen Denoiser");
++MODULE_LICENSE("GPL");
+--
+1.5.4.1
+
diff --git a/packages/linux/linux-rp_2.6.24.bb b/packages/linux/linux-rp_2.6.24.bb
index b3e04980de..48f964d7e7 100644
--- a/packages/linux/linux-rp_2.6.24.bb
+++ b/packages/linux/linux-rp_2.6.24.bb
@@ -5,6 +5,7 @@ PR = "r5"
DEFAULT_PREFERENCE = "-1"
DEFAULT_PREFERENCE_collie = "1"
DEFAULT_PREFERENCE_qemux86 = "1"
+DEFAULT_PREFERENCE_tosa = "1"
# Handy URLs
# git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git;protocol=git;tag=ef7d1b244fa6c94fb76d5f787b8629df64ea4046
@@ -68,9 +69,8 @@ SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 \
file://defconfig-qemux86 \
file://defconfig-bootcdx86 \
file://defconfig-htcuniversal \
+ file://defconfig-tosa \
file://defconfig-zylonite"
-# Tosa disabled until the patchset is updated
-# file://defconfig-tosa
# FIXMEs before made default
# ${RPSRC}/mmcsd_no_scr_check-r1.patch;patch=1;status=hack
@@ -109,34 +109,75 @@ SRC_URI_append_poodle = "\
"
SRC_URI_append_tosa = "\
- ${CHSRC}/tmio-core-r4.patch;patch=1 \
- file://tmio-tc6393-r8.patch;patch=1 \
- file://tmio-nand-r8.patch;patch=1 \
- ${CHSRC}/tmio-fb-r6.patch;patch=1 \
- file://tmio-fb-r6-fix-r0.patch;patch=1 \
- file://tosa-keyboard-r19.patch;patch=1 \
- ${DOSRC}/tosa-pxaac97-r6.patch;patch=1 \
- file://tosa-pxaac97-r6-fix-r0.patch;patch=1 \
- ${DOSRC}/tosa-tmio-r6.patch;patch=1 \
- file://tosa-power-r18.patch;patch=1 \
- file://tosa-power-r18-fix-r0.patch;patch=1 \
- file://tosa-tmio-lcd-r10.patch;patch=1 \
- file://tosa-tmio-lcd-r10-fix-r0.patch;patch=1 \
- file://tosa-bluetooth-r8.patch;patch=1 \
- file://wm97xx-lg13-r0.patch;patch=1 \
- file://wm97xx-lg13-r0-fix-r0.patch;patch=1 \
- file://wm9712-suspend-cold-res-r2.patch;patch=1 \
- file://sharpsl-pm-postresume-r1.patch;patch=1 \
- file://wm9712-reset-loop-r2.patch;patch=1 \
- file://tosa-lcdnoise-r1.patch;patch=1 \
- file://tosa-lcdnoise-r1-fix-r0.patch;patch=1 \
- file://arm-dma-coherent.patch;patch=1 \
- file://usb-ohci-hooks-r3.patch;patch=1 \
- file://tmio-ohci-r9.patch;patch=1 \
- file://pxa2xx_udc_support_inverse_vbus.patch;patch=1 \
- file://tosa_udc_use_gpio_vbus.patch;patch=1 \
+ file://tosa/0001-Allow-runtime-registration-of-regions-of-memory-that.patch;patch=1 \
+ file://tosa/0002-Modify-dma_alloc_coherent-on-ARM-so-that-it-supports.patch;patch=1 \
+ file://tosa/0003-Core-MFD-support.patch;patch=1 \
+ file://tosa/0004-Add-support-for-tc6393xb-MFD-core.patch;patch=1 \
+ file://tosa/0005-Add-support-for-tc6387xb-MFD-core.patch;patch=1 \
+ file://tosa/0006-Add-support-for-t7l66xb-MFD-core.patch;patch=1 \
+ file://tosa/0007-Common-headers-for-TMIO-MFD-subdevices.patch;patch=1 \
+ file://tosa/0008-Nand-driver-for-TMIO-devices.patch;patch=1 \
+ file://tosa/0009-FB-driver-for-TMIO-devices.patch;patch=1 \
+ file://tosa/0010-OHCI-driver-for-TMIO-devices.patch;patch=1 \
+ file://tosa/0011-MMC-driver-for-TMIO-devices.patch;patch=1 \
+ file://tosa/0012-Tosa-keyboard-support.patch;patch=1 \
+ file://tosa/0013-USB-gadget-pxa2xx_udc-supports-inverted-vbus.patch;patch=1 \
+ file://tosa/0014-tosa_udc_use_gpio_vbus.patch.patch;patch=1 \
+ file://tosa/0015-sharpsl-export-params.patch;patch=1 \
+ file://tosa/0016-This-patch-fixes-the-pxa25x-clocks-definitions-to-ad.patch;patch=1 \
+ file://tosa/0017-Convert-pxa2xx-UDC-to-use-debugfs.patch;patch=1 \
+ file://tosa/0018-Fix-the-pxa2xx_udc-to-balance-calls-to-clk_enable-cl.patch;patch=1 \
+ file://tosa/0026-I-don-t-think-we-should-check-for-IRQs-when-determin.patch;patch=1 \
+ file://tosa/0027-Add-LiMn-one-of-the-most-common-for-small-non-recha.patch;patch=1 \
+ file://tosa/0028-Add-suspend-resume-wakeup-support-for-pda_power.patch;patch=1 \
+ file://tosa/0029-Support-using-VOLTAGE_-properties-for-apm-calculati.patch;patch=1 \
+ file://tosa/0030-Core-driver-for-WM97xx-touchscreens.patch;patch=1 \
+ file://tosa/0031-Add-chip-driver-for-WM9705-touchscreen.patch;patch=1 \
+ file://tosa/0032-Add-chip-driver-for-WM9712-touchscreen.patch;patch=1 \
+ file://tosa/0033-Add-chip-driver-for-WM9713-touchscreen.patch;patch=1 \
+ file://tosa/0034-Driver-for-WM97xx-touchscreens-in-streaming-mode-on.patch;patch=1 \
+ file://tosa/0035-Build-system-and-MAINTAINERS-entry-for-WM97xx-touchs.patch;patch=1 \
+ file://tosa/0036-Set-id-to-1-for-wm97xx-subdevices.patch;patch=1 \
+ file://tosa/0037-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch;patch=1 \
+ file://tosa/0038-Don-t-lock-the-codec-list-in-snd_soc_dapm_new_widget.patch;patch=1 \
+ file://tosa/0044-fix-tmio_mmc-debug-compilation.patch;patch=1 \
+ file://tosa/0045-Update-tmio_ohci.patch;patch=1 \
+ file://tosa/0046-patch-tc6393xb-cleanup.patch;patch=1 \
+ file://tosa/0047-tc6393xb-use-bitmasks-instead-of-bit-field-structs.patch;patch=1 \
+ file://tosa/0048-tc6393xb-GPIO-support.patch;patch=1 \
+ file://tosa/0049-platform-support-for-TMIO-on-tosa.patch;patch=1 \
+ file://tosa/0050-tosa-update-for-tc6393xb-gpio.patch;patch=1 \
+ file://tosa/0051-fix-sound-soc-pxa-tosa.c-to-new-gpio-api.patch;patch=1 \
+ file://tosa/0052-tosa-platform-backlight-support.patch;patch=1 \
+ file://tosa/0053-sound-soc-codecs-wm9712.c-28.patch;patch=1 \
+ file://tosa/0054-sound-soc-codecs-wm9712.c-2.patch;patch=1 \
+ file://tosa/0055-Add-GPIO_POWERON-to-the-list-of-devices-that-we-supp.patch;patch=1 \
+ file://tosa/0058-Fix-tosakbd-suspend.patch;patch=1 \
+ file://tosa/0059-patch-tosa-wakeup-test.patch;patch=1 \
+ file://tosa/0060-Add-support-for-power_supply-on-tosa.patch;patch=1 \
+ file://tosa/0061-tosa-bat-unify.patch;patch=1 \
+ file://tosa/0062-tosa-bat-fix-charging.patch;patch=1 \
+ file://tosa/0063-patch-tosa-bat-jacket-detect.patch;patch=1 \
+ file://tosa/0064-Export-modes-via-sysfs.patch;patch=1 \
+ file://tosa/0065-wm97xx-core-fixes.patch;patch=1 \
+ file://tosa/0066-tmiofb_probe-should-be-__devinit.patch;patch=1 \
+ file://tosa/0067-modeswitching.patch;patch=1 \
+ file://tosa/0068-Preliminary-tosa-denoiser.patch;patch=1 \
+ file://tosa/0019-pxa-remove-periodic-mode-emulation-support.patch;patch=1 \
+ file://tosa/0020-Provide-dew-device-clock-backports-from-2.6.24-git.patch;patch=1 \
+ file://tosa/0021-Add-an-empty-drivers-gpio-directory-for-gpiolib-infr.patch;patch=1 \
+ file://tosa/0022-Provide-new-implementation-infrastructure-that-platf.patch;patch=1 \
+ file://tosa/0023-This-adds-gpiolib-support-for-the-PXA-architecture.patch;patch=1 \
+ file://tosa/0024-Update-Documentation-gpio.txt-primarily-to-include.patch;patch=1 \
+ file://tosa/0025-Signed-off-by-Dmitry-Baryshkov-dbaryshkov-gmail.co.patch;patch=1 \
+ file://tosa/0039-Add-generic-framework-for-managing-clocks.patch;patch=1 \
+ file://tosa/0040-Clocklib-debugfs-support.patch;patch=1 \
+ file://tosa/0041-From-80a359e60c2aec59ccf4fca0a7fd20495f82b1d2-Mon-Se.patch;patch=1 \
+ file://tosa/0042-Use-correct-clock-for-IrDA-on-pxa.patch;patch=1 \
+ file://tosa/0043-Use-clocklib-for-sa1100-sub-arch.patch;patch=1 \
+ file://tosa/0056-Support-resetting-by-asserting-GPIO-pin.patch;patch=1 \
+ file://tosa/0057-Clean-up-tosa-resetting.patch;patch=1 \
"
-# ${DOSRC}/tosa-asoc-r1.patch;patch=1 "
SRC_URI_append_akita = "\
file://mtd-module.patch;patch=1;status=external \
diff --git a/packages/linux/linux.inc b/packages/linux/linux.inc
index 835437415f..e0303c272f 100644
--- a/packages/linux/linux.inc
+++ b/packages/linux/linux.inc
@@ -144,6 +144,5 @@ do_deploy() {
do_deploy[dirs] = "${S}"
-addtask sizecheck before do_install after do_compile
addtask deploy before do_package after do_install
diff --git a/packages/linux/linux_2.6.24.bb b/packages/linux/linux_2.6.24.bb
index 40ffef7d0b..4394e4221c 100644
--- a/packages/linux/linux_2.6.24.bb
+++ b/packages/linux/linux_2.6.24.bb
@@ -13,13 +13,12 @@ PR = "r7"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2 \
http://kamikaze.waninkoko.info/patches/2.6.24/kamikaze1/broken-out/squashfs-lzma-2.6.24.patch;patch=1 \
- file://powerpc-clockres.patch;patch=1 \
- file://leds-cpu-activity.patch;patch=1 \
- file://leds-cpu-activity-powerpc.patch;patch=1 \
file://defconfig"
-# Real-time preemption. This is experimental and requires a different defconfig.
-#SRC_URI += " http://www.kernel.org/pub/linux/kernel/projects/rt/patch-2.6.24-rt1.bz2;patch=1"
+# Moved away temporarely until committed properly (work in progress).
+# file://powerpc-clockres.patch;patch=1 \
+# file://leds-cpu-activity.patch;patch=1 \
+# file://leds-cpu-activity-powerpc.patch;patch=1 \
SRC_URI_append_simpad = "\
file://linux-2.6.24-SIMpad-GPIO-MMC-mod.patch;patch=1 \
diff --git a/packages/meta/cross-linkage_1.0.bb b/packages/meta/cross-linkage_1.0.bb
index 2a9caca5da..e840e607b0 100644
--- a/packages/meta/cross-linkage_1.0.bb
+++ b/packages/meta/cross-linkage_1.0.bb
@@ -21,8 +21,14 @@ do_install() {
do_stage () {
install -d ${CROSS_DIR}/${TARGET_SYS}/
- rm -rf ${CROSS_DIR}/${TARGET_SYS}/include
+ if [ -e ${CROSS_DIR}/${TARGET_SYS}/include ]; then
+ cp -pPRr ${CROSS_DIR}/${TARGET_SYS}/include/* ${STAGING_INCDIR}
+ mv ${CROSS_DIR}/${TARGET_SYS}/include/ ${CROSS_DIR}/${TARGET_SYS}/include-oldbackup
+ fi
ln -s ${STAGING_INCDIR}/ ${CROSS_DIR}/${TARGET_SYS}/include
- rm -rf ${CROSS_DIR}/${TARGET_SYS}/lib
+ if [ -e ${CROSS_DIR}/${TARGET_SYS}/lib ]; then
+ cp -pPRr ${CROSS_DIR}/${TARGET_SYS}/lib/* ${STAGING_LIBDIR}
+ mv ${CROSS_DIR}/${TARGET_SYS}/lib/ ${CROSS_DIR}/${TARGET_SYS}/lib-oldbackup
+ fi
ln -s ${STAGING_LIBDIR} ${CROSS_DIR}/${TARGET_SYS}/lib
}
diff --git a/packages/meta/staging-linkage_1.0.bb b/packages/meta/staging-linkage_1.0.bb
index b718868138..d727350f88 100644
--- a/packages/meta/staging-linkage_1.0.bb
+++ b/packages/meta/staging-linkage_1.0.bb
@@ -22,7 +22,7 @@ do_install() {
do_stage () {
if [ -e ${STAGING_DIR_HOST}${layout_base_libdir} ]; then
cp -pPRr ${STAGING_DIR_HOST}${layout_base_libdir}/* ${STAGING_LIBDIR}
- mv ${STAGING_DIR_HOST}${layout_base_libdir}/ ${STAGING_DIR_HOST}${layout_libdir}-oldbackup/
+ mv ${STAGING_DIR_HOST}${layout_base_libdir}/ ${STAGING_DIR_HOST}${layout_libdir}-oldbackup
fi
ln -s ${STAGING_LIBDIR}/ ${STAGING_DIR_HOST}${layout_base_libdir}
}
diff --git a/packages/ncdu/.mtn2git_empty b/packages/ncdu/.mtn2git_empty
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/packages/ncdu/.mtn2git_empty
diff --git a/packages/ncdu/ncdu_1.3.bb b/packages/ncdu/ncdu_1.3.bb
new file mode 100644
index 0000000000..4676a6531e
--- /dev/null
+++ b/packages/ncdu/ncdu_1.3.bb
@@ -0,0 +1,6 @@
+DESCRIPTION = "NCurses Disk Usage"
+DEPENDS = "ncurses"
+
+SRC_URI = "http://dev.yorhel.nl/download/ncdu-${PV}.tar.gz"
+
+inherit autotools
diff --git a/packages/ncurses/ncurses.inc b/packages/ncurses/ncurses.inc
index 2c6cfd05b0..abb9a65a67 100644
--- a/packages/ncurses/ncurses.inc
+++ b/packages/ncurses/ncurses.inc
@@ -21,6 +21,7 @@ EXTRA_OECONF = "--with-shared \
--without-cxx-binding \
--with-terminfo-dirs=${sysconfdir}/terminfo:${datadir}/terminfo \
--enable-overwrite"
+
export BUILD_CCFLAGS = "-I${S}/ncurses -I${S}/include ${BUILD_CFLAGS}"
export BUILD_LDFLAGS = ""
export EXTRA_OEMAKE = '"BUILD_LDFLAGS=" "BUILD_CCFLAGS=${BUILD_CCFLAGS}"'
@@ -80,11 +81,29 @@ pkg_prerm_ncurses-tools () {
update-alternatives --remove reset reset.${PN}
}
-PACKAGES_prepend = "ncurses-tools "
-PACKAGES_append = " ncurses-terminfo"
-FILES_ncurses_append = " ${datadir}/tabset"
-# This keeps only tput/tset in ncurses
-# clear/reset are in already busybox
-FILES_ncurses-tools = "${bindir}/tic ${bindir}/toe ${bindir}/infotocap ${bindir}/captoinfo ${bindir}/infocmp ${bindir}/clear.${PN} ${bindir}/reset.${PN} ${bindir}/tack "
-FILES_ncurses-terminfo = "${datadir}/terminfo"
-FILES_${PN} = "${bindir}/tput ${bindir}/tset ${libdir}/lib*.so.* ยง{datadir}/tabset ${sysconfdir}/terminfo"
+
+PACKAGES =+ "${PN}-ncurses ${PN}-panel ${PN}-menu ${PN}-form ${PN}-terminfo ${PN}-tools"
+FILES_${PN}-ncurses = "${libdir}/libncurses.so.*"
+FILES_${PN}-panel = "${libdir}/libpanel.so.*"
+FILES_${PN}-menu = "${libdir}/libmenu.so.*"
+FILES_${PN}-form = "${libdir}/libform.so.*"
+FILES_${PN}-terminfo = "\
+ ${libdir}/terminfo \
+ ${datadir}/terminfo \
+"
+FILES_${PN}-tools = "\
+ ${bindir}/tic \
+ ${bindir}/tack \
+ ${bindir}/toe \
+ ${bindir}/infotocap \
+ ${bindir}/captoinfo \
+ ${bindir}/infocmp \
+ ${bindir}/clear.${PN} \
+ ${bindir}/reset.${PN} \
+"
+FILES_${PN} = "\
+ ${bindir}/tput \
+ ${bindir}/tset \
+ ${datadir}/tabset \
+ ${sysconfdir}/terminfo \
+"
diff --git a/packages/ncurses/ncurses_5.3.bb b/packages/ncurses/ncurses_5.3.bb
deleted file mode 100644
index 0b0897a409..0000000000
--- a/packages/ncurses/ncurses_5.3.bb
+++ /dev/null
@@ -1,11 +0,0 @@
-BaseV := "${PV}"
-SnapV := "20030906"
-PV = "${BaseV}.${SnapV}"
-PR = "r2"
-
-SRC_URI = "${GNU_MIRROR}/ncurses/ncurses-${BaseV}.tar.gz \
- file://${SnapV}.patch;patch=1 \
- file://configure.patch;patch=1"
-S = "${WORKDIR}/ncurses-${BaseV}"
-
-require ncurses.inc
diff --git a/packages/ncurses/ncurses_5.4.bb b/packages/ncurses/ncurses_5.4.bb
index f361d745b3..7a55baca4d 100644
--- a/packages/ncurses/ncurses_5.4.bb
+++ b/packages/ncurses/ncurses_5.4.bb
@@ -1,7 +1,7 @@
-PR = "r11"
+PR = "r12"
SRC_URI = "${GNU_MIRROR}/ncurses/ncurses-${PV}.tar.gz \
- file://visibility.patch;patch=1"
+ file://visibility.patch;patch=1"
S = "${WORKDIR}/ncurses-${PV}"
require ncurses.inc
diff --git a/packages/openttd/openttd_0.4.0.1.bb b/packages/openttd/openttd_0.4.0.1.bb
deleted file mode 100644
index 9dab970849..0000000000
--- a/packages/openttd/openttd_0.4.0.1.bb
+++ /dev/null
@@ -1,33 +0,0 @@
-require openttd.inc
-
-PR = "r2"
-
-EXTRA_OEMAKE = "WITH_ZLIB=1 \
- WITH_PNG=1 \
- WITH_SDL=1 \
- UNIX=1 \
- WITH_NETWORK=1 \
- VERBOSE=1 \
- INSTALL=1 \
- PREFIX=/usr \
- BINARY_DIR=bin \
- DATA_DIR=share/games/openttd \
- PERSONAL_DIR=.openttd \
- USE_HOMEDIR=1 \
- CC_HOST=gcc \
- CC_TARGET=${TARGET_SYS}-gcc"
-
-do_configure() {
- :
-}
-
-do_install() {
- oe_runmake install DESTDIR="${D}"
-
- install -d ${D}${datadir}/games/openttd/scenario/
- install -d ${D}${datadir}/games/openttd/data
-
- install -m 0644 ${S}/scenario/*.scn ${D}${datadir}/games/openttd/scenario/
- install -m 0644 ${S}/data/*.grf ${D}${datadir}/games/openttd/data/
-}
-
diff --git a/packages/python/python-2.5-manifest.inc b/packages/python/python-2.5-manifest.inc
index 5288bafbf4..9c4e68dfce 100644
--- a/packages/python/python-2.5-manifest.inc
+++ b/packages/python/python-2.5-manifest.inc
@@ -1,5 +1,5 @@
-########################################################################################################################
-### AUTO-GENERATED by './generate-manifest-2.5.py' [(C) 2002-2008 Michael 'Mickey' Lauer <mlauer@vanille-media.de>] on Wed Feb 27 13:29:38 2008
+#######################################################################################################################
+### AUTO-GENERATED by './contrib/python/generate-manifest-2.5.py' [(C) 2002-2008 Michael 'Mickey' Lauer <mlauer@vanille-media.de>] on Thu Mar 6 18:04:21 2008
###
### Visit THE Python for Embedded Systems Site => http://www.Vanille.de/projects/python.spy
###
@@ -127,7 +127,7 @@ PR_python-unixadmin="ml0"
RDEPENDS_python-unixadmin="python-core"
FILES_python-unixadmin="${libdir}/python2.5/lib-dynload/nis.so ${libdir}/python2.5/lib-dynload/grp.so ${libdir}/python2.5/lib-dynload/pwd.so ${libdir}/python2.5/getpass.* "
-DESCRIPTION_python-syslog="Python's syslog Interface"
+DESCRIPTION_python-syslog="Python's Syslog Interface"
PR_python-syslog="ml0"
RDEPENDS_python-syslog="python-core"
FILES_python-syslog="${libdir}/python2.5/lib-dynload/syslog.so "
@@ -213,9 +213,9 @@ RDEPENDS_python-mime="python-core python-io"
FILES_python-mime="${libdir}/python2.5/mimetools.* ${libdir}/python2.5/uu.* ${libdir}/python2.5/quopri.* ${libdir}/python2.5/rfc822.* "
DESCRIPTION_python-sqlite3="Python Sqlite3 Database Support"
-PR_python-sqlite3="ml0"
+PR_python-sqlite3="ml1"
RDEPENDS_python-sqlite3="python-core"
-FILES_python-sqlite3="${libdir}/python2.5/sqlite3 "
+FILES_python-sqlite3="${libdir}/python2.5/lib-dynload/_sqlite3.so ${libdir}/python2.5/sqlite3 "
DESCRIPTION_python-tests="Python Tests"
PR_python-tests="ml0"
@@ -278,7 +278,7 @@ RDEPENDS_python-db="python-core"
FILES_python-db="${libdir}/python2.5/anydbm.* ${libdir}/python2.5/dumbdbm.* ${libdir}/python2.5/whichdb.* "
DESCRIPTION_python-crypt="Python Basic Cryptographic and Hashing Support"
-PR_python-crypt="ml0"
+PR_python-crypt="ml1"
RDEPENDS_python-crypt="python-core"
FILES_python-crypt="${libdir}/python2.5/hashlib.* ${libdir}/python2.5/md5.* ${libdir}/python2.5/sha.* ${libdir}/python2.5/lib-dynload/crypt.so ${libdir}/python2.5/lib-dynload/_hashlib.so ${libdir}/python2.5/lib-dynload/_sha256.so ${libdir}/python2.5/lib-dynload/_sha512.so "
diff --git a/packages/python/python-gsmd_svn.bb b/packages/python/python-gsmd_svn.bb
index 14d3abd607..e92df762e7 100644
--- a/packages/python/python-gsmd_svn.bb
+++ b/packages/python/python-gsmd_svn.bb
@@ -5,9 +5,9 @@ SECTION = "devel/python"
LICENSE = "LGPL"
DEPENDS = "libgsmd"
PV = "0.02+svnr${SRCREV}"
-PR = "r1"
+PR = "r0"
-SRC_URI = "svn://svn.projects.openmoko.org/svnroot/python-openmoko;module=python-gsmd;proto=http"
+SRC_URI = "svn://svn.projects.openmoko.org/svnroot/python-openmoko/trunk;module=python-gsmd;proto=http"
S = "${WORKDIR}/python-gsmd"
SRCREV_pn-python-gsmd ?= "${AUTOREV}"
diff --git a/packages/python/python-pycairo_1.4.0.bb b/packages/python/python-pycairo_1.4.0.bb
index a74c59fdaa..9bb2fdfcd8 100644
--- a/packages/python/python-pycairo_1.4.0.bb
+++ b/packages/python/python-pycairo_1.4.0.bb
@@ -3,7 +3,7 @@ SECTION = "python-devel"
HOMEPAGE = "http://cairographics.org/pycairo"
LICENSE = "LGPL MPL"
DEPENDS = "cairo"
-PR = "ml0"
+PR = "ml1"
SRC_URI = "http://cairographics.org/releases/pycairo-${PV}.tar.gz"
S = "${WORKDIR}/pycairo-${PV}"
@@ -13,4 +13,7 @@ inherit distutils pkgconfig
do_stage() {
install -d ${STAGING_INCDIR}
install -m 0644 cairo/pycairo.h ${STAGING_INCDIR}
+
+ # nasty pkgconfig fix necessary here
+ sed -i -e s,${STAGING_DIR_NATIVE},, pycairo.pc
}
diff --git a/packages/python/python-pygtk/nodocs.patch b/packages/python/python-pygtk/nodocs.patch
new file mode 100644
index 0000000000..9b2387e959
--- /dev/null
+++ b/packages/python/python-pygtk/nodocs.patch
@@ -0,0 +1,13 @@
+Index: pygtk-2.10.4/Makefile.am
+===================================================================
+--- pygtk-2.10.4.orig/Makefile.am
++++ pygtk-2.10.4/Makefile.am
+@@ -4,7 +4,7 @@ if BUILD_GTK
+ GTK_SUBDIR = gtk
+ endif
+
+-SUBDIRS = codegen . $(GTK_SUBDIR) examples tests docs
++SUBDIRS = codegen . $(GTK_SUBDIR) examples tests
+
+ PLATFORM_VERSION = 2.0
+
diff --git a/packages/python/python-pygtk_2.10.4.bb b/packages/python/python-pygtk_2.10.4.bb
index 1af2093556..57dc48aa77 100644
--- a/packages/python/python-pygtk_2.10.4.bb
+++ b/packages/python/python-pygtk_2.10.4.bb
@@ -6,10 +6,11 @@ RDEPENDS = "python-shell python-pycairo python-pygobject"
PROVIDES = "python-pygtk2"
SRCNAME = "pygtk"
LICENSE = "LGPL"
-PR = "ml5"
+PR = "ml6"
SRC_URI = "ftp://ftp.gnome.org/pub/gnome/sources/pygtk/2.10/${SRCNAME}-${PV}.tar.bz2 \
file://fix-gtkunixprint.patch;patch=1 \
+ file://nodocs.patch;patch=1 \
file://acinclude.m4"
S = "${WORKDIR}/${SRCNAME}-${PV}"
diff --git a/packages/python/python-pyiw_0.3.3.bb b/packages/python/python-pyiw_0.3.3.bb
index aa86a07e8f..aaa18c7ee9 100644
--- a/packages/python/python-pyiw_0.3.3.bb
+++ b/packages/python/python-pyiw_0.3.3.bb
@@ -5,25 +5,24 @@ SECTION = "devel/python"
PRIORITY = "optional"
LICENSE = "GPL"
DEPENDS = "wireless-tools"
-RDEPENDS = "python-core libiw"
+RDEPENDS = "python-core"
PR = "ml0"
+inherit autotools pkgconfig distutils-base
+
+CFLAGS += "-I${STAGING_INCDIR}/${PYTHON_DIR}"
+
SRC_URI = "http://downloads.emperorlinux.com/contrib/pyiw/pyiw-${PV}.tbz2 \
file://Makefile"
-
-S="${WORKDIR}/pyiw-${PV}"
+S = "${WORKDIR}/pyiw-${PV}"
do_unpack_real () {
- tar jxvf pyiw-${PV}.tbz2
+ tar jxvf ${DL_DIR}/pyiw-${PV}.tbz2
cp Makefile pyiw-${PV}/
}
do_unpack_real[dirs] = "${WORKDIR}"
addtask unpack_real before do_patch after do_unpack
-inherit autotools pkgconfig distutils-base
-
-CFLAGS += "-I${STAGING_INCDIR}/${PYTHON_DIR}"
-
do_install() {
install -d ${D}${libdir}/${PYTHON_DIR}/site-packages/
install -m 0755 pyiw.so ${D}${libdir}/${PYTHON_DIR}/site-packages/pyiw.so
diff --git a/packages/python/python_2.5.2.bb b/packages/python/python_2.5.2.bb
index e6667cc04b..af907f23c9 100644
--- a/packages/python/python_2.5.2.bb
+++ b/packages/python/python_2.5.2.bb
@@ -5,9 +5,7 @@ SECTION = "devel/python"
PRIORITY = "optional"
DEPENDS = "python-native readline zlib gdbm openssl sqlite3 tcl tk"
DEPENDS_sharprom = "python-native readline zlib gdbm openssl"
-
-# NOTE: Keep the digit in sync with BASEREV in contrib/generate-manifest-2.5.py
-PR = "ml0"
+PR = "ml1"
PYTHON_MAJMIN = "2.5"
@@ -82,11 +80,10 @@ do_install() {
require python-${PYTHON_MAJMIN}-manifest.inc
-# manual additions
+# manual dependency additions
RPROVIDES_python-core = "python"
RRECOMMENDS_python-core = "python-readline"
RRECOMMENDS_python-crypt = "openssl"
-PR_python-crypt = "ml1"
# add sitecustomize
FILES_python-core += "${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py"
diff --git a/packages/tasks/task-python-everything.bb b/packages/tasks/task-python-everything.bb
index 18455f5b96..e4a185dde8 100644
--- a/packages/tasks/task-python-everything.bb
+++ b/packages/tasks/task-python-everything.bb
@@ -1,7 +1,7 @@
DESCRIPTION= "Everything Python"
HOMEPAGE = "http://www.vanille.de/projects/python.spy"
LICENSE = "MIT"
-PR = "ml26"
+PR = "ml27"
RDEPENDS = "\
python-ao \
@@ -10,14 +10,15 @@ RDEPENDS = "\
python-dbus \
python-dialog \
python-pydirectfb \
- python-efl \
- python-efl-examples \
+ task-python-efl \
+ task-python-efl-examples \
python-pycurl \
python-fam \
python-fnorb \
python-formencode \
python-fpconst \
python-fuse \
+ python-gammu \
python-gmpy \
python-gnosis \
python-gsmd \
@@ -32,6 +33,7 @@ RDEPENDS = "\
python-libgmail \
python-lightmediascanner \
python-lxml \
+ python-m2crypto \
python-mad \
python-numarray \
python-numeric \
@@ -90,8 +92,6 @@ RDEPENDS = "\
BROKEN_PACKAGES = "\
python-egenix-mx-base \
- python-gammu \
- python-m2crypto \
python-mysqldb \
python-pyqwt \
"
diff --git a/packages/wireless-tools/wireless-tools.inc b/packages/wireless-tools/wireless-tools.inc
index 857f63c91b..36ee3eddef 100644
--- a/packages/wireless-tools/wireless-tools.inc
+++ b/packages/wireless-tools/wireless-tools.inc
@@ -4,10 +4,15 @@ SECTION = "base"
PRIORITY = "optional"
LICENSE = "GPL"
-SRC_URI = "file://man.patch;patch=1 \
- file://wireless-tools.if-pre-up"
+SRC_URI += "\
+ http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.${PV}.tar.gz \
+ file://man.patch;patch=1 \
+ file://wireless-tools.if-pre-up \
+ file://zzz-wireless.if-pre-up"
+S = "${WORKDIR}/wireless_tools.${PV}"
CFLAGS =+ "-I${S}"
+
EXTRA_OEMAKE = "-e 'BUILD_SHARED=y' \
'INSTALL_DIR=${D}${base_sbindir}' \
'INSTALL_LIB=${D}${libdir}' \
@@ -24,6 +29,15 @@ do_stage() {
oe_libinstall -a -so libiw ${STAGING_LIBDIR}/
}
+do_install() {
+ oe_runmake PREFIX=${D} install-iwmulticall install-dynamic install-man install-hdr
+ install -d ${D}${sbindir}
+ install -m 0755 ifrename ${D}${sbindir}/ifrename
+ install -d ${D}${sysconfdir}/network/if-pre-up.d
+ install ${WORKDIR}/wireless-tools.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/wireless-tools
+ install ${WORKDIR}/zzz-wireless.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/zzz-wireless
+}
+
PACKAGES += "libiw libiw-dev libiw-doc libiw-dbg ifrename ifrename-dbg ifrename-doc"
FILES_libiw += "${libdir}/*.so.*"
FILES_libiw-dbg += "${libdir}/.debug/*.so.*"
diff --git a/packages/wireless-tools/wireless-tools_28+29pre10.bb b/packages/wireless-tools/wireless-tools_28+29pre10.bb
deleted file mode 100644
index cf519cd9f1..0000000000
--- a/packages/wireless-tools/wireless-tools_28+29pre10.bb
+++ /dev/null
@@ -1,14 +0,0 @@
-require wireless-tools.inc
-
-PR = "r3"
-
-SRC_URI += "http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.29.pre10.tar.gz"
-S = "${WORKDIR}/wireless_tools.29"
-
-do_install() {
- oe_runmake PREFIX=${D} install-iwmulticall install-dynamic install-man install-hdr
- install -d ${D}${sbindir}
- install -m 0755 ifrename ${D}${sbindir}/ifrename
- install -d ${D}${sysconfdir}/network/if-pre-up.d
- install ${WORKDIR}/wireless-tools.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/wireless-tools
-}
diff --git a/packages/wireless-tools/wireless-tools_28+29pre21.bb b/packages/wireless-tools/wireless-tools_28+29pre21.bb
deleted file mode 100644
index 41bd546b6d..0000000000
--- a/packages/wireless-tools/wireless-tools_28+29pre21.bb
+++ /dev/null
@@ -1,16 +0,0 @@
-require wireless-tools.inc
-
-PR = "r1"
-
-SRC_URI += "http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.29.pre21.tar.gz \
- file://zzz-wireless.if-pre-up"
-S = "${WORKDIR}/wireless_tools.29"
-
-do_install() {
- oe_runmake PREFIX=${D} install-iwmulticall install-dynamic install-man install-hdr
- install -d ${D}${sbindir}
- install -m 0755 ifrename ${D}${sbindir}/ifrename
- install -d ${D}${sysconfdir}/network/if-pre-up.d
- install ${WORKDIR}/wireless-tools.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/wireless-tools
- install ${WORKDIR}/zzz-wireless.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/zzz-wireless
-}
diff --git a/packages/wireless-tools/wireless-tools_28.bb b/packages/wireless-tools/wireless-tools_28.bb
deleted file mode 100644
index 92a49daae2..0000000000
--- a/packages/wireless-tools/wireless-tools_28.bb
+++ /dev/null
@@ -1,14 +0,0 @@
-require wireless-tools.inc
-
-PR = "r1"
-
-SRC_URI += "http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/wireless_tools.28.pre13.tar.gz \
- file://zzz-wireless.if-pre-up"
-S = "${WORKDIR}/wireless_tools.28"
-
-do_install() {
- oe_runmake PREFIX=${D} install-iwmulticall install-dynamic
- install -d ${D}${sysconfdir}/network/if-pre-up.d
- install ${WORKDIR}/wireless-tools.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/wireless-tools
- install ${WORKDIR}/zzz-wireless.if-pre-up ${D}${sysconfdir}/network/if-pre-up.d/zzz-wireless
-}