diff options
Diffstat (limited to 'packages')
211 files changed, 24728 insertions, 1405 deletions
diff --git a/packages/apmd/files/90-wifi-off b/packages/apmd/files/90-wifi-off index c54936c4be..645484b8cd 100644 --- a/packages/apmd/files/90-wifi-off +++ b/packages/apmd/files/90-wifi-off @@ -3,7 +3,7 @@ # # turn off wifi cards before suspend so they are fully reloaded upon resume -wifislot = `pccardctl ls|egrep '(hostap|orinoco)'|cut -f 2 -d " "` +wifislot = `pccardctl ls|egrep '(hostap|orinoco|libertas)'|cut -f 2 -d " "` if test $wifislot then for slot in $wifislot; do 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/dbus/dbus-1.0.2/.mtn2git_empty b/packages/dbench/files/.mtn2git_empty index e69de29bb2..e69de29bb2 100644 --- a/packages/dbus/dbus-1.0.2/.mtn2git_empty +++ 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-1.0.3/.mtn2git_empty b/packages/dbus/dbus-1.0.3/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/dbus/dbus-1.0.3/.mtn2git_empty diff --git a/packages/dbus/dbus-1.0.2/cross.patch b/packages/dbus/dbus-1.0.3/cross.patch index 268a3ae3de..268a3ae3de 100644 --- a/packages/dbus/dbus-1.0.2/cross.patch +++ b/packages/dbus/dbus-1.0.3/cross.patch diff --git a/packages/dbus/dbus-1.0.2/dbus-1.init b/packages/dbus/dbus-1.0.3/dbus-1.init index 0725083c69..0725083c69 100644 --- a/packages/dbus/dbus-1.0.2/dbus-1.init +++ b/packages/dbus/dbus-1.0.3/dbus-1.init diff --git a/packages/dbus/dbus-1.0.2/fix-install-daemon.patch b/packages/dbus/dbus-1.0.3/fix-install-daemon.patch index c31786357d..c31786357d 100644 --- a/packages/dbus/dbus-1.0.2/fix-install-daemon.patch +++ b/packages/dbus/dbus-1.0.3/fix-install-daemon.patch diff --git a/packages/dbus/dbus-1.0.2/fix-waitpid.patch b/packages/dbus/dbus-1.0.3/fix-waitpid.patch index 80c431809c..80c431809c 100644 --- a/packages/dbus/dbus-1.0.2/fix-waitpid.patch +++ b/packages/dbus/dbus-1.0.3/fix-waitpid.patch diff --git a/packages/dbus/dbus-1.0.2/tmpdir.patch b/packages/dbus/dbus-1.0.3/tmpdir.patch index 838b903f0a..838b903f0a 100644 --- a/packages/dbus/dbus-1.0.2/tmpdir.patch +++ b/packages/dbus/dbus-1.0.3/tmpdir.patch diff --git a/packages/dbus/dbus-native_1.0.2.bb b/packages/dbus/dbus-native_1.0.3.bb index 0149ab374f..195557b35b 100644 --- a/packages/dbus/dbus-native_1.0.2.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/dbus/dbus_1.0.2.bb b/packages/dbus/dbus_1.0.3.bb index 6a54a62d9a..6a54a62d9a 100644 --- a/packages/dbus/dbus_1.0.2.bb +++ b/packages/dbus/dbus_1.0.3.bb diff --git a/packages/dropbear/dropbear-0.50/.mtn2git_empty b/packages/dropbear/dropbear-0.50/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/dropbear/dropbear-0.50/.mtn2git_empty diff --git a/packages/dropbear/dropbear-0.50/configure.patch b/packages/dropbear/dropbear-0.50/configure.patch new file mode 100644 index 0000000000..fa24efc066 --- /dev/null +++ b/packages/dropbear/dropbear-0.50/configure.patch @@ -0,0 +1,27 @@ +Index: dropbear-0.50/configure.in +=================================================================== +--- dropbear-0.50.orig/configure.in ++++ dropbear-0.50/configure.in +@@ -164,14 +164,20 @@ AC_ARG_ENABLE(openpty, + AC_MSG_NOTICE(Not using openpty) + else + AC_MSG_NOTICE(Using openpty if available) +- AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY,,Have openpty() function)]) ++ AC_SEARCH_LIBS(openpty, util, [dropbear_cv_func_have_openpty=yes]) + fi + ], + [ + AC_MSG_NOTICE(Using openpty if available) +- AC_SEARCH_LIBS(openpty, util, [AC_DEFINE(HAVE_OPENPTY)]) ++ AC_SEARCH_LIBS(openpty, util, [dropbear_cv_func_have_openpty=yes]) + ] + ) ++ ++if test "x$dropbear_cv_func_have_openpty" = "xyes"; then ++ AC_DEFINE(HAVE_OPENPTY,,Have openpty() function) ++ no_ptc_check=yes ++ no_ptmx_check=yes ++fi + + + AC_ARG_ENABLE(syslog, diff --git a/packages/dropbear/dropbear-0.50/fix-2kb-keys.patch b/packages/dropbear/dropbear-0.50/fix-2kb-keys.patch new file mode 100644 index 0000000000..bb7a4d32ac --- /dev/null +++ b/packages/dropbear/dropbear-0.50/fix-2kb-keys.patch @@ -0,0 +1,12 @@ +Index: dropbear-0.50/kex.h +=================================================================== +--- dropbear-0.50.orig/kex.h ++++ dropbear-0.50/kex.h +@@ -59,6 +59,6 @@ struct KEXState { + + }; + +-#define MAX_KEXHASHBUF 2000 ++#define MAX_KEXHASHBUF 3000 + + #endif /* _KEX_H_ */ diff --git a/packages/dropbear/dropbear-0.50/urandom-xauth-changes-to-options.h.patch b/packages/dropbear/dropbear-0.50/urandom-xauth-changes-to-options.h.patch new file mode 100644 index 0000000000..787b801643 --- /dev/null +++ b/packages/dropbear/dropbear-0.50/urandom-xauth-changes-to-options.h.patch @@ -0,0 +1,13 @@ +Index: dropbear-0.50/options.h +=================================================================== +--- dropbear-0.50.orig/options.h ++++ dropbear-0.50/options.h +@@ -197,7 +197,7 @@ etc) slower (perhaps by 50%). Recommende + /* The command to invoke for xauth when using X11 forwarding. + * "-q" for quiet */ + #ifndef XAUTH_COMMAND +-#define XAUTH_COMMAND "/usr/X11R6/bin/xauth -q" ++#define XAUTH_COMMAND "xauth -q" + #endif + + /* if you want to enable running an sftp server (such as the one included with diff --git a/packages/dropbear/dropbear/chansession-security-fix.patch b/packages/dropbear/dropbear/chansession-security-fix.patch deleted file mode 100644 index bc4c461fee..0000000000 --- a/packages/dropbear/dropbear/chansession-security-fix.patch +++ /dev/null @@ -1,74 +0,0 @@ -Date: Sun, 11 Dec 2005 23:30:02 +0800 -From: Matt Johnston <matt@ucc.asn.au> -To: dropbear@ucc.gu.uwa.edu.au -Subject: Dropbear 0.47 (and security fix) -Message-ID: <20051211153002.GH28839@ucc.gu.uwa.edu.au> - -Hi all. - -I've put up a new release 0.47 of Dropbear, which has -various fixes and new features - see the change summary -below. -http://matt.ucc.asn.au/dropbear/dropbear.html is the -url as usual or directly at -http://matt.ucc.asn.au/dropbear/dropbear-0.47.tar.bz2 - -This release also fixes a potential security issue, which -may allow authenticated users to run arbitrary code as the -server user. I'm unsure exactly how likely it is to be -exploitable, but anyone who's running a multi-user server is -advised to upgrade. For older releases, the patch is: -(against chanesssion.c for 0.43 and earlier). - ---- dropbear/svr-chansession.c -+++ dropbear/svr-chansession.c -@@ -810,7 +810,7 @@ - /* need to increase size */ - if (i == svr_ses.childpidsize) { - svr_ses.childpids = (struct ChildPid*)m_realloc(svr_ses.childpids, -- sizeof(struct ChildPid) * svr_ses.childpidsize+1); -+ sizeof(struct ChildPid) * (svr_ses.childpidsize+1)); - svr_ses.childpidsize++; - } - - -Matt - - -0.47 - Thurs Dec 8 2005 - -- SECURITY: fix for buffer allocation error in server code, could potentially - allow authenticated users to gain elevated privileges. All multi-user systems - running the server should upgrade (or apply the patch available on the - Dropbear webpage). - -- Fix channel handling code so that redirecting to /dev/null doesn't use - 100% CPU. - -- Turn on zlib compression for dbclient. - -- Set "low delay" TOS bit, can significantly improve interactivity - over some links. - -- Added client keyboard-interactive mode support, allows operation with - newer OpenSSH servers in default config. - -- Log when pubkey auth fails because of bad ~/.ssh/authorized_keys permissions - -- Improve logging of assertions - -- Added aes-256 cipher and sha1-96 hmac. - -- Fix twofish so that it actually works. - -- Improve PAM prompt comparison. - -- Added -g (dbclient) and -a (dropbear server) options to allow - connections to listening forwarded ports from remote machines. - -- Various other minor fixes - -- Compile fixes for glibc 2.1 (ss_family vs __ss_family) and NetBSD - (netinet/in_systm.h needs to be included). - - diff --git a/packages/dropbear/dropbear_0.45.bb b/packages/dropbear/dropbear_0.45.bb deleted file mode 100644 index 68c6e87e75..0000000000 --- a/packages/dropbear/dropbear_0.45.bb +++ /dev/null @@ -1,5 +0,0 @@ -require dropbear.inc - -PR = "r4" - -SRC_URI += "file://chansession-security-fix.patch;patch=1 " diff --git a/packages/dropbear/dropbear_0.46.bb b/packages/dropbear/dropbear_0.46.bb deleted file mode 100644 index d34787fa64..0000000000 --- a/packages/dropbear/dropbear_0.46.bb +++ /dev/null @@ -1,5 +0,0 @@ -require dropbear.inc - -PR = "r6" - -SRC_URI += "file://chansession-security-fix.patch;patch=1 " diff --git a/packages/dropbear/dropbear_0.47.bb b/packages/dropbear/dropbear_0.47.bb deleted file mode 100644 index b8467e1e7c..0000000000 --- a/packages/dropbear/dropbear_0.47.bb +++ /dev/null @@ -1,3 +0,0 @@ -require dropbear.inc - -PR = "r2" diff --git a/packages/dropbear/dropbear_0.48.1.bb b/packages/dropbear/dropbear_0.48.1.bb deleted file mode 100644 index f98c0ac8f6..0000000000 --- a/packages/dropbear/dropbear_0.48.1.bb +++ /dev/null @@ -1 +0,0 @@ -require dropbear.inc diff --git a/packages/dropbear/dropbear_0.50.bb b/packages/dropbear/dropbear_0.50.bb new file mode 100644 index 0000000000..21d46ef59c --- /dev/null +++ b/packages/dropbear/dropbear_0.50.bb @@ -0,0 +1,6 @@ +PR = "r0" + +require dropbear.inc + +# testing +DEFAULT_PREFERENCE = "-1" diff --git a/packages/gcc/gcc-cross-initial_csl-arm-2005q3.bb b/packages/gcc/gcc-cross-initial_csl-arm-2005q3.bb index 1639511362..aff22fb694 100644 --- a/packages/gcc/gcc-cross-initial_csl-arm-2005q3.bb +++ b/packages/gcc/gcc-cross-initial_csl-arm-2005q3.bb @@ -1,2 +1,2 @@ -require gcc-cross_${PV}.bb +require gcc-cross_csl-arm-2005q3.bb require gcc-cross-initial.inc diff --git a/packages/gcc/gcc-cross-kernel-3.4.4_csl-arm-2005q3.bb b/packages/gcc/gcc-cross-kernel-3.4.4_csl-arm-2005q3.bb index 4b7e7b715c..d9c818979c 100644 --- a/packages/gcc/gcc-cross-kernel-3.4.4_csl-arm-2005q3.bb +++ b/packages/gcc/gcc-cross-kernel-3.4.4_csl-arm-2005q3.bb @@ -7,7 +7,7 @@ SECTION = "devel" # cut-down gcc for kernel builds # only installs ${TARGET_PREFIX}gcc-${PV}, not ${TARGET_PREFIX}gcc. -require gcc-cross-initial_${PV}.bb +require gcc-cross-initial_csl-arm-2005q3.bb PROVIDES = "virtual/${TARGET_PREFIX}gcc-${PV}" diff --git a/packages/gcc/gcc-package-sdk.inc b/packages/gcc/gcc-package-sdk.inc index c3ba231678..635ab6d1f4 100644 --- a/packages/gcc/gcc-package-sdk.inc +++ b/packages/gcc/gcc-package-sdk.inc @@ -1,18 +1,58 @@ -# Packages emitted by our gcc-cross builds. # +# Note gcc-package.inc was already included before us. +# +# We override PACKAGES and FILES to change the packaging +# + INHIBIT_PACKAGE_STRIP ?= "" +HAS_G2C ?= "yes" +HAS_GFORTRAN ?= "no" OLD_INHIBIT_PACKAGE_STRIP := "${INHIBIT_PACKAGE_STRIP}" INHIBIT_PACKAGE_STRIP = "1" -python do_package() { - if bb.data.getVar('DEBIAN_NAMES', d, 1): - bb.data.setVar('PKG_libgcc', 'libgcc1', d) - bb.build.exec_func('package_do_package', d) -} +# Having anything auto depending on gcc-cross-sdk is a really bad idea... +EXCLUDE_FROM_SHLIBS = "1" + +PACKAGES = "${PN} ${PN}-doc" +FILES_${PN} = "\ + ${bindir}/* \ + ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/cc1 \ + ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/collect2 \ + ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/f771 \ + ${libexecdir}/gcc/${TARGET_SYS}/${BINV}/cc1plus \ + ${gcclibdir}/${TARGET_SYS}/${BINV}/*.o \ + ${gcclibdir}/${TARGET_SYS}/${BINV}/specs \ + ${gcclibdir}/${TARGET_SYS}/${BINV}/lib* \ + ${gcclibdir}/${TARGET_SYS}/${BINV}/include \ + ${includedir}/c++/${BINV} \ + ${prefix}/${TARGET_SYS}/bin/* \ + ${prefix}/${TARGET_SYS}/lib/* \ + " do_install () { oe_runmake 'DESTDIR=${D}' install + # Cleanup some of the ${libdir}{,exec}/gcc stuff ... + rm -r ${D}${libdir}/gcc/${TARGET_SYS}/${BINV}/install-tools + rm -r ${D}${libexecdir}/gcc/${TARGET_SYS}/${BINV}/install-tools + + # We care about g++ not c++ + rm -f ${D}${bindir}/*c++ + + # We don't care about the gcc-<version> copies + rm -f ${D}${bindir}/*gcc-?.?* + + # We use libiberty from binutils + rm -f ${D}${prefix}/${TARGET_SYS}/lib/libiberty.a + rm -f ${D}${libdir}/libiberty.a + + # Create the ${prefix}/${TARGET_SYS}/bin/* symlinks + install -d ${D}${prefix}/${TARGET_SYS}/bin/ + for l in ${D}${bindir}/*; do + ln -sf "${bindir}/`basename $l`" "${D}${prefix}/${TARGET_SYS}/bin/`basename $l | sed -e 's,${TARGET_PREFIX},,'`" + done + ln -sf "${bindir}/${TARGET_PREFIX}gcc" "${D}${prefix}/${TARGET_SYS}/bin/cc" + # Manually run the target stripper since we won't get it run by # the packaging. if [ "x${OLD_INHIBIT_PACKAGE_STRIP}" != "x1" ]; then @@ -22,15 +62,3 @@ do_install () { fi } -FILES_libgcc = "${prefix}/${TARGET_SYS}/lib/libgcc*.so.*" -FILES_libgcc-dev = "${prefix}/${TARGET_SYS}/lib/libgcc*.so" - -FILES_libstdc++ = "${prefix}/${TARGET_SYS}/lib/libstdc++.so.*" -FILES_libstdc++-dev = "${includedir}/c++/${BINV} \ - ${prefix}/${TARGET_SYS}/lib/libstdc++.so \ - ${prefix}/${TARGET_SYS}/lib/libstdc++.a \ - ${prefix}/${TARGET_SYS}/lib/libsupc++.a" - -FILES_libmudflap = "${prefix}/${TARGET_SYS}/lib/libmudflap*.so.*" -FILES_libmudflap-dev = "${prefix}/${TARGET_SYS}/lib/libmudflap*.so \ - ${prefix}/${TARGET_SYS}/lib/libmudflap*.a" diff --git a/packages/gcc/gcc4-build-sdk.inc b/packages/gcc/gcc4-build-sdk.inc index d6af5fe933..b66c716505 100644 --- a/packages/gcc/gcc4-build-sdk.inc +++ b/packages/gcc/gcc4-build-sdk.inc @@ -1,12 +1,40 @@ USE_NLS = '${@base_conditional( "TARGET_OS", "linux-uclibc", "no", "", d )}' USE_NLS = '${@base_conditional( "TARGET_OS", "linux-uclibcgnueabi", "no", "", d )}' -EXTRA_OECONF += "--with-sysroot=${prefix}/${TARGET_SYS} --with-build-sysroot=${STAGING_DIR_TARGET}" +EXTRA_OECONF_PATHS = "--with-local-prefix=${STAGING_DIR_TARGET}${layout_prefix} \ + --with-gxx-include-dir=${STAGING_DIR_TARGET}/${layout_includedir}/c++ \ + --with-sysroot=${prefix}/${TARGET_SYS} \ + --with-build-sysroot=${STAGING_DIR_TARGET}" + +# +# gcc-cross looks and finds these in ${exec_prefix} but we're not so lucky +# for the sdk. Hardcoding the paths ensures the build doesn't go canadian or worse. +# +export AR_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/ar" +export AS_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/as" +export DLLTOOL_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/dlltool" +export LD_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/ld" +export LIPO_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/lipo" +export NM_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/nm" +export OBJDUMP_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/objdump" +export RANLIB_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/ranlib" +export STRIP_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/strip" +export WINDRES_FOR_TARGET = "${CROSS_DIR}/${TARGET_SYS}/bin/windres" + +# +# We need to override this and make sure the compiler can find staging +# +export ARCH_FLAGS_FOR_TARGET = "--sysroot=/media/build1/builds/oe/angstrom/tmp/staging/arm-angstrom-linux-gnueabi" do_configure () { - (cd ${S} && gnu-configize) || die "failure running gnu-configize" - (cd ${S}/libstdc++-v3 && autoreconf) - oe_runconf + export CC_FOR_BUILD="${BUILD_CC}" + export CXX_FOR_BUILD="${BUILD_CXX}" + export CFLAGS_FOR_BUILD="${BUILD_CFLAGS}" + export CPPFLAGS_FOR_BUILD="${BUILD_CPPFLAGS}" + export CXXFLAGS_FOR_BUILD="${BUILD_CXXFLAGS}" + export LDFLAGS_FOR_BUILD="${BUILD_LDFLAGS}" + (cd ${S} && gnu-configize) || die "failure running gnu-configize" + oe_runconf } do_compile () { @@ -16,5 +44,5 @@ do_compile () { export LD_FOR_TARGET="${TARGET_SYS}-ld" export NM_FOR_TARGET="${TARGET_SYS}-nm" export CC_FOR_TARGET="${CCACHE} ${TARGET_SYS}-gcc ${TARGET_CC_ARCH}" - oe_runmake + base_do_compile } diff --git a/packages/gcc/gcc_csl-arm-2005q3.bb b/packages/gcc/gcc_csl-arm-2005q3.bb index 4c8f8227a9..b90f6907bb 100644 --- a/packages/gcc/gcc_csl-arm-2005q3.bb +++ b/packages/gcc/gcc_csl-arm-2005q3.bb @@ -4,6 +4,7 @@ SECTION = "devel" LICENSE = "GPL" BINV = "3.4.4" PV = "3.4.4+csl-arm-2005q3" +PV_chinook-compat = "3.4.4cs2005q3.2" PR = "r3" FILESDIR = "${FILE_DIRNAME}/gcc-csl-arm" 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/gnutls/gnutls.inc b/packages/gnutls/gnutls.inc index 781267093c..6400e80b11 100644 --- a/packages/gnutls/gnutls.inc +++ b/packages/gnutls/gnutls.inc @@ -7,10 +7,10 @@ SRC_URI = "ftp://ftp.gnutls.org/pub/gnutls/gnutls-${PV}.tar.bz2" inherit autotools binconfig pkgconfig -EXTRA_OECONF="--with-included-opencdk --with-included-libtasn1" +EXTRA_OECONF = "--with-included-opencdk --with-included-libtasn1" # fix wrong dependency -do_configure_append() { +do_configure_prepend() { sed -i s,gcrypt,libgcrypt, lib/gnutls.pc.in } diff --git a/packages/gnutls/gnutls_1.4.5.bb b/packages/gnutls/gnutls_1.4.5.bb index 4c247717ae..749064af65 100644 --- a/packages/gnutls/gnutls_1.4.5.bb +++ b/packages/gnutls/gnutls_1.4.5.bb @@ -1,3 +1,3 @@ require gnutls.inc -PR = "r2" +PR = "r3" diff --git a/packages/gnutls/gnutls_1.6.3.bb b/packages/gnutls/gnutls_1.6.3.bb index cc35d8b7a3..ce10a4b6cf 100644 --- a/packages/gnutls/gnutls_1.6.3.bb +++ b/packages/gnutls/gnutls_1.6.3.bb @@ -6,4 +6,4 @@ SRC_URI += "\ file://configure_madness.patch;patch=1 \ " -PR = "r5" +PR = "r6" 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/kismet/kismet-2007-10-R1/.mtn2git_empty b/packages/kismet/kismet-2007-10-R1/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/kismet/kismet-2007-10-R1/.mtn2git_empty diff --git a/packages/kismet/kismet.inc b/packages/kismet/kismet.inc index 57298c5c00..efc987cf0c 100644 --- a/packages/kismet/kismet.inc +++ b/packages/kismet/kismet.inc @@ -11,6 +11,9 @@ EXTRA_OECONF = "--enable-wsp100 --with-pcap=linux \ inherit autotools +# .depend is needed by the main compile but can run in parallel +PARALLE_MAKE = "" + fakeroot do_install() { oe_runmake "DESTDIR=${D}" suidinstall } diff --git a/packages/kismet/kismet_2007-10-R1.bb b/packages/kismet/kismet_2007-10-R1.bb index ef1cf86c98..4786543ec8 100644 --- a/packages/kismet/kismet_2007-10-R1.bb +++ b/packages/kismet/kismet_2007-10-R1.bb @@ -1,3 +1,5 @@ require kismet.inc -PR = "r3" +SRC_URI += "file://fix_strip.patch;patch=1" + +PR = "r5" 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/libsexy/files/libsexy-pkgconfig-fixes.patch b/packages/libsexy/files/libsexy-pkgconfig-fixes.patch index 331b24bf1b..61da9474df 100644 --- a/packages/libsexy/files/libsexy-pkgconfig-fixes.patch +++ b/packages/libsexy/files/libsexy-pkgconfig-fixes.patch @@ -9,7 +9,7 @@ Index: libsexy-0.1.11/libsexy.pc.in -Libs: -L${libdir} -lsexy @PACKAGE_LIBS@ -Cflags: -I${includedir} @PACKAGE_CFLAGS@ -+Requires: pango glib-2.0 gtk+-2.0 libxml ++Requires: pango glib-2.0 gtk+-2.0 libxml-2.0 +Libs: -L${libdir} -lsexy +Cflags: -I${includedir} diff --git a/packages/libspiff/files/autofoo.patch b/packages/libspiff/files/autofoo.patch index 2fcd7ebb47..5f96a2c217 100644 --- a/packages/libspiff/files/autofoo.patch +++ b/packages/libspiff/files/autofoo.patch @@ -1,17 +1,15 @@ -Index: libspiff-0.7.2/configure.in +Index: libspiff-0.8.2/configure.in =================================================================== ---- libspiff-0.7.2.orig/configure.in 2007-08-25 15:47:29.000000000 +0000 -+++ libspiff-0.7.2/configure.in 2007-08-25 15:47:48.000000000 +0000 -@@ -78,26 +78,6 @@ - LDFLAGS="-L${withval} ${LDFLAGS}" - ], []) +--- libspiff-0.8.2.orig/configure.in ++++ libspiff-0.8.2/configure.in +@@ -80,24 +80,6 @@ AC_ARG_WITH(uriparser-lib, [ --with-uri + + -- -- -# Local headers must come very first. Otherwise we -# risk including headers of an already installed -# libSpiff version if its path is in CPPFLAGS --CPPFLAGS="-Iinclude ${CPPFLAGS}" +-CPPFLAGS="-I${srcdir}/include ${CPPFLAGS}" - - - diff --git a/packages/libspiff/libspiff_0.7.2.bb b/packages/libspiff/libspiff_0.8.2.bb index 06be4b3aa4..06be4b3aa4 100644 --- a/packages/libspiff/libspiff_0.7.2.bb +++ b/packages/libspiff/libspiff_0.8.2.bb diff --git a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig index 418a1b4402..cfc7babcef 100644 --- a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig +++ b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig @@ -1031,14 +1031,15 @@ CONFIG_I2C_PXA=m # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 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_TSC2003 is not set +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_TSC2003=m +CONFIG_SENSORS_TSC2003_SYSFS=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1157,8 +1158,8 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set # CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -CONFIG_FONT_7x14=y +CONFIG_FONT_6x11=y +# 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 diff --git a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig-nofb b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig-nofb index 22e0ef0413..3840a395df 100644 --- a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig-nofb +++ b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-connex/defconfig-nofb @@ -1031,14 +1031,15 @@ CONFIG_I2C_PXA=m # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 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_TSC2003 is not set +CONFIG_SENSORS_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_TSC2003=m +CONFIG_SENSORS_TSC2003_SYSFS=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set diff --git a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig index 5a8728d26a..70a733a15c 100644 --- a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig +++ b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig @@ -1058,13 +1058,13 @@ CONFIG_I2C_PXA=m # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 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_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m CONFIG_SENSORS_TSC2003=m CONFIG_SENSORS_TSC2003_SYSFS=m # CONFIG_I2C_DEBUG_CORE is not set @@ -1187,8 +1187,8 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y # CONFIG_FONT_8x8 is not set # CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -CONFIG_FONT_7x14=y +CONFIG_FONT_6x11=y +# 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 @@ -1244,7 +1244,7 @@ CONFIG_SND_PXA2XX_AC97=m # # USB devices # -# CONFIG_SND_USB_AUDIO is not set +CONFIG_SND_USB_AUDIO=m # # PCMCIA devices @@ -1426,7 +1426,7 @@ CONFIG_USB_SERIAL_KEYSPAN_PDA=m # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set +CONFIG_USB_SERIAL_OPTION=m # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_DEBUG is not set CONFIG_USB_EZUSB=y diff --git a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig-nofb b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig-nofb index 0634a90a94..144b3c6e3a 100644 --- a/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig-nofb +++ b/packages/linux/gumstix-kernel-2.6.21/gumstix-custom-verdex/defconfig-nofb @@ -1058,13 +1058,13 @@ CONFIG_I2C_PXA=m # # Miscellaneous I2C Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 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_DS1337=m +CONFIG_SENSORS_DS1374=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_MAX6875=m CONFIG_SENSORS_TSC2003=m CONFIG_SENSORS_TSC2003_SYSFS=m # CONFIG_I2C_DEBUG_CORE is not set @@ -1244,7 +1244,7 @@ CONFIG_SND_PXA2XX_AC97=m # # USB devices # -# CONFIG_SND_USB_AUDIO is not set +CONFIG_SND_USB_AUDIO=m # # PCMCIA devices @@ -1426,7 +1426,7 @@ CONFIG_USB_SERIAL_KEYSPAN_PDA=m # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set +CONFIG_USB_SERIAL_OPTION=m # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_DEBUG is not set CONFIG_USB_EZUSB=y diff --git a/packages/linux/gumstix-kernel-2.6.21/one-wire.patch b/packages/linux/gumstix-kernel-2.6.21/one-wire.patch new file mode 100644 index 0000000000..b4994c3e61 --- /dev/null +++ b/packages/linux/gumstix-kernel-2.6.21/one-wire.patch @@ -0,0 +1,35 @@ +--- linux-2.6.21/drivers/w1/w1.c ++++ linux-2.6.21/drivers/w1/w1.c +@@ -675,7 +675,6 @@ static void w1_slave_found(void *data, u64 rn) + struct w1_slave *sl; + struct list_head *ent; + struct w1_reg_num *tmp; +- int family_found = 0; + struct w1_master *dev; + u64 rn_le = cpu_to_le64(rn); + +@@ -698,9 +697,6 @@ static void w1_slave_found(void *data, u64 rn) + sl->reg_num.crc == tmp->crc) { + set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); + break; +- } else if (sl->reg_num.family == tmp->family) { +- family_found = 1; +- break; + } + + slave_count++; +@@ -874,11 +874,9 @@ void w1_search_process(struct w1_master *dev, u8 search_type) + w1_search_devices(dev, search_type, w1_slave_found); + + list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { +- if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { ++ if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) + w1_slave_detach(sl); +- +- dev->slave_count--; +- } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) ++ else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) + sl->ttl = dev->slave_ttl; + } + + diff --git a/packages/linux/gumstix-kernel-2.6.21/pxafb-backto16.patch b/packages/linux/gumstix-kernel-2.6.21/pxafb-backto16.patch new file mode 100644 index 0000000000..a8b91daf37 --- /dev/null +++ b/packages/linux/gumstix-kernel-2.6.21/pxafb-backto16.patch @@ -0,0 +1,40 @@ +--- linux-2.6.21/arch/arm/mach-pxa/gumstix.c-orig 2008-02-20 16:18:57.000000000 -0800 ++++ linux-2.6.21/arch/arm/mach-pxa/gumstix.c 2008-02-20 16:21:21.000000000 -0800 +@@ -146,8 +146,7 @@ + .pixclock = 110000, + .xres = 480, + .yres = 272, +- .bpp = 18, +- .nonstd = 24, ++ .bpp = 16, + .hsync_len = 41, + .left_margin = 2, + .right_margin = 2, +@@ -161,7 +160,7 @@ + .modes = &gumstix_fb_mode, + .num_modes = 1, + .lccr0 = LCCR0_Act | LCCR0_Sngl | LCCR0_Color, +- .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | (3 << 30), ++ .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | (0 << 30), + .pxafb_backlight_power = &gumstix_lcd_backlight, + }; + #elif defined(CONFIG_FB_PXA_SAMSUNG_LTE430WQ_F0C) +@@ -175,8 +174,7 @@ + .vsync_len = 10, // VLW from datasheet: 10 typ + .upper_margin = 2, // VBP - VLW from datasheet: 12 - 10 = 2 + .lower_margin = 4, // VFP from datasheet: 4 typ +- .bpp = 18, +- .nonstd = 24, ++ .bpp = 16, + .sync = 0, // Hsync and Vsync both active low + }; + +@@ -184,7 +182,7 @@ + .modes = &gumstix_fb_mode, + .num_modes = 1, + .lccr0 = LCCR0_Act | LCCR0_Sngl | LCCR0_Color, +- .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | (3 << 30), ++ .lccr3 = LCCR3_OutEnH | LCCR3_PixFlEdg | (0 << 30), + .pxafb_backlight_power = &gumstix_lcd_backlight, + }; + #endif diff --git a/packages/linux/gumstix-kernel-2.6.21/smc91x-fail-if-no-chip.patch b/packages/linux/gumstix-kernel-2.6.21/smc91x-fail-if-no-chip.patch new file mode 100644 index 0000000000..0d4425412c --- /dev/null +++ b/packages/linux/gumstix-kernel-2.6.21/smc91x-fail-if-no-chip.patch @@ -0,0 +1,58 @@ +--- linux-2.6.21/drivers/net/gumstix-smc91x.c-orig 2008-02-24 22:06:30.000000000 -0800 ++++ linux-2.6.21/drivers/net/gumstix-smc91x.c 2008-02-25 08:12:57.000000000 -0800 +@@ -90,18 +90,42 @@ + pxa_gpio_mode(GPIO49_nPWE_MD); + + pxa_gpio_mode(GPIO78_nCS_2_MD); +- // If either if statement fails, then we'll drop out and turn_off_eth1, ++ ++ // First look for smc91x0 ++ // If either if statement fails, then we'll drop out and turn_off_eth0, ++ // if both succeed, then we'll skip that and just proceed ++ // to test for 2 smc91x chips ++ if(request_mem_region(gumstix_smc91x0_resources[0].start, SMC_IO_EXTENT, "smc91x0 probe")) ++ { ++ ioaddr = ioremap(gumstix_smc91x0_resources[0].start, SMC_IO_EXTENT); ++ val = ioread16(ioaddr + BANK_SELECT); ++ iounmap(ioaddr); ++ release_mem_region(gumstix_smc91x0_resources[0].start, SMC_IO_EXTENT); ++ if ((val & 0xFF00) == 0x3300) { ++ goto proceed; ++ } ++ } ++ ++ printk(KERN_ERR "%s: smc91x chip not found, returning -ENXIO\n", __FUNCTION__); ++ return -ENXIO; ++ ++proceed: ++ printk(KERN_ERR "%s: smc91x chip found\n", __FUNCTION__); ++ ++ // Now look for a second smc91x ++ // If either if statement fails, then we'll drop out and return -ENXIO + // if both succeed, then we'll skip that and just proceed with 2 cards +- if(request_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT, "smc91x probe")) ++ if(request_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT, "smc91x1 probe")) + { + ioaddr = ioremap(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT); + val = ioread16(ioaddr + BANK_SELECT); + iounmap(ioaddr); + release_mem_region(gumstix_smc91x1_resources[0].start, SMC_IO_EXTENT); + if ((val & 0xFF00) == 0x3300) { +- goto proceed; ++ goto proceed1; + } + } ++ + + turn_off_eth1: + // This is apparently not an SMC91C111 +@@ -110,7 +134,8 @@ + smc91x_devices[1] = NULL; + pxa_gpio_mode(78 | GPIO_IN); + +-proceed: ++proceed1: ++ printk(KERN_ERR "%s: found %d smc91x chip(s)\n", __FUNCTION__); + pxa_gpio_mode(GPIO15_nCS_1_MD); + + if(smc91x_devices[1]) pxa_gpio_mode(GPIO_GUMSTIX_ETH1_RST_MD); diff --git a/packages/linux/gumstix-kernel-2.6.21/tsc2003.c b/packages/linux/gumstix-kernel-2.6.21/tsc2003.c index d0f496617e..a4a68b756d 100644 --- a/packages/linux/gumstix-kernel-2.6.21/tsc2003.c +++ b/packages/linux/gumstix-kernel-2.6.21/tsc2003.c @@ -3,6 +3,7 @@ * * Copyright (C) 2005 Bill Gatliff <bgat at billgatliff.com> * Changes for 2.6.20 kernel by Nicholas Chen <nchen at cs.umd.edu> + * Changes for 2.6.21 kernel by Chris Dollar <chris.dollar at gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -25,669 +26,442 @@ #include <linux/delay.h> #include <asm-arm/arch-pxa/irqs.h> -static unsigned short normal_i2c[] -= {0x48, I2C_CLIENT_END }; +#define DRIVER_NAME "tsc2003" +#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1)) +#define ADC_MAX ((1 << 12) - 1) -I2C_CLIENT_INSMOD_1(tsc2003); +//#define CONFIG_I2C_DEBUG_CHIP 1 -#define DRIVER_NAME "tsc2003" +static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD_1(tsc2003); enum tsc2003_pd { - PD_POWERDOWN = 0, /* penirq */ - PD_IREFOFF_ADCON = 1, /* no penirq */ - PD_IREFON_ADCOFF = 2, /* penirq */ - PD_IREFON_ADCON = 3, /* no penirq */ - PD_PENIRQ_ARM = PD_IREFON_ADCOFF, - PD_PENIRQ_DISARM = PD_IREFON_ADCON, + PD_POWERDOWN = 0, /* penirq */ + PD_IREFOFF_ADCON = 1, /* no penirq */ + PD_IREFON_ADCOFF = 2, /* penirq */ + PD_IREFON_ADCON = 3, /* no penirq */ + PD_PENIRQ_ARM = PD_IREFON_ADCOFF, + PD_PENIRQ_DISARM = PD_IREFON_ADCON, }; enum tsc2003_m { - M_12BIT = 0, - M_8BIT = 1 + M_12BIT = 0, + M_8BIT = 1 }; enum tsc2003_cmd { - MEAS_TEMP0 = 0, - MEAS_VBAT1 = 1, - MEAS_IN1 = 2, - MEAS_TEMP1 = 4, - MEAS_VBAT2 = 5, - MEAS_IN2 = 6, - ACTIVATE_NX_DRIVERS = 8, - ACTIVATE_NY_DRIVERS = 9, - ACTIVATE_YNX_DRIVERS = 10, - MEAS_XPOS = 12, - MEAS_YPOS = 13, - MEAS_Z1POS = 14, - MEAS_Z2POS = 15 + MEAS_TEMP0 = 0, + MEAS_VBAT1 = 1, + MEAS_IN1 = 2, + MEAS_TEMP1 = 4, + MEAS_VBAT2 = 5, + MEAS_IN2 = 6, + ACTIVATE_NX_DRIVERS = 8, + ACTIVATE_NY_DRIVERS = 9, + ACTIVATE_YNX_DRIVERS = 10, + MEAS_XPOS = 12, + MEAS_YPOS = 13, + MEAS_Z1POS = 14, + MEAS_Z2POS = 15 }; -#define TSC2003_CMD(cn,pdn,m) (((cn) << 4) | ((pdn) << 2) | ((m) << 1)) - -#define ADC_MAX ((1 << 12) - 1) - struct tsc2003_data { - struct i2c_client client; - struct device_driver driver; - struct input_dev *idev; - struct timer_list penirq_timer; - struct semaphore sem; - struct task_struct *tstask; - struct completion tstask_completion; - struct completion penirq_completion; - enum tsc2003_pd pd; - enum tsc2003_m m; - int penirq; - - int vbat1; - int vbat2; - int temp0; - int temp1; - int in1; - int in2; + struct i2c_client client; + struct device_driver driver; + struct input_dev *idev; + struct semaphore sem; + struct task_struct *tstask; + struct completion tstask_completion; + struct completion penirq_completion; + enum tsc2003_pd pd; + enum tsc2003_m m; + int penirq; + + int vbat1; + int vbat2; + int temp0; + int temp1; + int in1; + int in2; }; -static int tsc2003_i2c_detect (struct i2c_adapter *adapter, int address, -int kind); +static int + tsc2003_i2c_detect(struct i2c_adapter *adapter, int address, int kind); -static inline int tsc2003_command (struct tsc2003_data *data, - enum tsc2003_cmd cmd, - enum tsc2003_pd pd) -{ - char c; - int ret; - down(&data->sem); - c = TSC2003_CMD(cmd, pd, data->m); - ret = i2c_master_send(&data->client, &c, 1); - up(&data->sem); - return ret; -} +static int tsc2003_read(struct tsc2003_data *data, enum tsc2003_cmd cmd, + enum tsc2003_pd pd, int *val) { + char c; + char d[2]; + int ret; -static int tsc2003_read (struct tsc2003_data *data, - enum tsc2003_cmd cmd, - enum tsc2003_pd pd, - int *val) -{ - char c; - char d[2]; - int ret; - - c = TSC2003_CMD(cmd, pd, data->m); - ret = i2c_master_send(&data->client, &c, 1); - if (ret <= 0) goto err; - - udelay(20); - ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1); - if (ret <= 0) goto err; - - if (val) - { - *val = d[0]; - *val <<= 4; - if (data->m == M_12BIT) - *val += (d[1] >> 4); - } + c = TSC2003_CMD(cmd, pd, data->m); + ret = i2c_master_send(&data->client, &c, 1); + if (ret <= 0) + goto err; + + udelay(20); + ret = i2c_master_recv(&data->client, d, data->m == M_12BIT ? 2 : 1); + if (ret <= 0) + goto err; + + if (val) { + *val = d[0]; + *val <<= 4; + if (data->m == M_12BIT) + *val += (d[1] >> 4); + } #if defined(CONFIG_I2C_DEBUG_CHIP) - printk(KERN_ERR "%s: val[%x] = %d\n", - __FUNCTION__, cmd, (((int)d[0]) << 8) + d[1]); + printk(KERN_ERR "%s: val[%x] = %d\n", + __FUNCTION__, cmd, (((int)d[0]) << 8) + d[1]); #endif - return 0; - err: - if (!ret) ret = -ENODEV; - return ret; + return 0; + err: if (!ret) + ret = -ENODEV; + return ret; } -static inline int tsc2003_read_temp0 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_TEMP0, pd, t); +static inline int tsc2003_read_temp0(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_TEMP0, pd, t); } -static inline int tsc2003_read_temp1 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_TEMP1, pd, t); +static inline int tsc2003_read_temp1(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_TEMP1, pd, t); } -static inline int tsc2003_read_xpos (struct tsc2003_data *d, enum -tsc2003_pd pd, int *x) -{ - return tsc2003_read(d, MEAS_XPOS, pd, x); +static inline int tsc2003_read_xpos(struct tsc2003_data *d, enum +tsc2003_pd pd, int *x) { + return tsc2003_read(d, MEAS_XPOS, pd, x); } -static inline int tsc2003_read_ypos (struct tsc2003_data *d, enum -tsc2003_pd pd, int *y) -{ - return tsc2003_read(d, MEAS_YPOS, pd, y); +static inline int tsc2003_read_ypos(struct tsc2003_data *d, enum +tsc2003_pd pd, int *y) { + return tsc2003_read(d, MEAS_YPOS, pd, y); } -static inline int tsc2003_read_pressure (struct tsc2003_data *d, enum -tsc2003_pd pd, int *p) -{ - return tsc2003_read(d, MEAS_Z1POS, pd, p); +static inline int tsc2003_read_pressure(struct tsc2003_data *d, enum +tsc2003_pd pd, int *p) { + return tsc2003_read(d, MEAS_Z1POS, pd, p); } -static inline int tsc2003_read_in1 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_IN1, pd, t); +static inline int tsc2003_read_in1(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_IN1, pd, t); } -static inline int tsc2003_read_in2 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_IN2, pd, t); +static inline int tsc2003_read_in2(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_IN2, pd, t); } -static inline int tsc2003_read_vbat1 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_VBAT1, pd, t); +static inline int tsc2003_read_vbat1(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_VBAT1, pd, t); } -static inline int tsc2003_read_vbat2 (struct tsc2003_data *d, enum -tsc2003_pd pd, int *t) -{ - return tsc2003_read(d, MEAS_VBAT2, pd, t); +static inline int tsc2003_read_vbat2(struct tsc2003_data *d, enum +tsc2003_pd pd, int *t) { + return tsc2003_read(d, MEAS_VBAT2, pd, t); } -static inline int tsc2003_powerdown (struct tsc2003_data *d) -{ - /* we don't have a distinct powerdown command, - so do a benign read with the PD bits cleared */ - return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0); +static inline int tsc2003_powerdown(struct tsc2003_data *d) { + /* we don't have a distinct powerdown command, + so do a benign read with the PD bits cleared */ + return tsc2003_read(d, MEAS_IN1, PD_POWERDOWN, 0); } -void tsc2003_init_client (struct i2c_client *client) -{ - struct tsc2003_data *data = i2c_get_clientdata(client); +void tsc2003_init_client(struct i2c_client *client) { + struct tsc2003_data *data = i2c_get_clientdata(client); - data->pd = PD_PENIRQ_DISARM; - data->m = M_8BIT; - return; + data->pd = PD_PENIRQ_DISARM; + data->m = M_8BIT; + return; } -#define PENUP_TIMEOUT 50 /* msec */ +static irqreturn_t tsc2003_penirq(int irq, void *v) { + struct tsc2003_data *d = v; -static irqreturn_t tsc2003_penirq (int irq, void *v) -{ - struct tsc2003_data *d = v; - complete(&d->penirq_completion); - return IRQ_HANDLED; -} + printk(KERN_INFO "penirq: %Ld\n", jiffies); -/* -static int tsc2003_remove (struct device *dev) -{ - struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver); - free_irq(d->penirq,d); - input_unregister_device(d->idev); - return 0; -} -*/ + // disable the penirq while we take the sample + disable_irq_nosync(d->penirq); -static void tsc2003_pen_up (unsigned long v) -{ - struct tsc2003_data *d = (struct tsc2003_data *)v; - input_report_abs(d->idev, ABS_PRESSURE, 0); - input_sync(d->idev); - return; + complete(&d->penirq_completion); + return IRQ_HANDLED; } -static inline void tsc2003_restart_pen_up_timer (struct tsc2003_data *d) -{ - mod_timer(&d->penirq_timer, jiffies + (PENUP_TIMEOUT * HZ) / 1000); +static void tsc2003_pen_up(unsigned long v) { + printk(KERN_INFO "tsc2003_pen_up - re-enable irq now\n"); + struct tsc2003_data *d = (struct tsc2003_data *)v; + + enable_irq(d->penirq); + + input_report_abs(d->idev, ABS_PRESSURE, 0); + input_sync(d->idev); + return; } -static int tsc2003ts_thread (void *v) -{ - struct tsc2003_data *d = v; - struct task_struct *tsk = current; - int ret; - - d->tstask = tsk; +static int tsc2003ts_thread(void *v) { + struct tsc2003_data *d = v; + struct task_struct *tsk = current; + int ret; + int err = 0; + + d->tstask = tsk; - daemonize(DRIVER_NAME "tsd"); - allow_signal(SIGKILL); + daemonize(DRIVER_NAME "tsd"); + allow_signal(SIGKILL); - complete(&d->tstask_completion); + complete(&d->tstask_completion); #if defined(CONFIG_I2C_DEBUG_CHIP) - printk(KERN_INFO "%s: address 0x%x\n", - __FUNCTION__, d->client.addr); -#endif + printk(KERN_INFO "%s: address 0x%x\n", + __FUNCTION__, d->client.addr); +#endif + + do { + unsigned int x, y, p, fp; + int pen_is_up = 0; + + down(&d->sem); + + // take the sample + d->pd = PD_PENIRQ_DISARM; + tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x); + tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y); + tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p); + + if (p < 64) { + p=0; + } - while (!signal_pending(tsk)) - { - unsigned int x, y, p; - - if (!down_interruptible(&d->sem)) - { - d->pd = PD_PENIRQ_DISARM; - disable_irq(d->penirq); - tsc2003_read_xpos(d, PD_PENIRQ_DISARM, &x); - tsc2003_read_ypos(d, PD_PENIRQ_DISARM, &y); - tsc2003_read_pressure(d, PD_PENIRQ_DISARM, &p); - - /* non-X-Y driver read to avoid glitch in penirq (errata?) */ - tsc2003_read_vbat1(d, PD_PENIRQ_DISARM, 0); - enable_irq(d->penirq); - - - input_report_abs(d->idev, ABS_X, 4096 - x); - input_report_abs(d->idev, ABS_Y, 4096 - y); - input_report_abs(d->idev, ABS_PRESSURE, p); - input_sync(d->idev); - - - do - { - ret = wait_for_completion_interruptible_timeout(&d->penirq_completion, HZ / 100); - if (ret) - { - if (d->pd == PD_PENIRQ_DISARM) - { - /* fake penirq, avoid glitch and then start watching for real now */ - d->pd = PD_PENIRQ_ARM; - tsc2003_read_vbat1(d, PD_PENIRQ_ARM, 0); - up(&d->sem); - } - else - { - /* pen down event, (re)start the pen up timer */ - tsc2003_restart_pen_up_timer(d); - } - } - else - { - if (d->pd != PD_PENIRQ_ARM) - { - /* fake penirq never arrived, which would be the case - for a level-triggered irq line */ - tsc2003_read_vbat1(d, PD_PENIRQ_ARM, 0); - d->pd = PD_PENIRQ_ARM; - up(&d->sem); - } - if (timer_pending(&d->penirq_timer)) - { - /* pen is down, time to send (another) sample */ - break; - } - else - { - /* pen is up, nothing to do but wait for it to - come down */ - wait_for_completion_interruptible(&d->penirq_completion); - /* pen is down, (re)start the pen up timer */ - tsc2003_restart_pen_up_timer(d); - break; - } - } - } - while (!signal_pending(tsk)); - } - } - - d->tstask = NULL; - complete_and_exit(&d->tstask_completion, 0); -} +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_INFO "TSD X: %d Y: %d P: %d\n", x, y, p); +#endif + + if (!pen_is_up) { + // report our touch to the input layer + input_report_abs(d->idev, ABS_X, 4096 - x); + input_report_abs(d->idev, ABS_Y, 4096 - y); + input_report_abs(d->idev, ABS_PRESSURE, p); + input_sync(d->idev); + } + + if(p == 0) { +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_INFO "No pressure - pen is up!\n"); +#endif + // set our pen as up + pen_is_up = 1; + } + else { +#if defined(CONFIG_I2C_DEBUG_CHIP) + printk(KERN_INFO "Pen is still down - sleeping and will re-sample!\n"); +#endif + // set our pen as down + pen_is_up = 0; + } -static int tsc2003_idev_open (struct input_dev *idev) -{ - struct tsc2003_data *d = idev->private; - int ret = 0; + // sleep for 3 jiffies to give us about 30 updates/sec + msleep (3); - if (down_interruptible(&d->sem)) - return -EINTR; + up(&d->sem); - if (d->tstask) - panic(DRIVER_NAME "tsd already running (!). abort."); - - d->penirq_timer.data = (unsigned long)d; - d->penirq_timer.function = tsc2003_pen_up; + } while (!signal_pending(tsk)); - ret = kernel_thread(tsc2003ts_thread, d, CLONE_KERNEL); - if (ret >= 0) - { - wait_for_completion(&d->tstask_completion); - ret = 0; - } + d->tstask = NULL; + complete_and_exit(&d->tstask_completion, 0); +} - +static int tsc2003_idev_open(struct input_dev *idev) { + struct tsc2003_data *d = idev->private; + int ret = 0; - up(&d->sem); - return ret; -} + if (down_interruptible(&d->sem)) + return -EINTR; -static void tsc2003_idev_close (struct input_dev *idev) -{ - struct tsc2003_data *d = idev->private; - down_interruptible(&d->sem); - if (d->tstask) - { - send_sig(SIGKILL, d->tstask, 1); - wait_for_completion(&d->tstask_completion); - } - - if (timer_pending(&d->penirq_timer)) - del_timer(&d->penirq_timer); - up(&d->sem); - return; -} + if (d->tstask) + panic(DRIVER_NAME "tsd already running (!). abort."); -#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS) -static ssize_t show_addr (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->client.addr); -} -static DEVICE_ATTR(addr, S_IRUGO, show_addr, NULL); + ret = kernel_thread(tsc2003ts_thread, d, CLONE_KERNEL); + if (ret >= 0) { + wait_for_completion(&d->tstask_completion); + ret = 0; + } -static ssize_t show_vbat1 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->vbat1); + up(&d->sem); + return ret; } -static DEVICE_ATTR(vbat1, S_IRUGO, show_vbat1, NULL); -static ssize_t show_vbat2 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->vbat2); -} -static DEVICE_ATTR(vbat2, S_IRUGO, show_vbat2, NULL); +static void tsc2003_idev_close(struct input_dev *idev) { + struct tsc2003_data *d = idev->private; + down_interruptible(&d->sem); + if (d->tstask) { + send_sig(SIGKILL, d->tstask, 1); + wait_for_completion(&d->tstask_completion); + } -static ssize_t show_in1 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->in1); + up(&d->sem); + return; } -static DEVICE_ATTR(in1, S_IRUGO, show_in1, NULL); -static ssize_t show_in2 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->in2); +static int tsc2003_detect_irq(struct tsc2003_data *d) { + d->penirq = IRQ_GPIO(16); //PWM0 GPIO + return 0; } -static DEVICE_ATTR(in2, S_IRUGO, show_in2, NULL); -static ssize_t show_temp0 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->temp0); -} -static DEVICE_ATTR(temp0, S_IRUGO, show_temp0, NULL); +static int tsc2003_driver_register(struct tsc2003_data *data) { + struct input_dev *idev; + int ret = 0; + int error; -static ssize_t show_temp1 (struct device *dev, char *buf) -{ - struct tsc2003_data *d = container_of(dev->driver, struct -tsc2003_data, driver); - return sprintf(buf, "%d\n", d->temp1); -} -static DEVICE_ATTR(temp1, S_IRUGO, show_temp1, NULL); + init_MUTEX(&data->sem); -#warning "TODO: this daemon sometimes hangs the touchscreen daemon" -#warning "TODO: under periods of heavy touch screen activity." -#warning "TODO: Use with caution until the bug is squashed." -static int tsc2003s_thread (void *v) -{ - struct tsc2003_data *d = v; - - daemonize(DRIVER_NAME "sd"); - allow_signal(SIGKILL); - - printk(KERN_INFO "%s: address 0x%x\n", - __FUNCTION__, d->client.addr); - - while (!signal_pending(current)) - { - if (!down_interruptible(&d->sem)) - { - if (!timer_pending(&d->penirq_timer)) - { - tsc2003_read_vbat1(d, d->pd, &d->vbat1); - tsc2003_read_vbat2(d, d->pd, &d->vbat2); - tsc2003_read_in1(d, d->pd, &d->in1); - tsc2003_read_in2(d, d->pd, &d->in2); - tsc2003_read_temp0(d, d->pd, &d->temp0); - tsc2003_read_temp1(d, d->pd, &d->temp1); - } - up(&d->sem); - } - set_task_state(current, TASK_INTERRUPTIBLE); - schedule_timeout(5 * HZ); - } - do_exit(0); -} -#endif + error = tsc2003_detect_irq(data); + if (error) { + printk(KERN_ERR "TSC2003: IRQ probe failed\n"); + } -static int tsc2003_detect_irq (struct tsc2003_data *d) -{ - d->penirq = IRQ_GPIO(16); //PWM0 GPIO - return 0; -} + if (data->penirq) { + ret = request_irq(data->penirq, tsc2003_penirq, SA_INTERRUPT | IRQF_TRIGGER_LOW, + DRIVER_NAME, data); + if (!ret) { + printk(KERN_INFO "%s: irq %d\n", __FUNCTION__, data->penirq); + init_completion(&data->tstask_completion); + init_completion(&data->penirq_completion); + } else { + printk(KERN_ERR "%s: cannot grab irq %d\n", __FUNCTION__, data->penirq); + } + } -/* -static int tsc2003_probe (struct device *dev) -{ - //struct platform_device *p = to_platform_device(dev); - struct tsc2003_data *d = container_of(dev->driver, struct tsc2003_data, driver); - int ret = 0; - int error; - - printk(KERN_ERR "TSC2003: tsc2003_probe probing...\n"); - - error = tsc2003_detect_irq(d); - if(error) - { - printk(KERN_ERR "TSC2003: IRQ probe failed\n"); - } - - if (d->penirq) - { - ret = request_irq(d->penirq, tsc2003_penirq, IRQF_TRIGGER_FALLING, DRIVER_NAME, d); - if (!ret) - { - printk(KERN_INFO "%s: irq %d\n", __FUNCTION__, d->penirq); - } - else - { - printk(KERN_INFO "%s: cannot grab irq %d\n", __FUNCTION__, d->penirq); - } - } - -#if defined(CONFIG_SYSFS) && defined(CONFIG_SENSORS_TSC2003_SYSFS) - ret = kernel_thread(tsc2003s_thread, d, CLONE_KERNEL); - if (ret >= 0) - ret = 0; - - device_create_file(dev, &dev_attr_addr); - device_create_file(dev, &dev_attr_vbat1); - device_create_file(dev, &dev_attr_vbat2); - device_create_file(dev, &dev_attr_in1); - device_create_file(dev, &dev_attr_in2); - device_create_file(dev, &dev_attr_temp0); - device_create_file(dev, &dev_attr_temp1); -#endif + idev = input_allocate_device(); + data->idev = idev; + idev->private = data; + idev->name = DRIVER_NAME; + idev->evbit[0] = BIT(EV_ABS); + idev->open = tsc2003_idev_open; + idev->close = tsc2003_idev_close; + idev->absbit[LONG(ABS_X)] = BIT(ABS_X); + idev->absbit[LONG(ABS_Y)] = BIT(ABS_Y); + idev->absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE); + input_set_abs_params(idev, ABS_X, 0, ADC_MAX, 0, 0); + input_set_abs_params(idev, ABS_Y, 0, ADC_MAX, 0, 0); + input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); - return ret; -} -*/ + if (!ret) { + input_register_device(idev); + printk(KERN_INFO "tsc2003 - registering input device\n"); + } -static int tsc2003_driver_register (struct tsc2003_data *data) -{ - struct input_dev *idev; - int ret = 0; - int error; - - init_MUTEX(&data->sem); - - init_timer(&data->penirq_timer); - data->penirq_timer.data = (unsigned long)data; - data->penirq_timer.function = tsc2003_pen_up; - - error = tsc2003_detect_irq(data); - if(error) - { - printk(KERN_ERR "TSC2003: IRQ probe failed\n"); - } - - if (data->penirq) - { - ret = request_irq(data->penirq, tsc2003_penirq, IRQF_TRIGGER_FALLING, DRIVER_NAME, data); - if (!ret) - { - printk(KERN_INFO "%s: irq %d\n", __FUNCTION__, data->penirq); - init_completion(&data->tstask_completion); - init_completion(&data->penirq_completion); - } - else - { - printk(KERN_ERR "%s: cannot grab irq %d\n", __FUNCTION__, data->penirq); - } - } - - idev = input_allocate_device(); - data->idev = idev; - - idev->private = data; - idev->name = DRIVER_NAME; - idev->evbit[0] = BIT(EV_ABS); - idev->open = tsc2003_idev_open; - idev->close = tsc2003_idev_close; - idev->absbit[LONG(ABS_X)] = BIT(ABS_X); - idev->absbit[LONG(ABS_Y)] = BIT(ABS_Y); - idev->absbit[LONG(ABS_PRESSURE)] = BIT(ABS_PRESSURE); - input_set_abs_params(idev, ABS_X, 0, ADC_MAX, 0, 0); - input_set_abs_params(idev, ABS_Y, 0, ADC_MAX, 0, 0); - input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0); - - if (!ret) - { - input_register_device(idev); - printk(KERN_INFO "tsc2003 - registering input device\n"); - } - - return ret; + return ret; } -static int tsc2003_i2c_attach_adapter(struct i2c_adapter *adapter) -{ - printk(KERN_INFO "tsc2003 i2c touch screen controller\n"); - printk(KERN_INFO "Bill Gatliff <bgat at billgatliff.com\n"); - printk(KERN_INFO "Nicholas Chen <nchen at cs.umd.edu>\n"); - - return i2c_probe(adapter, &addr_data, tsc2003_i2c_detect); +static int tsc2003_i2c_attach_adapter(struct i2c_adapter *adapter) { + printk(KERN_INFO "tsc2003 i2c touch screen controller\n"); + printk(KERN_INFO "Bill Gatliff <bgat at billgatliff.com\n"); + printk(KERN_INFO "Nicholas Chen <nchen at cs.umd.edu>\n"); + + return i2c_probe(adapter, &addr_data, tsc2003_i2c_detect); } -static int tsc2003_i2c_detach_client(struct i2c_client *client) -{ - int err; - struct tsc2003_data *d = i2c_get_clientdata(client); +static int tsc2003_i2c_detach_client(struct i2c_client *client) { + int err; + struct tsc2003_data *d = i2c_get_clientdata(client); - free_irq(d->penirq,d); - input_unregister_device(d->idev); + free_irq(d->penirq, d); + input_unregister_device(d->idev); - if ((err = i2c_detach_client(client))) { - dev_err(&client->dev, "Client deregistration failed, " - "client not detached.\n"); - return err; - } + if ((err = i2c_detach_client(client))) { + dev_err(&client->dev, "Client deregistration failed, " + "client not detached.\n"); + return err; + } - return 0; + return 0; } -static struct i2c_driver tsc2003_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME, - }, - .attach_adapter = tsc2003_i2c_attach_adapter, - .detach_client = tsc2003_i2c_detach_client, - // .command = tsc2003_command, +static struct i2c_driver tsc2003_driver = { + .driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + }, + .attach_adapter = tsc2003_i2c_attach_adapter, + .detach_client = tsc2003_i2c_detach_client, }; -static int tsc2003_i2c_detect (struct i2c_adapter *adapter, int address, -int kind) -{ - struct i2c_client *new_client; - struct tsc2003_data *data; - - int err = 0; - const char *name = ""; - - if (!i2c_check_functionality(adapter, - I2C_FUNC_SMBUS_BYTE_DATA - | I2C_FUNC_I2C - | I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - data = kcalloc(1, sizeof(*data), GFP_KERNEL); - if (!data) { - err = -ENOMEM; - goto exit; - } - - new_client = &data->client; - i2c_set_clientdata(new_client, data); - new_client->addr = address; - new_client->adapter = adapter; - new_client->driver = &tsc2003_driver; - new_client->flags = 0; - - /* TODO: I'm pretty sure I'm not dealing with kind correctly */ - if (kind == 0 /* identification */ || kind < 0 /* detection */) - kind = tsc2003; - - if (kind == tsc2003) - name = DRIVER_NAME; - - /* try a command, see if we get an ack; - if we do, assume it's our device */ - printk(KERN_INFO "%s: probing address 0x%x\n", - __FUNCTION__, address); - err = tsc2003_powerdown(data); - if (err >= 0) - { - strlcpy(new_client->name, name, I2C_NAME_SIZE); - err = i2c_attach_client(new_client); - if (err) goto exit_free; - - tsc2003_init_client(new_client); - - err = tsc2003_driver_register(data); - if (err < 0) goto exit_free; - - printk(KERN_INFO "%s: device address 0x%x attached.\n", - __FUNCTION__, address); - return 0; - } - /* failure to detect when everything else is ok isn't an error */ - else err = 0; - - exit_free: - kfree(new_client); - exit: - return err; +static int tsc2003_i2c_detect(struct i2c_adapter *adapter, int address, int kind) { + struct i2c_client *new_client; + struct tsc2003_data *data; + + int err = 0; + const char *name = ""; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA + | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WORD_DATA)) + goto exit; + + data = kcalloc(1, sizeof(*data), GFP_KERNEL); + if (!data) { + err = -ENOMEM; + goto exit; + } + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &tsc2003_driver; + new_client->flags = 0; + + /* TODO: I'm pretty sure I'm not dealing with kind correctly */ + if (kind == 0 /* identification */|| kind < 0 /* detection */) + kind = tsc2003; + + if (kind == tsc2003) + name = DRIVER_NAME; + + /* try a command, see if we get an ack; + if we do, assume it's our device */ + printk(KERN_INFO "%s: probing address 0x%x\n", + __FUNCTION__, address); + err = tsc2003_powerdown(data); + if (err >= 0) { + strlcpy(new_client->name, name, I2C_NAME_SIZE); + err = i2c_attach_client(new_client); + if (err) + goto exit_free; + + tsc2003_init_client(new_client); + + err = tsc2003_driver_register(data); + if (err < 0) + goto exit_free; + + printk(KERN_INFO "%s: device address 0x%x attached.\n", + __FUNCTION__, address); + return 0; + } + /* failure to detect when everything else is ok isn't an error */ + else + err = 0; + + exit_free: kfree(new_client); + exit: return err; } static int __init tsc2003_init(void) { - return i2c_add_driver(&tsc2003_driver); + return i2c_add_driver(&tsc2003_driver); } static void __exit tsc2003_exit(void) { - i2c_del_driver(&tsc2003_driver); + i2c_del_driver(&tsc2003_driver); } MODULE_AUTHOR("Bill Gatliff <bgat at billgatliff.com>"); @@ -696,4 +470,3 @@ MODULE_LICENSE("GPL"); module_init(tsc2003_init); module_exit(tsc2003_exit); - diff --git a/packages/linux/gumstix-kernel_2.6.21.bb b/packages/linux/gumstix-kernel_2.6.21.bb index 3bc7df238a..e71c972053 100644 --- a/packages/linux/gumstix-kernel_2.6.21.bb +++ b/packages/linux/gumstix-kernel_2.6.21.bb @@ -1,7 +1,7 @@ require gumstix-linux.inc SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ - ${@base_contains('MACHINE_FEATURES', 'lcd','file://defconfig', 'file://defconfig-nofb',d)} \ + file://defconfig \ file://tsc2003.c \ file://tsc2003-config.diff;patch=1 \ file://pxa-regs-additions.patch;patch=1 \ @@ -46,9 +46,37 @@ SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ file://gumstix-pxa270-mmc.patch;patch=1 \ file://pxafb-18bpp-mode.patch;patch=1 \ file://smc911x-fixup.patch;patch=1 \ + file://smc91x-fail-if-no-chip.patch;patch=1 \ + file://one-wire.patch;patch=1 \ + ${@base_contains('MACHINE_FEATURES', 'rgb16','file://pxafb-backto16.patch;patch=1', '',d)} \ " do_configure_prepend() { - ${@base_contains('MACHINE_FEATURES', 'lcd','','mv ${WORKDIR}/defconfig-nofb ${WORKDIR}/defconfig',d)} + cp ${WORKDIR}/tsc2003.c ${S}/drivers/i2c/chips/ + + # turn off frame buffer support in kernel if lcd MACHINE_FEATURES not defined + ${@base_contains('MACHINE_FEATURES', 'lcd','','sed -i "s/CONFIG_FB=y/# CONFIG_FB is not set/" ${WORKDIR}/defconfig',d)} + ${@base_contains('MACHINE_FEATURES', 'lcd','','sed -i "s/CONFIG_FB_PXA=y/# CONFIG_FB_PXA is not set/" ${WORKDIR}/defconfig',d)} + ${@base_contains('MACHINE_FEATURES', 'lcd','','sed -i "s/CONFIG_FRAMEBUFFER_CONSOLE=y/# CONFIG_FRAMEBUFFER_CONSOLE is not set/" ${WORKDIR}/defconfig',d)} + ${@base_contains('MACHINE_FEATURES', 'lcd','','sed -i "s/CONFIG_LOGO=y/# CONFIG_LOGO is not set/" ${WORKDIR}/defconfig',d)} + + # if mmcroot MACHINE_FEATURES requested disable jffs2 and enable mmc and ext2 support in kernel + ${@base_contains('MACHINE_FEATURES', 'mmcroot','sed -i "s/CONFIG_JFFS2_FS=y/CONFIG_JFFS2_FS=m/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'mmcroot','sed -i "s/CONFIG_EXT2_FS=m/CONFIG_EXT2_FS=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'mmcroot','sed -i "s/CONFIG_MMC=m/CONFIG_MMC=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'mmcroot','sed -i "s/CONFIG_MMC_PXA=m/CONFIG_MMC_PXA=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'mmcroot','sed -i "s/CONFIG_MMC_BLOCK=m/CONFIG_MMC_BLOCK=y/" ${WORKDIR}/defconfig','',d)} + + # if cfroot MACHINE_FEATURES requested disable jffs2 and enable pcmcia and ext2 support in kernel + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_JFFS2_FS=y/CONFIG_JFFS2_FS=m/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_EXT2_FS=m/CONFIG_EXT2_FS=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_PCCARD=m/CONFIG_PCCARD=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_PCMCIA=m/CONFIG_PCMCIA=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_PCMCIA_PXA2XX=m/CONFIG_PCMCIA_PXA2XX=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_IDE=m/CONFIG_IDE=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_BLK_DEV_IDE=m/CONFIG_BLK_DEV_IDE=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_BLK_DEV_IDEDISK=m/CONFIG_BLK_DEV_IDEDISK=y/" ${WORKDIR}/defconfig','',d)} + ${@base_contains('MACHINE_FEATURES', 'cfroot','sed -i "s/CONFIG_BLK_DEV_IDECS=m/CONFIG_BLK_DEV_IDECS=y/" ${WORKDIR}/defconfig','',d)} + } 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/matchbox-stroke/matchbox-stroke_svn.bb b/packages/matchbox-stroke/matchbox-stroke_svn.bb index 7afa80d589..a6d6dce07e 100644 --- a/packages/matchbox-stroke/matchbox-stroke_svn.bb +++ b/packages/matchbox-stroke/matchbox-stroke_svn.bb @@ -2,7 +2,7 @@ DESCRIPTION = "Matchbox keyboard" LICENSE = "GPL" DEPENDS = "libfakekey expat libxft" SECTION = "x11/wm" -PV = "0.0+svn${SRCDATE}" +PV = "0.0+svnr${SRCREV}" PR="r2" 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/opkg/opkg_svn.bb b/packages/opkg/opkg_svn.bb index 51c83f8968..149f3050cf 100644 --- a/packages/opkg/opkg_svn.bb +++ b/packages/opkg/opkg_svn.bb @@ -1,26 +1,21 @@ DESCRIPTION = "Open Package Manager" -DESCRIPTION_libipkg = "Open Package Manager Library" +DESCRIPTION_libopkg = "Open Package Manager Library" SECTION = "base" LICENSE = "GPL" DEPENDS = "curl gpgme" PV = "0.0+svnr${SRCREV}" -SRC_URI = "svn://svn.openmoko.org/trunk/src/target/;module=opkg;proto=http" +PR = "r1" +SRC_URI = "svn://svn.openmoko.org/trunk/src/target/;module=opkg;proto=http" S = "${WORKDIR}/opkg" inherit autotools pkgconfig do_stage() { - oe_libinstall -so libopkg ${STAGING_LIBDIR} - install -d ${STAGING_INCDIR}/libopkg/ - for f in *.h - do - install -m 0644 $f ${STAGING_INCDIR}/libopkg/ - done + autotools_stage_all } PACKAGES =+ "libopkg-dev libopkg" FILES_libopkg-dev = "${libdir}/*.a ${libdir}/*.la ${libdir}/*.so" FILES_libopkg = "${libdir}/*.so.*" - 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/sharprom-toolchain/sharprom-toolchain-native_1.0.bb b/packages/sharprom-toolchain/sharprom-toolchain-native_1.0.bb index e52ab34392..aa7c98affd 100644 --- a/packages/sharprom-toolchain/sharprom-toolchain-native_1.0.bb +++ b/packages/sharprom-toolchain/sharprom-toolchain-native_1.0.bb @@ -8,10 +8,15 @@ PROVIDES_sharprom-compatible = "\ virtual/arm-linux-libc-for-gcc \ virtual/arm-linux-binutils \ virtual/libc \ + virtual/libintl \ + virtual/libiconv \ virtual/arm-linux-gcc \ virtual/arm-linux-gcc-initial " PR = "r1" +RPROVIDES = "glibc-utils libsegfault glibc-thread-db libgcc-dev libstdc++-dev libstdc++" +PACKAGES_DYNAMIC = "glibc-gconv-*" + # This needs to be extracted to /usr/local/arm : # SRC_URI = "http://handhelds.org/download/projects/toolchain/archive/cross-2.95.3.tar.bz2" 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/uclibc/uclibc-initial_0.9.26.bb b/packages/uclibc/uclibc-initial_0.9.26.bb index 840acafeac..c29a498a96 100644 --- a/packages/uclibc/uclibc-initial_0.9.26.bb +++ b/packages/uclibc/uclibc-initial_0.9.26.bb @@ -9,18 +9,14 @@ PACKAGES = "" do_stage() { # Install initial headers into the cross dir - make PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \ + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ pregen install_dev - mkdir -p ${CROSS_DIR}/${TARGET_SYS} - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/include - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/lib ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include - rm -rf ${CROSS_DIR}/${TARGET_SYS}/${prefix} # This conflicts with the c++ version of this header - rm -f ${UCLIBC_PREFIX}/include/bits/atomicity.h + rm -f ${UCLIBC_STAGING_PREFIX}/include/bits/atomicity.h } do_install() { diff --git a/packages/uclibc/uclibc-initial_0.9.27.bb b/packages/uclibc/uclibc-initial_0.9.27.bb index 840acafeac..c29a498a96 100644 --- a/packages/uclibc/uclibc-initial_0.9.27.bb +++ b/packages/uclibc/uclibc-initial_0.9.27.bb @@ -9,18 +9,14 @@ PACKAGES = "" do_stage() { # Install initial headers into the cross dir - make PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \ + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ pregen install_dev - mkdir -p ${CROSS_DIR}/${TARGET_SYS} - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/include - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/lib ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include - rm -rf ${CROSS_DIR}/${TARGET_SYS}/${prefix} # This conflicts with the c++ version of this header - rm -f ${UCLIBC_PREFIX}/include/bits/atomicity.h + rm -f ${UCLIBC_STAGING_PREFIX}/include/bits/atomicity.h } do_install() { diff --git a/packages/uclibc/uclibc-initial_0.9.28.bb b/packages/uclibc/uclibc-initial_0.9.28.bb index 840acafeac..c29a498a96 100644 --- a/packages/uclibc/uclibc-initial_0.9.28.bb +++ b/packages/uclibc/uclibc-initial_0.9.28.bb @@ -9,18 +9,14 @@ PACKAGES = "" do_stage() { # Install initial headers into the cross dir - make PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \ + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ pregen install_dev - mkdir -p ${CROSS_DIR}/${TARGET_SYS} - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/include - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/lib ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include - rm -rf ${CROSS_DIR}/${TARGET_SYS}/${prefix} # This conflicts with the c++ version of this header - rm -f ${UCLIBC_PREFIX}/include/bits/atomicity.h + rm -f ${UCLIBC_STAGING_PREFIX}/include/bits/atomicity.h } do_install() { diff --git a/packages/uclibc/uclibc-initial_0.9.29.bb b/packages/uclibc/uclibc-initial_0.9.29.bb index 840acafeac..aa42fa3d19 100644 --- a/packages/uclibc/uclibc-initial_0.9.29.bb +++ b/packages/uclibc/uclibc-initial_0.9.29.bb @@ -9,18 +9,14 @@ PACKAGES = "" do_stage() { # Install initial headers into the cross dir - make PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \ + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGE_PREFIX}/ \ pregen install_dev - mkdir -p ${CROSS_DIR}/${TARGET_SYS} - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/include - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/lib ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include - rm -rf ${CROSS_DIR}/${TARGET_SYS}/${prefix} # This conflicts with the c++ version of this header - rm -f ${UCLIBC_PREFIX}/include/bits/atomicity.h + rm -f ${UCLIBC_STAGE_PREFIX}/include/bits/atomicity.h } do_install() { diff --git a/packages/uclibc/uclibc-initial_svn.bb b/packages/uclibc/uclibc-initial_svn.bb index b85dd0e18d..eb57f85b24 100644 --- a/packages/uclibc/uclibc-initial_svn.bb +++ b/packages/uclibc/uclibc-initial_svn.bb @@ -9,18 +9,14 @@ PACKAGES = "" do_stage() { # Install initial headers into the cross dir - make PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \ - RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \ + make PREFIX= DEVEL_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ + RUNTIME_PREFIX=${UCLIBC_STAGING_PREFIX}/ \ pregen install_dev - mkdir -p ${CROSS_DIR}/${TARGET_SYS} - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/include - mkdir -p ${CROSS_DIR}/${TARGET_SYS}/lib ln -sf include ${CROSS_DIR}/${TARGET_SYS}/sys-include - rm -rf ${CROSS_DIR}/${TARGET_SYS}/${prefix} # This conflicts with the c++ version of this header - rm -f ${UCLIBC_PREFIX}/include/bits/atomicity.h + rm -f ${UCLIBC_STAGING_PREFIX}/include/bits/atomicity.h } do_install() { diff --git a/packages/uclibc/uclibc_0.9.28.bb b/packages/uclibc/uclibc_0.9.28.bb index d5d1bae4be..4d3a8d9d03 100644 --- a/packages/uclibc/uclibc_0.9.28.bb +++ b/packages/uclibc/uclibc_0.9.28.bb @@ -1,12 +1,12 @@ DEFAULT_PREFERENCE = "1" -PR = "r10" +PR = "r11" require uclibc.inc # This is the correct KERNEL_SOURCE location, if the uClibc # fix_includes.sh script is run (see nokernelheader.patch below) # this must be correct. -KERNEL_SOURCE = "${CROSS_DIR}/${TARGET_SYS}" +KERNEL_SOURCE = "${STAGING_DIR_HOST}/${exec_prefix}" SRC_URI += "http://www.uclibc.org/downloads/uClibc-${PV}.tar.bz2" diff --git a/packages/uclibc/uclibc_0.9.29.bb b/packages/uclibc/uclibc_0.9.29.bb index 484477c084..9051029cdf 100644 --- a/packages/uclibc/uclibc_0.9.29.bb +++ b/packages/uclibc/uclibc_0.9.29.bb @@ -33,7 +33,7 @@ PACKAGE_ARCH = "${MACHINE_ARCH}" #as stated above, uclibc needs real kernel-headers #however: we can't depend on virtual/kernel when nptl hits due to depends deadlocking .... -KERNEL_SOURCE = "${CROSS_DIR}/${TARGET_SYS}" +KERNEL_SOURCE = "${STAGING_DIR_HOST}/${exec_prefix}" SRC_URI += "http://www.uclibc.org/downloads/uClibc-${PV}.tar.bz2" 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 -} diff --git a/packages/xorg-lib/libx11/include_fix.patch b/packages/xorg-lib/libx11/include_fix.patch new file mode 100644 index 0000000000..565308834e --- /dev/null +++ b/packages/xorg-lib/libx11/include_fix.patch @@ -0,0 +1,62 @@ +--- + configure.ac | 44 ++++++++++++++++++++++++-------------------- + 1 file changed, 24 insertions(+), 20 deletions(-) + +Index: libX11-1.1.2/configure.ac +=================================================================== +--- libX11-1.1.2.orig/configure.ac 2008-01-02 15:30:47.000000000 +0000 ++++ libX11-1.1.2/configure.ac 2008-01-02 15:47:25.000000000 +0000 +@@ -207,29 +207,33 @@ AC_CHECK_FUNC(poll, [AC_DEFINE(USE_POLL, + # + KEYSYMDEF="" + AC_MSG_CHECKING([keysymdef.h]) +-for flag in $XPROTO_CFLAGS -I/usr/include; do +- case "$KEYSYMDEF" in +- "") +- case "$flag" in +- *-I*) +- dir=`echo "$flag" | sed 's/ *-I//'` +- file="$dir/X11/keysymdef.h" +- if test -f "$file"; then +- KEYSYMDEF="$file" +- fi ++AC_ARG_WITH(keysymdef, ++ AC_HELP_STRING([--with-keysymdef=DIR/keysymdef.h], [The location of keysymdef.h]), ++ KEYSYMDEF=$withval, KEYSYMDEF="") ++ ++if test x$KEYSYMDEF = x; then ++ for flag in $XPROTO_CFLAGS -I/usr/include; do ++ case "$KEYSYMDEF" in ++ "") ++ case "$flag" in ++ *-I*) ++ dir=`echo "$flag" | sed 's/ *-I//'` ++ file="$dir/X11/keysymdef.h" ++ if test -f "$file"; then ++ KEYSYMDEF="$file" ++ fi ++ ;; ++ esac + ;; + esac +- ;; +- esac +-done +-case "$KEYSYMDEF" in +-"") +- AC_MSG_ERROR([Cannot find keysymdef.h]) +- ;; +-*) ++ done ++fi ++ ++if test -f "$KEYSYMDEF"; then + AC_MSG_RESULT([$KEYSYMDEF]) +- ;; +-esac ++else ++ AC_MSG_ERROR([Cannot find keysymdef.h]) ++fi + AC_SUBST(KEYSYMDEF) + + AC_ARG_ENABLE(udc, diff --git a/packages/xorg-lib/libx11_1.1.2.bb b/packages/xorg-lib/libx11_1.1.2.bb index e6b0ec5d8b..5243de4259 100644 --- a/packages/xorg-lib/libx11_1.1.2.bb +++ b/packages/xorg-lib/libx11_1.1.2.bb @@ -5,19 +5,21 @@ DEPENDS += "bigreqsproto xproto xextproto xtrans libxau xcmiscproto \ libxdmcp xf86bigfontproto kbproto inputproto" PROVIDES = "virtual/libx11" PE = "1" -PR = "r1" +PR = "r3" XORG_PN = "libX11" -EXTRA_OECONF += "--without-xcb" +SRC_URI += "file://include_fix.patch;patch=1" + +EXTRA_OECONF += "--without-xcb --with-keysymdef=${STAGING_INCDIR}/X11/keysymdef.h" do_compile() { - ( - unset CC LD CXX CCLD CFLAGS CPPFLAGS LDFLAGS CXXFLAGS - cd src/util; touch makekeys-makekeys.o ; ${BUILD_CC} ${BUILD_CFLAGS} makekeys.c -o makekeys - cd ../../ - ) || exit 1 - oe_runmake + ( + unset CC LD CXX CCLD CFLAGS CPPFLAGS LDFLAGS CXXFLAGS + cd src/util; touch makekeys-makekeys.o ; ${BUILD_CC} ${BUILD_CFLAGS} makekeys.c -o makekeys + cd ../../ + ) || exit 1 + oe_runmake } FILES_${PN} += "${datadir}/X11/XKeysymDB ${datadir}/X11/XErrorDB ${libdir}/X11/Xcms.txt" diff --git a/packages/xorg-lib/libx11_1.1.3.bb b/packages/xorg-lib/libx11_1.1.3.bb index 4035c77cdc..5243de4259 100644 --- a/packages/xorg-lib/libx11_1.1.3.bb +++ b/packages/xorg-lib/libx11_1.1.3.bb @@ -5,19 +5,21 @@ DEPENDS += "bigreqsproto xproto xextproto xtrans libxau xcmiscproto \ libxdmcp xf86bigfontproto kbproto inputproto" PROVIDES = "virtual/libx11" PE = "1" -PR = "r0" +PR = "r3" XORG_PN = "libX11" -EXTRA_OECONF += "--without-xcb" +SRC_URI += "file://include_fix.patch;patch=1" + +EXTRA_OECONF += "--without-xcb --with-keysymdef=${STAGING_INCDIR}/X11/keysymdef.h" do_compile() { - ( - unset CC LD CXX CCLD CFLAGS CPPFLAGS LDFLAGS CXXFLAGS - cd src/util; touch makekeys-makekeys.o ; ${BUILD_CC} ${BUILD_CFLAGS} makekeys.c -o makekeys - cd ../../ - ) || exit 1 - oe_runmake + ( + unset CC LD CXX CCLD CFLAGS CPPFLAGS LDFLAGS CXXFLAGS + cd src/util; touch makekeys-makekeys.o ; ${BUILD_CC} ${BUILD_CFLAGS} makekeys.c -o makekeys + cd ../../ + ) || exit 1 + oe_runmake } FILES_${PN} += "${datadir}/X11/XKeysymDB ${datadir}/X11/XErrorDB ${libdir}/X11/Xcms.txt" diff --git a/packages/zlib/zlib-native_1.2.3.bb b/packages/zlib/zlib-native_1.2.3.bb index 8ad4a8c03c..246bf2835c 100644 --- a/packages/zlib/zlib-native_1.2.3.bb +++ b/packages/zlib/zlib-native_1.2.3.bb @@ -1,4 +1,3 @@ -SECTION = "libs" require zlib_${PV}.bb ZLIB_EXTRA = "" inherit native |