diff --git a/config/options b/config/options index 9797a93a60..622fcb65c2 100644 --- a/config/options +++ b/config/options @@ -88,6 +88,7 @@ get_graphicdrivers() { [ "$drv" = "r600" ] && MESA_DRIVERS="$MESA_DRIVERS,r600" [ "$drv" = "radeon" ] && MESA_DRIVERS="$MESA_DRIVERS,radeon" [ "$drv" = "nouveau" ] && MESA_DRIVERS="$MESA_DRIVERS,nouveau" + [ "$drv" = "omapfb" ] && MESA_DRIVERS="$MESA_DRIVERS,swrast" if [ "$drv" = "i915" -o "$drv" = "i965" ]; then XORG_DRIVERS="$XORG_DRIVERS intel" @@ -106,6 +107,10 @@ get_graphicdrivers() { XINERAMA_SUPPORT="yes" fi + if [ "$drv" = "omapfb" ]; then + XORG_DRIVERS="$XORG_DRIVERS ompafb" + fi + if [ "$drv" = "vmware" ]; then XINERAMA_SUPPORT="yes" fi diff --git a/packages/databases/mysql/build b/packages/databases/mysql/build index a487761fb7..1913e89348 100755 --- a/packages/databases/mysql/build +++ b/packages/databases/mysql/build @@ -22,6 +22,9 @@ . config/options $1 +# mysql fails to build with LTO support + strip_lto + cd $PKG_BUILD ac_cv_c_stack_direction=-1 \ ac_cv_sys_restartable_syscalls=yes \ diff --git a/packages/databases/mysql/install b/packages/databases/mysql/install index a9ad3f0f62..c505d95a2a 100755 --- a/packages/databases/mysql/install +++ b/packages/databases/mysql/install @@ -23,4 +23,7 @@ . config/options $1 mkdir -p $INSTALL/usr/lib - cp -PR $PKG_BUILD/libmysql/.libs/libmysqlclient.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/libmysql/.libs/libmysqlclient.so* $INSTALL/usr/lib + +mkdir -p $INSTALL/usr/share/mysql/charsets + cp -R $PKG_BUILD/sql/share/charsets/*.xml $INSTALL/usr/share/mysql/charsets \ No newline at end of file diff --git a/packages/databases/sqlite/build b/packages/databases/sqlite/build index 2eb5bbbb48..8af6ff70eb 100755 --- a/packages/databases/sqlite/build +++ b/packages/databases/sqlite/build @@ -37,7 +37,6 @@ cd $PKG_BUILD --enable-dynamic-extensions \ --with-gnu-ld - make $STRIP .libs/sqlite3 diff --git a/packages/graphics/tiff/install b/packages/graphics/tiff/install index 35d05edfa4..4f894746e8 100755 --- a/packages/graphics/tiff/install +++ b/packages/graphics/tiff/install @@ -23,4 +23,6 @@ . config/options $1 mkdir -p $INSTALL/usr/lib - cp -P $PKG_BUILD/libtiff/.libs/*.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/libtiff/.libs/libtiff.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/libtiff/.libs/libtiffxx.so* $INSTALL/usr/lib + rm -rf $INSTALL/usr/lib/libtiffxx.so*T \ No newline at end of file diff --git a/packages/linux/meta b/packages/linux/meta index 7ef67b2fae..2c35b2c352 100644 --- a/packages/linux/meta +++ b/packages/linux/meta @@ -19,13 +19,13 @@ ################################################################################ PKG_NAME="linux" -PKG_VERSION="2.6.38-rc8" +PKG_VERSION="2.6.38" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.kernel.org" -#PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/$PKG_NAME-$PKG_VERSION.tar.bz2" -PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/testing/$PKG_NAME-$PKG_VERSION.tar.bz2" +PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/$PKG_NAME-$PKG_VERSION.tar.bz2" +#PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/testing/$PKG_NAME-$PKG_VERSION.tar.bz2" PKG_DEPENDS="busybox linux-drivers linux-firmware" PKG_BUILD_DEPENDS="toolchain busybox-hosttools xz" PKG_PRIORITY="optional" @@ -36,7 +36,13 @@ PKG_IS_ADDON="no" PKG_AUTORECONF="no" -if [ "$LINUX_NEXT" = "yes" ]; then - PKG_VERSION="2.6.38-rc7" - PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/testing/$PKG_NAME-$PKG_VERSION.tar.bz2" +if [ "$LINUX_NEXT" = "yes" -a "$LINUX" = "default" ]; then + PKG_VERSION="2.6.38" + PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/$PKG_NAME-$PKG_VERSION.tar.bz2" +# PKG_URL="http://www.kernel.org/pub/linux/kernel/v2.6/testing/$PKG_NAME-$PKG_VERSION.tar.bz2" +fi + +if [ "$LINUX" = "ti-omap4" ]; then + PKG_VERSION="2.6.35-ti.980.1r14" + PKG_URL="$OPENELEC_SRC/$PKG_NAME-$PKG_VERSION.tar.bz2" fi diff --git a/packages/linux/patches/linux-2.6.38-rc8-000_crosscompile.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-000_crosscompile.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-000_crosscompile.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-000_crosscompile.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-002_bash_only_feature.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-002-bash-only-feature.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-002_bash_only_feature.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-002-bash-only-feature.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-003-no_dev_console.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-003-no_dev_console.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-003-no_dev_console.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-003-no_dev_console.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-004_lower_undefined_mode_timeout.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-004-lower-undefined-mode-timeout.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-004_lower_undefined_mode_timeout.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-004-lower-undefined-mode-timeout.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-005_kconfig_no_timestamp.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-005-kconfig-no-timestamp.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-005_kconfig_no_timestamp.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-005-kconfig-no-timestamp.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-006_enable_utf8.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-006-enable-utf8.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-006_enable_utf8.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-006-enable-utf8.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-007_die_floppy_die.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-007-die-floppy-die.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-007_die_floppy_die.patch rename to packages/linux/patches/linux-2.6.35-ti.980.1r14-007-die-floppy-die.patch diff --git a/packages/linux/patches/linux-2.6.35-ti.980.1r14-008-014-linux-2.6.35-01-add_lirc_drivers-20100407-0.1.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-008-014-linux-2.6.35-01-add_lirc_drivers-20100407-0.1.patch new file mode 100644 index 0000000000..5fba624388 --- /dev/null +++ b/packages/linux/patches/linux-2.6.35-ti.980.1r14-008-014-linux-2.6.35-01-add_lirc_drivers-20100407-0.1.patch @@ -0,0 +1,17337 @@ +diff -Naur linux-2.6.35-rc6/drivers/input/Kconfig linux-2.6.35-rc6.patch/drivers/input/Kconfig +--- linux-2.6.35-rc6/drivers/input/Kconfig 2010-07-22 21:13:38.000000000 +0200 ++++ linux-2.6.35-rc6.patch/drivers/input/Kconfig 2010-08-02 09:28:03.918052011 +0200 +@@ -183,6 +183,8 @@ + + source "drivers/input/touchscreen/Kconfig" + ++source "drivers/input/lirc/Kconfig" ++ + source "drivers/input/misc/Kconfig" + + endif +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/Kconfig linux-2.6.35-rc6.patch/drivers/input/lirc/Kconfig +--- linux-2.6.35-rc6/drivers/input/lirc/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/Kconfig 2010-08-02 09:28:03.919051573 +0200 +@@ -0,0 +1,116 @@ ++# ++# LIRC driver(s) configuration ++# ++menuconfig INPUT_LIRC ++ tristate "Linux Infrared Remote Control IR receiver/transmitter drivers" ++ help ++ Say Y here, and all supported Linux Infrared Remote Control IR and ++ RF receiver and transmitter drivers will be displayed. When paired ++ with a remote control and the lirc daemon, the receiver drivers ++ allow control of your Linux system via remote control. ++ ++if INPUT_LIRC ++ ++config LIRC_BT829 ++ tristate "BT829 based hardware" ++ depends on INPUT_LIRC ++ help ++ Driver for the IR interface on BT829-based hardware ++ ++config LIRC_ENE0100 ++ tristate "ENE KB3924/ENE0100 CIR Port Reciever" ++ depends on INPUT_LIRC ++ help ++ This is a driver for CIR port handled by ENE KB3924 embedded ++ controller found on some notebooks. ++ It appears on PNP list as ENE0100. ++ ++config LIRC_I2C ++ tristate "I2C Based IR Receivers" ++ depends on INPUT_LIRC ++ help ++ Driver for I2C-based IR receivers, such as those commonly ++ found onboard Hauppauge PVR-150/250/350 video capture cards ++ ++config LIRC_IGORPLUGUSB ++ tristate "Igor Cesko's USB IR Receiver" ++ depends on INPUT_LIRC && USB ++ help ++ Driver for Igor Cesko's USB IR Receiver ++ ++config LIRC_IMON ++ tristate "Legacy SoundGraph iMON Receiver and Display" ++ depends on INPUT_LIRC ++ help ++ Driver for the original SoundGraph iMON IR Receiver and Display ++ ++ Current generation iMON devices use the input layer imon driver. ++ ++config LIRC_IT87 ++ tristate "ITE IT87XX CIR Port Receiver" ++ depends on INPUT_LIRC ++ help ++ Driver for the ITE IT87xx IR Receiver ++ ++config LIRC_ITE8709 ++ tristate "ITE8709 CIR Port Receiver" ++ depends on INPUT_LIRC && PNP ++ help ++ Driver for the ITE8709 IR Receiver ++ ++config LIRC_MCEUSB ++ tristate "Windows Media Center Ed. USB IR Transceiver" ++ depends on INPUT_LIRC && USB ++ help ++ Driver for Windows Media Center Ed. USB IR Transceivers ++ ++config LIRC_PARALLEL ++ tristate "Homebrew Parallel Port Receiver" ++ depends on INPUT_LIRC && !SMP ++ help ++ Driver for Homebrew Parallel Port Receivers ++ ++config LIRC_SASEM ++ tristate "Sasem USB IR Remote" ++ depends on INPUT_LIRC ++ help ++ Driver for the Sasem OnAir Remocon-V or Dign HV5 HTPC IR/VFD Module ++ ++config LIRC_SERIAL ++ tristate "Homebrew Serial Port Receiver" ++ depends on INPUT_LIRC ++ help ++ Driver for Homebrew Serial Port Receivers ++ ++config LIRC_SERIAL_TRANSMITTER ++ bool "Serial Port Transmitter" ++ default y ++ depends on LIRC_SERIAL ++ help ++ Serial Port Transmitter support ++ ++config LIRC_SIR ++ tristate "Built-in SIR IrDA port" ++ depends on INPUT_LIRC ++ help ++ Driver for the SIR IrDA port ++ ++config LIRC_STREAMZAP ++ tristate "Streamzap PC Receiver" ++ depends on INPUT_LIRC ++ help ++ Driver for the Streamzap PC Receiver ++ ++config LIRC_TTUSBIR ++ tristate "Technotrend USB IR Receiver" ++ depends on INPUT_LIRC && USB ++ help ++ Driver for the Technotrend USB IR Receiver ++ ++config LIRC_ZILOG ++ tristate "Zilog/Hauppauge IR Transmitter" ++ depends on INPUT_LIRC ++ help ++ Driver for the Zilog/Hauppauge IR Transmitter, found on ++ PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards ++endif +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_bt829.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_bt829.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_bt829.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_bt829.c 2010-08-02 09:28:03.925051670 +0200 +@@ -0,0 +1,383 @@ ++/* ++ * Remote control driver for the TV-card based on bt829 ++ * ++ * by Leonid Froenchenko ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++*/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lirc_dev.h" ++ ++static int poll_main(void); ++static int atir_init_start(void); ++ ++static void write_index(unsigned char index, unsigned int value); ++static unsigned int read_index(unsigned char index); ++ ++static void do_i2c_start(void); ++static void do_i2c_stop(void); ++ ++static void seems_wr_byte(unsigned char al); ++static unsigned char seems_rd_byte(void); ++ ++static unsigned int read_index(unsigned char al); ++static void write_index(unsigned char ah, unsigned int edx); ++ ++static void cycle_delay(int cycle); ++ ++static void do_set_bits(unsigned char bl); ++static unsigned char do_get_bits(void); ++ ++#define DATA_PCI_OFF 0x7FFC00 ++#define WAIT_CYCLE 20 ++ ++#define DRIVER_NAME "lirc_bt829" ++ ++static int debug; ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG DRIVER_NAME ": "fmt, ## args); \ ++ } while (0) ++ ++static int atir_minor; ++static unsigned long pci_addr_phys; ++static unsigned char *pci_addr_lin; ++ ++static struct lirc_driver atir_driver; ++ ++static struct pci_dev *do_pci_probe(void) ++{ ++ struct pci_dev *my_dev; ++ my_dev = pci_get_device(PCI_VENDOR_ID_ATI, ++ PCI_DEVICE_ID_ATI_264VT, NULL); ++ if (my_dev) { ++ printk(KERN_ERR DRIVER_NAME ": Using device: %s\n", ++ pci_name(my_dev)); ++ pci_addr_phys = 0; ++ if (my_dev->resource[0].flags & IORESOURCE_MEM) { ++ pci_addr_phys = my_dev->resource[0].start; ++ printk(KERN_INFO DRIVER_NAME ": memory at 0x%08X \n", ++ (unsigned int)pci_addr_phys); ++ } ++ if (pci_addr_phys == 0) { ++ printk(KERN_ERR DRIVER_NAME ": no memory resource ?\n"); ++ return NULL; ++ } ++ } else { ++ printk(KERN_ERR DRIVER_NAME ": pci_probe failed\n"); ++ return NULL; ++ } ++ return my_dev; ++} ++ ++static int atir_add_to_buf(void *data, struct lirc_buffer *buf) ++{ ++ unsigned char key; ++ int status; ++ status = poll_main(); ++ key = (status >> 8) & 0xFF; ++ if (status & 0xFF) { ++ dprintk("reading key %02X\n", key); ++ lirc_buffer_write(buf, &key); ++ return 0; ++ } ++ return -ENODATA; ++} ++ ++static int atir_set_use_inc(void *data) ++{ ++ dprintk("driver is opened\n"); ++ return 0; ++} ++ ++static void atir_set_use_dec(void *data) ++{ ++ dprintk("driver is closed\n"); ++} ++ ++int init_module(void) ++{ ++ struct pci_dev *pdev; ++ ++ pdev = do_pci_probe(); ++ if (pdev == NULL) ++ return 1; ++ ++ if (!atir_init_start()) ++ return 1; ++ ++ strcpy(atir_driver.name, "ATIR"); ++ atir_driver.minor = -1; ++ atir_driver.code_length = 8; ++ atir_driver.sample_rate = 10; ++ atir_driver.data = 0; ++ atir_driver.add_to_buf = atir_add_to_buf; ++ atir_driver.set_use_inc = atir_set_use_inc; ++ atir_driver.set_use_dec = atir_set_use_dec; ++ atir_driver.dev = &pdev->dev; ++ atir_driver.owner = THIS_MODULE; ++ ++ atir_minor = lirc_register_driver(&atir_driver); ++ if (atir_minor < 0) { ++ printk(KERN_ERR DRIVER_NAME ": failed to register driver!\n"); ++ return atir_minor; ++ } ++ dprintk("driver is registered on minor %d\n", atir_minor); ++ ++ return 0; ++} ++ ++ ++void cleanup_module(void) ++{ ++ lirc_unregister_driver(atir_minor); ++} ++ ++ ++static int atir_init_start(void) ++{ ++ pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400); ++ if (pci_addr_lin == 0) { ++ printk(KERN_INFO DRIVER_NAME ": pci mem must be mapped\n"); ++ return 0; ++ } ++ return 1; ++} ++ ++static void cycle_delay(int cycle) ++{ ++ udelay(WAIT_CYCLE*cycle); ++} ++ ++ ++static int poll_main() ++{ ++ unsigned char status_high, status_low; ++ ++ do_i2c_start(); ++ ++ seems_wr_byte(0xAA); ++ seems_wr_byte(0x01); ++ ++ do_i2c_start(); ++ ++ seems_wr_byte(0xAB); ++ ++ status_low = seems_rd_byte(); ++ status_high = seems_rd_byte(); ++ ++ do_i2c_stop(); ++ ++ return (status_high << 8) | status_low; ++} ++ ++static void do_i2c_start(void) ++{ ++ do_set_bits(3); ++ cycle_delay(4); ++ ++ do_set_bits(1); ++ cycle_delay(7); ++ ++ do_set_bits(0); ++ cycle_delay(2); ++} ++ ++static void do_i2c_stop(void) ++{ ++ unsigned char bits; ++ bits = do_get_bits() & 0xFD; ++ do_set_bits(bits); ++ cycle_delay(1); ++ ++ bits |= 1; ++ do_set_bits(bits); ++ cycle_delay(2); ++ ++ bits |= 2; ++ do_set_bits(bits); ++ bits = 3; ++ do_set_bits(bits); ++ cycle_delay(2); ++} ++ ++static void seems_wr_byte(unsigned char value) ++{ ++ int i; ++ unsigned char reg; ++ ++ reg = do_get_bits(); ++ for (i = 0; i < 8; i++) { ++ if (value & 0x80) ++ reg |= 0x02; ++ else ++ reg &= 0xFD; ++ ++ do_set_bits(reg); ++ cycle_delay(1); ++ ++ reg |= 1; ++ do_set_bits(reg); ++ cycle_delay(1); ++ ++ reg &= 0xFE; ++ do_set_bits(reg); ++ cycle_delay(1); ++ value <<= 1; ++ } ++ cycle_delay(2); ++ ++ reg |= 2; ++ do_set_bits(reg); ++ ++ reg |= 1; ++ do_set_bits(reg); ++ ++ cycle_delay(1); ++ do_get_bits(); ++ ++ reg &= 0xFE; ++ do_set_bits(reg); ++ cycle_delay(3); ++} ++ ++static unsigned char seems_rd_byte(void) ++{ ++ int i; ++ int rd_byte; ++ unsigned char bits_2, bits_1; ++ ++ bits_1 = do_get_bits() | 2; ++ do_set_bits(bits_1); ++ ++ rd_byte = 0; ++ for (i = 0; i < 8; i++) { ++ bits_1 &= 0xFE; ++ do_set_bits(bits_1); ++ cycle_delay(2); ++ ++ bits_1 |= 1; ++ do_set_bits(bits_1); ++ cycle_delay(1); ++ ++ bits_2 = do_get_bits(); ++ if (bits_2 & 2) ++ rd_byte |= 1; ++ ++ rd_byte <<= 1; ++ } ++ ++ bits_1 = 0; ++ if (bits_2 == 0) ++ bits_1 |= 2; ++ ++ do_set_bits(bits_1); ++ cycle_delay(2); ++ ++ bits_1 |= 1; ++ do_set_bits(bits_1); ++ cycle_delay(3); ++ ++ bits_1 &= 0xFE; ++ do_set_bits(bits_1); ++ cycle_delay(2); ++ ++ rd_byte >>= 1; ++ rd_byte &= 0xFF; ++ return rd_byte; ++} ++ ++static void do_set_bits(unsigned char new_bits) ++{ ++ int reg_val; ++ reg_val = read_index(0x34); ++ if (new_bits & 2) { ++ reg_val &= 0xFFFFFFDF; ++ reg_val |= 1; ++ } else { ++ reg_val &= 0xFFFFFFFE; ++ reg_val |= 0x20; ++ } ++ reg_val |= 0x10; ++ write_index(0x34, reg_val); ++ ++ reg_val = read_index(0x31); ++ if (new_bits & 1) ++ reg_val |= 0x1000000; ++ else ++ reg_val &= 0xFEFFFFFF; ++ ++ reg_val |= 0x8000000; ++ write_index(0x31, reg_val); ++} ++ ++static unsigned char do_get_bits(void) ++{ ++ unsigned char bits; ++ int reg_val; ++ ++ reg_val = read_index(0x34); ++ reg_val |= 0x10; ++ reg_val &= 0xFFFFFFDF; ++ write_index(0x34, reg_val); ++ ++ reg_val = read_index(0x34); ++ bits = 0; ++ if (reg_val & 8) ++ bits |= 2; ++ else ++ bits &= 0xFD; ++ ++ reg_val = read_index(0x31); ++ if (reg_val & 0x1000000) ++ bits |= 1; ++ else ++ bits &= 0xFE; ++ ++ return bits; ++} ++ ++static unsigned int read_index(unsigned char index) ++{ ++ unsigned char *addr; ++ unsigned int value; ++ /* addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */ ++ addr = pci_addr_lin + ((index & 0xFF) << 2); ++ value = readl(addr); ++ return value; ++} ++ ++static void write_index(unsigned char index, unsigned int reg_val) ++{ ++ unsigned char *addr; ++ addr = pci_addr_lin + ((index & 0xFF) << 2); ++ writel(reg_val, addr); ++} ++ ++MODULE_AUTHOR("Froenchenko Leonid"); ++MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards"); ++MODULE_LICENSE("GPL"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug enabled or not"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_dev.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_dev.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_dev.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_dev.c 2010-08-02 09:28:03.928052591 +0200 +@@ -0,0 +1,850 @@ ++/* ++ * LIRC base driver ++ * ++ * by Artur Lipowski ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_COMPAT ++#include ++#endif ++ ++#include ++#include "lirc_dev.h" ++ ++static int debug; ++ ++#define IRCTL_DEV_NAME "BaseRemoteCtl" ++#define NOPLUG -1 ++#define LOGHEAD "lirc_dev (%s[%d]): " ++ ++static dev_t lirc_base_dev; ++ ++struct irctl { ++ struct lirc_driver d; ++ int attached; ++ int open; ++ ++ struct mutex irctl_lock; ++ struct lirc_buffer *buf; ++ unsigned int chunk_size; ++ ++ struct task_struct *task; ++ long jiffies_to_wait; ++ ++ struct cdev cdev; ++}; ++ ++static DEFINE_MUTEX(lirc_dev_lock); ++ ++static struct irctl *irctls[MAX_IRCTL_DEVICES]; ++ ++/* Only used for sysfs but defined to void otherwise */ ++static struct class *lirc_class; ++ ++/* helper function ++ * initializes the irctl structure ++ */ ++static void init_irctl(struct irctl *ir) ++{ ++ dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n", ++ ir->d.name, ir->d.minor); ++ mutex_init(&ir->irctl_lock); ++ ir->d.minor = NOPLUG; ++} ++ ++static void cleanup(struct irctl *ir) ++{ ++ dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor); ++ ++ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); ++ ++ if (ir->buf != ir->d.rbuf) { ++ lirc_buffer_free(ir->buf); ++ kfree(ir->buf); ++ } ++ ir->buf = NULL; ++} ++ ++/* helper function ++ * reads key codes from driver and puts them into buffer ++ * returns 0 on success ++ */ ++static int add_to_buf(struct irctl *ir) ++{ ++ if (ir->d.add_to_buf) { ++ int res = -ENODATA; ++ int got_data = 0; ++ ++ /* ++ * service the device as long as it is returning ++ * data and we have space ++ */ ++get_data: ++ res = ir->d.add_to_buf(ir->d.data, ir->buf); ++ if (res == 0) { ++ got_data++; ++ goto get_data; ++ } ++ ++ if (res == -ENODEV) ++ kthread_stop(ir->task); ++ ++ return got_data ? 0 : res; ++ } ++ ++ return 0; ++} ++ ++/* main function of the polling thread ++ */ ++static int lirc_thread(void *irctl) ++{ ++ struct irctl *ir = irctl; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n", ++ ir->d.name, ir->d.minor); ++ ++ do { ++ if (ir->open) { ++ if (ir->jiffies_to_wait) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(ir->jiffies_to_wait); ++ } ++ if (kthread_should_stop()) ++ break; ++ if (!add_to_buf(ir)) ++ wake_up_interruptible(&ir->buf->wait_poll); ++ } else { ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule(); ++ } ++ } while (!kthread_should_stop()); ++ ++ dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n", ++ ir->d.name, ir->d.minor); ++ ++ return 0; ++} ++ ++ ++static struct file_operations fops = { ++ .owner = THIS_MODULE, ++ .read = lirc_dev_fop_read, ++ .write = lirc_dev_fop_write, ++ .poll = lirc_dev_fop_poll, ++ .ioctl = lirc_dev_fop_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = lirc_dev_fop_compat_ioctl, ++#endif ++ .open = lirc_dev_fop_open, ++ .release = lirc_dev_fop_close, ++}; ++ ++static int lirc_cdev_add(struct irctl *ir) ++{ ++ int retval; ++ struct lirc_driver *d = &ir->d; ++ ++ if (d->fops) { ++ cdev_init(&ir->cdev, d->fops); ++ ir->cdev.owner = d->owner; ++ } else { ++ cdev_init(&ir->cdev, &fops); ++ ir->cdev.owner = THIS_MODULE; ++ } ++ kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor); ++ ++ retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); ++ if (retval) ++ kobject_put(&ir->cdev.kobj); ++ ++ return retval; ++} ++ ++int lirc_register_driver(struct lirc_driver *d) ++{ ++ struct irctl *ir; ++ int minor; ++ int bytes_in_key; ++ unsigned int chunk_size; ++ unsigned int buffer_size; ++ int err; ++ ++ if (!d) { ++ printk(KERN_ERR "lirc_dev: lirc_register_driver: " ++ "driver pointer must be not NULL!\n"); ++ err = -EBADRQC; ++ goto out; ++ } ++ ++ if (MAX_IRCTL_DEVICES <= d->minor) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "\"minor\" must be between 0 and %d (%d)!\n", ++ MAX_IRCTL_DEVICES-1, d->minor); ++ err = -EBADRQC; ++ goto out; ++ } ++ ++ if (1 > d->code_length || (BUFLEN * 8) < d->code_length) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "code length in bits for minor (%d) " ++ "must be less than %d!\n", ++ d->minor, BUFLEN * 8); ++ err = -EBADRQC; ++ goto out; ++ } ++ ++ dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n", ++ d->sample_rate); ++ if (d->sample_rate) { ++ if (2 > d->sample_rate || HZ < d->sample_rate) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "sample_rate must be between 2 and %d!\n", HZ); ++ err = -EBADRQC; ++ goto out; ++ } ++ if (!d->add_to_buf) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "add_to_buf cannot be NULL when " ++ "sample_rate is set\n"); ++ err = -EBADRQC; ++ goto out; ++ } ++ } else if (!(d->fops && d->fops->read) && !d->rbuf) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "fops->read and rbuf cannot all be NULL!\n"); ++ err = -EBADRQC; ++ goto out; ++ } else if (!d->rbuf) { ++ if (!(d->fops && d->fops->read && d->fops->poll && ++ d->fops->ioctl)) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "neither read, poll nor ioctl can be NULL!\n"); ++ err = -EBADRQC; ++ goto out; ++ } ++ } ++ ++ mutex_lock(&lirc_dev_lock); ++ ++ minor = d->minor; ++ ++ if (minor < 0) { ++ /* find first free slot for driver */ ++ for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) ++ if (!irctls[minor]) ++ break; ++ if (MAX_IRCTL_DEVICES == minor) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "no free slots for drivers!\n"); ++ err = -ENOMEM; ++ goto out_lock; ++ } ++ } else if (irctls[minor]) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "minor (%d) just registered!\n", minor); ++ err = -EBUSY; ++ goto out_lock; ++ } ++ ++ ir = kzalloc(sizeof(struct irctl), GFP_KERNEL); ++ if (!ir) { ++ err = -ENOMEM; ++ goto out_lock; ++ } ++ init_irctl(ir); ++ irctls[minor] = ir; ++ d->minor = minor; ++ ++ if (d->sample_rate) { ++ ir->jiffies_to_wait = HZ / d->sample_rate; ++ } else { ++ /* it means - wait for external event in task queue */ ++ ir->jiffies_to_wait = 0; ++ } ++ ++ /* some safety check 8-) */ ++ d->name[sizeof(d->name)-1] = '\0'; ++ ++ bytes_in_key = BITS_TO_LONGS(d->code_length) + ++ (d->code_length % 8 ? 1 : 0); ++ buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key; ++ chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key; ++ ++ if (d->rbuf) { ++ ir->buf = d->rbuf; ++ } else { ++ ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!ir->buf) { ++ err = -ENOMEM; ++ goto out_lock; ++ } ++ err = lirc_buffer_init(ir->buf, chunk_size, buffer_size); ++ if (err) { ++ kfree(ir->buf); ++ goto out_lock; ++ } ++ } ++ ir->chunk_size = ir->buf->chunk_size; ++ ++ if (d->features == 0) ++ d->features = LIRC_CAN_REC_LIRCCODE; ++ ++ ir->d = *d; ++ ir->d.minor = minor; ++ ++ device_create(lirc_class, ir->d.dev, ++ MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL, ++ "lirc%u", ir->d.minor); ++ ++ if (d->sample_rate) { ++ /* try to fire up polling thread */ ++ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); ++ if (IS_ERR(ir->task)) { ++ dev_err(d->dev, "lirc_dev: lirc_register_driver: " ++ "cannot run poll thread for minor = %d\n", ++ d->minor); ++ err = -ECHILD; ++ goto out_sysfs; ++ } ++ } ++ ++ err = lirc_cdev_add(ir); ++ if (err) ++ goto out_sysfs; ++ ++ ir->attached = 1; ++ mutex_unlock(&lirc_dev_lock); ++ ++ dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n", ++ ir->d.name, ir->d.minor); ++ return minor; ++ ++out_sysfs: ++ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor)); ++out_lock: ++ mutex_unlock(&lirc_dev_lock); ++out: ++ return err; ++} ++EXPORT_SYMBOL(lirc_register_driver); ++ ++int lirc_unregister_driver(int minor) ++{ ++ struct irctl *ir; ++ ++ if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { ++ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " ++ "\"minor (%d)\" must be between 0 and %d!\n", ++ minor, MAX_IRCTL_DEVICES-1); ++ return -EBADRQC; ++ } ++ ++ ir = irctls[minor]; ++ ++ mutex_lock(&lirc_dev_lock); ++ ++ if (ir->d.minor != minor) { ++ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: " ++ "minor (%d) device not registered!", minor); ++ mutex_unlock(&lirc_dev_lock); ++ return -ENOENT; ++ } ++ ++ /* end up polling thread */ ++ if (ir->task) ++ kthread_stop(ir->task); ++ ++ dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n", ++ ir->d.name, ir->d.minor); ++ ++ ir->attached = 0; ++ if (ir->open) { ++ dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n", ++ ir->d.name, ir->d.minor); ++ wake_up_interruptible(&ir->buf->wait_poll); ++ mutex_lock(&ir->irctl_lock); ++ ir->d.set_use_dec(ir->d.data); ++ module_put(ir->d.owner); ++ mutex_unlock(&ir->irctl_lock); ++ cdev_del(&ir->cdev); ++ } else { ++ cleanup(ir); ++ cdev_del(&ir->cdev); ++ kfree(ir); ++ irctls[minor] = NULL; ++ } ++ ++ mutex_unlock(&lirc_dev_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL(lirc_unregister_driver); ++ ++int lirc_dev_fop_open(struct inode *inode, struct file *file) ++{ ++ struct irctl *ir; ++ int retval = 0; ++ ++ if (iminor(inode) >= MAX_IRCTL_DEVICES) { ++ printk(KERN_WARNING "lirc_dev [%d]: open result = -ENODEV\n", ++ iminor(inode)); ++ return -ENODEV; ++ } ++ ++ if (mutex_lock_interruptible(&lirc_dev_lock)) ++ return -ERESTARTSYS; ++ ++ ir = irctls[iminor(inode)]; ++ if (!ir) { ++ retval = -ENODEV; ++ goto error; ++ } ++ ++ dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor); ++ ++ if (ir->d.minor == NOPLUG) { ++ retval = -ENODEV; ++ goto error; ++ } ++ ++ if (ir->open) { ++ retval = -EBUSY; ++ goto error; ++ } ++ ++ if (try_module_get(ir->d.owner)) { ++ ++ir->open; ++ retval = ir->d.set_use_inc(ir->d.data); ++ ++ if (retval) { ++ module_put(ir->d.owner); ++ --ir->open; ++ } else { ++ lirc_buffer_clear(ir->buf); ++ } ++ if (ir->task) ++ wake_up_process(ir->task); ++ } ++ ++error: ++ if (ir) ++ dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n", ++ ir->d.name, ir->d.minor, retval); ++ ++ mutex_unlock(&lirc_dev_lock); ++ ++ return retval; ++} ++EXPORT_SYMBOL(lirc_dev_fop_open); ++ ++int lirc_dev_fop_close(struct inode *inode, struct file *file) ++{ ++ struct irctl *ir = irctls[iminor(inode)]; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); ++ ++ WARN_ON(mutex_lock_killable(&lirc_dev_lock)); ++ ++ --ir->open; ++ if (ir->attached) { ++ ir->d.set_use_dec(ir->d.data); ++ module_put(ir->d.owner); ++ } else { ++ cleanup(ir); ++ irctls[ir->d.minor] = NULL; ++ kfree(ir); ++ } ++ ++ mutex_unlock(&lirc_dev_lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL(lirc_dev_fop_close); ++ ++unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) ++{ ++ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; ++ unsigned int ret; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); ++ ++ if (!ir->attached) { ++ mutex_unlock(&ir->irctl_lock); ++ return POLLERR; ++ } ++ ++ poll_wait(file, &ir->buf->wait_poll, wait); ++ ++ if (ir->buf) ++ if (lirc_buffer_empty(ir->buf)) ++ ret = 0; ++ else ++ ret = POLLIN | POLLRDNORM; ++ else ++ ret = POLLERR; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n", ++ ir->d.name, ir->d.minor, ret); ++ ++ return ret; ++} ++EXPORT_SYMBOL(lirc_dev_fop_poll); ++ ++int lirc_dev_fop_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ unsigned long mode; ++ int result = 0; ++ struct irctl *ir = irctls[iminor(inode)]; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n", ++ ir->d.name, ir->d.minor, cmd); ++ ++ if (ir->d.minor == NOPLUG || !ir->attached) { ++ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n", ++ ir->d.name, ir->d.minor); ++ return -ENODEV; ++ } ++ ++ switch (cmd) { ++ case LIRC_GET_FEATURES: ++ result = put_user(ir->d.features, (unsigned long *)arg); ++ break; ++ case LIRC_GET_REC_MODE: ++ if (!(ir->d.features & LIRC_CAN_REC_MASK)) ++ return -ENOSYS; ++ ++ result = put_user(LIRC_REC2MODE ++ (ir->d.features & LIRC_CAN_REC_MASK), ++ (unsigned long *)arg); ++ break; ++ case LIRC_SET_REC_MODE: ++ if (!(ir->d.features & LIRC_CAN_REC_MASK)) ++ return -ENOSYS; ++ ++ result = get_user(mode, (unsigned long *)arg); ++ if (!result && !(LIRC_MODE2REC(mode) & ir->d.features)) ++ result = -EINVAL; ++ /* ++ * FIXME: We should actually set the mode somehow but ++ * for now, lirc_serial doesn't support mode changing either ++ */ ++ break; ++ case LIRC_GET_LENGTH: ++ result = put_user(ir->d.code_length, (unsigned long *)arg); ++ break; ++ case LIRC_GET_MIN_TIMEOUT: ++ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ++ ir->d.min_timeout == 0) ++ return -ENOSYS; ++ ++ result = put_user(ir->d.min_timeout, (int *) arg); ++ break; ++ case LIRC_GET_MAX_TIMEOUT: ++ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) || ++ ir->d.max_timeout == 0) ++ return -ENOSYS; ++ ++ result = put_user(ir->d.max_timeout, (int *) arg); ++ break; ++ default: ++ result = -EINVAL; ++ } ++ ++ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n", ++ ir->d.name, ir->d.minor, result); ++ ++ return result; ++} ++EXPORT_SYMBOL(lirc_dev_fop_ioctl); ++ ++#ifdef CONFIG_COMPAT ++#define LIRC_GET_FEATURES_COMPAT32 _IOR('i', 0x00000000, __u32) ++ ++#define LIRC_GET_SEND_MODE_COMPAT32 _IOR('i', 0x00000001, __u32) ++#define LIRC_GET_REC_MODE_COMPAT32 _IOR('i', 0x00000002, __u32) ++ ++#define LIRC_GET_LENGTH_COMPAT32 _IOR('i', 0x0000000f, __u32) ++ ++#define LIRC_SET_SEND_MODE_COMPAT32 _IOW('i', 0x00000011, __u32) ++#define LIRC_SET_REC_MODE_COMPAT32 _IOW('i', 0x00000012, __u32) ++ ++long lirc_dev_fop_compat_ioctl(struct file *file, ++ unsigned int cmd32, ++ unsigned long arg) ++{ ++ mm_segment_t old_fs; ++ int ret; ++ unsigned long val; ++ unsigned int cmd; ++ ++ switch (cmd32) { ++ case LIRC_GET_FEATURES_COMPAT32: ++ case LIRC_GET_SEND_MODE_COMPAT32: ++ case LIRC_GET_REC_MODE_COMPAT32: ++ case LIRC_GET_LENGTH_COMPAT32: ++ case LIRC_SET_SEND_MODE_COMPAT32: ++ case LIRC_SET_REC_MODE_COMPAT32: ++ /* ++ * These commands expect (unsigned long *) arg ++ * but the 32-bit app supplied (__u32 *). ++ * Conversion is required. ++ */ ++ if (get_user(val, (__u32 *)compat_ptr(arg))) ++ return -EFAULT; ++ lock_kernel(); ++ /* ++ * tell lirc_dev_fop_ioctl that it's safe to use the pointer ++ * to val which is in kernel address space and not in ++ * user address space. ++ */ ++ old_fs = get_fs(); ++ set_fs(KERNEL_DS); ++ ++ cmd = _IOC(_IOC_DIR(cmd32), _IOC_TYPE(cmd32), _IOC_NR(cmd32), ++ (_IOC_TYPECHECK(unsigned long))); ++ ret = lirc_dev_fop_ioctl(file->f_path.dentry->d_inode, file, ++ cmd, (unsigned long)(&val)); ++ ++ set_fs(old_fs); ++ unlock_kernel(); ++ switch (cmd) { ++ case LIRC_GET_FEATURES: ++ case LIRC_GET_SEND_MODE: ++ case LIRC_GET_REC_MODE: ++ case LIRC_GET_LENGTH: ++ if (!ret && put_user(val, (__u32 *)compat_ptr(arg))) ++ return -EFAULT; ++ break; ++ } ++ return ret; ++ ++ case LIRC_GET_SEND_CARRIER: ++ case LIRC_GET_REC_CARRIER: ++ case LIRC_GET_SEND_DUTY_CYCLE: ++ case LIRC_GET_REC_DUTY_CYCLE: ++ case LIRC_GET_REC_RESOLUTION: ++ case LIRC_SET_SEND_CARRIER: ++ case LIRC_SET_REC_CARRIER: ++ case LIRC_SET_SEND_DUTY_CYCLE: ++ case LIRC_SET_REC_DUTY_CYCLE: ++ case LIRC_SET_TRANSMITTER_MASK: ++ case LIRC_SET_REC_DUTY_CYCLE_RANGE: ++ case LIRC_SET_REC_CARRIER_RANGE: ++ /* ++ * These commands expect (unsigned int *)arg ++ * so no problems here. Just handle the locking. ++ */ ++ lock_kernel(); ++ cmd = cmd32; ++ ret = lirc_dev_fop_ioctl(file->f_path.dentry->d_inode, ++ file, cmd, arg); ++ unlock_kernel(); ++ return ret; ++ default: ++ /* unknown */ ++ printk(KERN_ERR "lirc_dev: %s(%s:%d): Unknown cmd %08x\n", ++ __func__, current->comm, current->pid, cmd32); ++ return -ENOIOCTLCMD; ++ } ++} ++EXPORT_SYMBOL(lirc_dev_fop_compat_ioctl); ++#endif ++ ++ ++ssize_t lirc_dev_fop_read(struct file *file, ++ char *buffer, ++ size_t length, ++ loff_t *ppos) ++{ ++ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; ++ unsigned char buf[ir->chunk_size]; ++ int ret = 0, written = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor); ++ ++ if (mutex_lock_interruptible(&ir->irctl_lock)) ++ return -ERESTARTSYS; ++ if (!ir->attached) { ++ mutex_unlock(&ir->irctl_lock); ++ return -ENODEV; ++ } ++ ++ if (length % ir->chunk_size) { ++ dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n", ++ ir->d.name, ir->d.minor); ++ mutex_unlock(&ir->irctl_lock); ++ return -EINVAL; ++ } ++ ++ /* ++ * we add ourselves to the task queue before buffer check ++ * to avoid losing scan code (in case when queue is awaken somewhere ++ * between while condition checking and scheduling) ++ */ ++ add_wait_queue(&ir->buf->wait_poll, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ /* ++ * while we didn't provide 'length' bytes, device is opened in blocking ++ * mode and 'copy_to_user' is happy, wait for data. ++ */ ++ while (written < length && ret == 0) { ++ if (lirc_buffer_empty(ir->buf)) { ++ /* According to the read(2) man page, 'written' can be ++ * returned as less than 'length', instead of blocking ++ * again, returning -EWOULDBLOCK, or returning ++ * -ERESTARTSYS */ ++ if (written) ++ break; ++ if (file->f_flags & O_NONBLOCK) { ++ ret = -EWOULDBLOCK; ++ break; ++ } ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ ++ mutex_unlock(&ir->irctl_lock); ++ schedule(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ if (mutex_lock_interruptible(&ir->irctl_lock)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ ++ if (!ir->attached) { ++ ret = -ENODEV; ++ break; ++ } ++ } else { ++ lirc_buffer_read(ir->buf, buf); ++ ret = copy_to_user((void *)buffer+written, buf, ++ ir->buf->chunk_size); ++ written += ir->buf->chunk_size; ++ } ++ } ++ ++ remove_wait_queue(&ir->buf->wait_poll, &wait); ++ set_current_state(TASK_RUNNING); ++ mutex_unlock(&ir->irctl_lock); ++ ++ dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", ++ ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); ++ ++ return ret ? ret : written; ++} ++EXPORT_SYMBOL(lirc_dev_fop_read); ++ ++void *lirc_get_pdata(struct file *file) ++{ ++ void *data = NULL; ++ ++ if (file && file->f_dentry && file->f_dentry->d_inode && ++ file->f_dentry->d_inode->i_rdev) { ++ struct irctl *ir; ++ ir = irctls[iminor(file->f_dentry->d_inode)]; ++ data = ir->d.data; ++ } ++ ++ return data; ++} ++EXPORT_SYMBOL(lirc_get_pdata); ++ ++ ++ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, ++ size_t length, loff_t *ppos) ++{ ++ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)]; ++ ++ dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor); ++ ++ if (!ir->attached) ++ return -ENODEV; ++ ++ return -EINVAL; ++} ++EXPORT_SYMBOL(lirc_dev_fop_write); ++ ++ ++static int __init lirc_dev_init(void) ++{ ++ int retval; ++ ++ lirc_class = class_create(THIS_MODULE, "lirc"); ++ if (IS_ERR(lirc_class)) { ++ retval = PTR_ERR(lirc_class); ++ printk(KERN_ERR "lirc_dev: class_create failed\n"); ++ goto error; ++ } ++ ++ retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES, ++ IRCTL_DEV_NAME); ++ if (retval) { ++ class_destroy(lirc_class); ++ printk(KERN_ERR "lirc_dev: alloc_chrdev_region failed\n"); ++ goto error; ++ } ++ ++ ++ printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, " ++ "major %d \n", MAJOR(lirc_base_dev)); ++ ++error: ++ return retval; ++} ++ ++ ++ ++static void __exit lirc_dev_exit(void) ++{ ++ class_destroy(lirc_class); ++ unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES); ++ printk(KERN_INFO "lirc_dev: module unloaded\n"); ++} ++ ++module_init(lirc_dev_init); ++module_exit(lirc_dev_exit); ++ ++MODULE_DESCRIPTION("LIRC base driver module"); ++MODULE_AUTHOR("Artur Lipowski"); ++MODULE_LICENSE("GPL"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_dev.h linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_dev.h +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_dev.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_dev.h 2010-08-02 09:28:03.929052362 +0200 +@@ -0,0 +1,228 @@ ++/* ++ * LIRC base driver ++ * ++ * by Artur Lipowski ++ * This code is licensed under GNU GPL ++ * ++ */ ++ ++#ifndef _LINUX_LIRC_DEV_H ++#define _LINUX_LIRC_DEV_H ++ ++#define MAX_IRCTL_DEVICES 4 ++#define BUFLEN 16 ++ ++#define mod(n, div) ((n) % (div)) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct lirc_buffer { ++ wait_queue_head_t wait_poll; ++ spinlock_t fifo_lock; ++ unsigned int chunk_size; ++ unsigned int size; /* in chunks */ ++ /* Using chunks instead of bytes pretends to simplify boundary checking ++ * And should allow for some performance fine tunning later */ ++ struct kfifo fifo; ++ u8 fifo_initialized; ++}; ++ ++static inline void lirc_buffer_clear(struct lirc_buffer *buf) ++{ ++ unsigned long flags; ++ ++ if (buf->fifo_initialized) { ++ spin_lock_irqsave(&buf->fifo_lock, flags); ++ kfifo_reset(&buf->fifo); ++ spin_unlock_irqrestore(&buf->fifo_lock, flags); ++ } else ++ WARN(1, "calling %s on an uninitialized lirc_buffer\n", ++ __func__); ++} ++ ++static inline int lirc_buffer_init(struct lirc_buffer *buf, ++ unsigned int chunk_size, ++ unsigned int size) ++{ ++ int ret; ++ ++ init_waitqueue_head(&buf->wait_poll); ++ spin_lock_init(&buf->fifo_lock); ++ buf->chunk_size = chunk_size; ++ buf->size = size; ++ ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); ++ if (ret == 0) ++ buf->fifo_initialized = 1; ++ ++ return ret; ++} ++ ++static inline void lirc_buffer_free(struct lirc_buffer *buf) ++{ ++ if (buf->fifo_initialized) { ++ kfifo_free(&buf->fifo); ++ buf->fifo_initialized = 0; ++ } else ++ WARN(1, "calling %s on an uninitialized lirc_buffer\n", ++ __func__); ++} ++ ++static inline int lirc_buffer_len(struct lirc_buffer *buf) ++{ ++ int len; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&buf->fifo_lock, flags); ++ len = kfifo_len(&buf->fifo); ++ spin_unlock_irqrestore(&buf->fifo_lock, flags); ++ ++ return len; ++} ++ ++static inline int lirc_buffer_full(struct lirc_buffer *buf) ++{ ++ return lirc_buffer_len(buf) == buf->size * buf->chunk_size; ++} ++ ++static inline int lirc_buffer_empty(struct lirc_buffer *buf) ++{ ++ return !lirc_buffer_len(buf); ++} ++ ++static inline int lirc_buffer_available(struct lirc_buffer *buf) ++{ ++ return buf->size - (lirc_buffer_len(buf) / buf->chunk_size); ++} ++ ++static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf, ++ unsigned char *dest) ++{ ++ unsigned int ret = 0; ++ ++ if (lirc_buffer_len(buf) >= buf->chunk_size) ++ ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size, ++ &buf->fifo_lock); ++ return ret; ++ ++} ++ ++static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, ++ unsigned char *orig) ++{ ++ unsigned int ret; ++ ++ ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size, ++ &buf->fifo_lock); ++ ++ return ret; ++} ++ ++struct lirc_driver { ++ char name[40]; ++ int minor; ++ unsigned long code_length; ++ unsigned int buffer_size; /* in chunks holding one code each */ ++ int sample_rate; ++ unsigned long features; ++ ++ unsigned int chunk_size; ++ ++ void *data; ++ int min_timeout; ++ int max_timeout; ++ int (*add_to_buf) (void *data, struct lirc_buffer *buf); ++ struct lirc_buffer *rbuf; ++ int (*set_use_inc) (void *data); ++ void (*set_use_dec) (void *data); ++ struct file_operations *fops; ++ struct device *dev; ++ struct module *owner; ++}; ++ ++/* name: ++ * this string will be used for logs ++ * ++ * minor: ++ * indicates minor device (/dev/lirc) number for registered driver ++ * if caller fills it with negative value, then the first free minor ++ * number will be used (if available) ++ * ++ * code_length: ++ * length of the remote control key code expressed in bits ++ * ++ * sample_rate: ++ * ++ * data: ++ * it may point to any driver data and this pointer will be passed to ++ * all callback functions ++ * ++ * add_to_buf: ++ * add_to_buf will be called after specified period of the time or ++ * triggered by the external event, this behavior depends on value of ++ * the sample_rate this function will be called in user context. This ++ * routine should return 0 if data was added to the buffer and ++ * -ENODATA if none was available. This should add some number of bits ++ * evenly divisible by code_length to the buffer ++ * ++ * rbuf: ++ * if not NULL, it will be used as a read buffer, you will have to ++ * write to the buffer by other means, like irq's (see also ++ * lirc_serial.c). ++ * ++ * set_use_inc: ++ * set_use_inc will be called after device is opened ++ * ++ * set_use_dec: ++ * set_use_dec will be called after device is closed ++ * ++ * fops: ++ * file_operations for drivers which don't fit the current driver model. ++ * ++ * Some ioctl's can be directly handled by lirc_dev if the driver's ++ * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also ++ * lirc_serial.c). ++ * ++ * owner: ++ * the module owning this struct ++ * ++ */ ++ ++ ++/* following functions can be called ONLY from user context ++ * ++ * returns negative value on error or minor number ++ * of the registered device if success ++ * contents of the structure pointed by p is copied ++ */ ++extern int lirc_register_driver(struct lirc_driver *d); ++ ++/* returns negative value on error or 0 if success ++*/ ++extern int lirc_unregister_driver(int minor); ++ ++/* Returns the private data stored in the lirc_driver ++ * associated with the given device file pointer. ++ */ ++void *lirc_get_pdata(struct file *file); ++ ++/* default file operations ++ * used by drivers if they override only some operations ++ */ ++int lirc_dev_fop_open(struct inode *inode, struct file *file); ++int lirc_dev_fop_close(struct inode *inode, struct file *file); ++unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait); ++int lirc_dev_fop_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg); ++ssize_t lirc_dev_fop_read(struct file *file, char *buffer, size_t length, ++ loff_t *ppos); ++ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, size_t length, ++ loff_t *ppos); ++long lirc_dev_fop_compat_ioctl(struct file *file, unsigned int cmd32, ++ unsigned long arg); ++ ++#endif +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_ene0100.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ene0100.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_ene0100.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ene0100.c 2010-08-02 09:28:03.931051836 +0200 +@@ -0,0 +1,646 @@ ++/* ++ * driver for ENE KB3926 B/C/D CIR (also known as ENE0100) ++ * ++ * Copyright (C) 2009 Maxim Levitsky ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ * USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "lirc_ene0100.h" ++ ++static int sample_period = 75; ++static int enable_idle = 1; ++static int enable_learning; ++ ++static void ene_set_idle(struct ene_device *dev, int idle); ++static void ene_set_inputs(struct ene_device *dev, int enable); ++ ++/* read a hardware register */ ++static u8 ene_hw_read_reg(struct ene_device *dev, u16 reg) ++{ ++ outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); ++ outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); ++ return inb(dev->hw_io + ENE_IO); ++} ++ ++/* write a hardware register */ ++static void ene_hw_write_reg(struct ene_device *dev, u16 reg, u8 value) ++{ ++ outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); ++ outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); ++ outb(value, dev->hw_io + ENE_IO); ++} ++ ++/* change specific bits in hardware register */ ++static void ene_hw_write_reg_mask(struct ene_device *dev, ++ u16 reg, u8 value, u8 mask) ++{ ++ u8 regvalue; ++ ++ outb(reg >> 8, dev->hw_io + ENE_ADDR_HI); ++ outb(reg & 0xFF, dev->hw_io + ENE_ADDR_LO); ++ ++ regvalue = inb(dev->hw_io + ENE_IO) & ~mask; ++ regvalue |= (value & mask); ++ outb(regvalue, dev->hw_io + ENE_IO); ++} ++ ++/* read irq status and ack it */ ++static int ene_hw_irq_status(struct ene_device *dev, int *buffer_pointer) ++{ ++ u8 irq_status; ++ u8 fw_flags1, fw_flags2; ++ ++ fw_flags2 = ene_hw_read_reg(dev, ENE_FW2); ++ ++ if (buffer_pointer) ++ *buffer_pointer = 4 * (fw_flags2 & ENE_FW2_BUF_HIGH); ++ ++ if (dev->hw_revision < ENE_HW_C) { ++ irq_status = ene_hw_read_reg(dev, ENEB_IRQ_STATUS); ++ ++ if (!(irq_status & ENEB_IRQ_STATUS_IR)) ++ return 0; ++ ene_hw_write_reg(dev, ENEB_IRQ_STATUS, ++ irq_status & ~ENEB_IRQ_STATUS_IR); ++ ++ /* rev B support only recieving */ ++ return ENE_IRQ_RX; ++ } ++ ++ irq_status = ene_hw_read_reg(dev, ENEC_IRQ); ++ ++ if (!(irq_status & ENEC_IRQ_STATUS)) ++ return 0; ++ ++ /* original driver does that twice - a workaround ? */ ++ ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS); ++ ene_hw_write_reg(dev, ENEC_IRQ, irq_status & ~ENEC_IRQ_STATUS); ++ ++ /* clear unknown flag in F8F9 */ ++ if (fw_flags2 & ENE_FW2_IRQ_CLR) ++ ene_hw_write_reg(dev, ENE_FW2, fw_flags2 & ~ENE_FW2_IRQ_CLR); ++ ++ /* check if this is a TX interrupt */ ++ fw_flags1 = ene_hw_read_reg(dev, ENE_FW1); ++ ++ if (fw_flags1 & ENE_FW1_TXIRQ) { ++ ene_hw_write_reg(dev, ENE_FW1, fw_flags1 & ~ENE_FW1_TXIRQ); ++ return ENE_IRQ_TX; ++ } else ++ return ENE_IRQ_RX; ++} ++ ++static int ene_hw_detect(struct ene_device *dev) ++{ ++ u8 chip_major, chip_minor; ++ u8 hw_revision, old_ver; ++ u8 tmp; ++ u8 fw_capabilities; ++ ++ tmp = ene_hw_read_reg(dev, ENE_HW_UNK); ++ ene_hw_write_reg(dev, ENE_HW_UNK, tmp & ~ENE_HW_UNK_CLR); ++ ++ chip_major = ene_hw_read_reg(dev, ENE_HW_VER_MAJOR); ++ chip_minor = ene_hw_read_reg(dev, ENE_HW_VER_MINOR); ++ ++ ene_hw_write_reg(dev, ENE_HW_UNK, tmp); ++ hw_revision = ene_hw_read_reg(dev, ENE_HW_VERSION); ++ old_ver = ene_hw_read_reg(dev, ENE_HW_VER_OLD); ++ ++ if (hw_revision == 0xFF) { ++ ++ ene_printk(KERN_WARNING, "device seems to be disabled\n"); ++ ene_printk(KERN_WARNING, ++ "send a mail to lirc-list@lists.sourceforge.net\n"); ++ ene_printk(KERN_WARNING, "please attach output of acpidump\n"); ++ ++ return -ENODEV; ++ } ++ ++ if (chip_major == 0x33) { ++ ene_printk(KERN_WARNING, "chips 0x33xx aren't supported yet\n"); ++ return -ENODEV; ++ } ++ ++ if (chip_major == 0x39 && chip_minor == 0x26 && hw_revision == 0xC0) { ++ dev->hw_revision = ENE_HW_C; ++ ene_printk(KERN_WARNING, ++ "KB3926C detected, driver support is not complete!\n"); ++ ++ } else if (old_ver == 0x24 && hw_revision == 0xC0) { ++ dev->hw_revision = ENE_HW_B; ++ ene_printk(KERN_NOTICE, "KB3926B detected\n"); ++ } else { ++ dev->hw_revision = ENE_HW_D; ++ ene_printk(KERN_WARNING, ++ "unknown ENE chip detected, assuming KB3926D\n"); ++ ene_printk(KERN_WARNING, "driver support incomplete"); ++ ++ } ++ ++ ene_printk(KERN_DEBUG, "chip is 0x%02x%02x - 0x%02x, 0x%02x\n", ++ chip_major, chip_minor, old_ver, hw_revision); ++ ++ ++ /* detect features hardware supports */ ++ ++ if (dev->hw_revision < ENE_HW_C) ++ return 0; ++ ++ fw_capabilities = ene_hw_read_reg(dev, ENE_FW2); ++ ++ dev->hw_gpio40_learning = fw_capabilities & ENE_FW2_GP40_AS_LEARN; ++ dev->hw_learning_and_tx_capable = fw_capabilities & ENE_FW2_LEARNING; ++ ++ dev->hw_fan_as_normal_input = dev->hw_learning_and_tx_capable && ++ fw_capabilities & ENE_FW2_FAN_AS_NRML_IN; ++ ++ ene_printk(KERN_NOTICE, "hardware features:\n"); ++ ene_printk(KERN_NOTICE, ++ "learning and tx %s, gpio40_learn %s, fan_in %s\n", ++ dev->hw_learning_and_tx_capable ? "on" : "off", ++ dev->hw_gpio40_learning ? "on" : "off", ++ dev->hw_fan_as_normal_input ? "on" : "off"); ++ ++ if (!dev->hw_learning_and_tx_capable && enable_learning) ++ enable_learning = 0; ++ ++ if (dev->hw_learning_and_tx_capable) { ++ ene_printk(KERN_WARNING, ++ "Device supports transmitting, but the driver doesn't\n"); ++ ene_printk(KERN_WARNING, ++ "due to lack of hardware to test against.\n"); ++ ene_printk(KERN_WARNING, ++ "Send a mail to: lirc-list@lists.sourceforge.net\n"); ++ } ++ return 0; ++} ++ ++/* hardware initialization */ ++static int ene_hw_init(void *data) ++{ ++ u8 reg_value; ++ struct ene_device *dev = (struct ene_device *)data; ++ dev->in_use = 1; ++ ++ if (dev->hw_revision < ENE_HW_C) { ++ ene_hw_write_reg(dev, ENEB_IRQ, dev->irq << 1); ++ ene_hw_write_reg(dev, ENEB_IRQ_UNK1, 0x01); ++ } else { ++ reg_value = ene_hw_read_reg(dev, ENEC_IRQ) & 0xF0; ++ reg_value |= ENEC_IRQ_UNK_EN; ++ reg_value &= ~ENEC_IRQ_STATUS; ++ reg_value |= (dev->irq & ENEC_IRQ_MASK); ++ ene_hw_write_reg(dev, ENEC_IRQ, reg_value); ++ ene_hw_write_reg(dev, ENE_TX_UNK1, 0x63); ++ } ++ ++ ene_hw_write_reg(dev, ENE_CIR_CONF2, 0x00); ++ ene_set_inputs(dev, enable_learning); ++ ++ /* set sampling period */ ++ ene_hw_write_reg(dev, ENE_CIR_SAMPLE_PERIOD, sample_period); ++ ++ /* ack any pending irqs - just in case */ ++ ene_hw_irq_status(dev, NULL); ++ ++ /* enter idle mode */ ++ ene_set_idle(dev, 1); ++ ++ /* enable firmware bits */ ++ ene_hw_write_reg_mask(dev, ENE_FW1, ++ ENE_FW1_ENABLE | ENE_FW1_IRQ, ++ ENE_FW1_ENABLE | ENE_FW1_IRQ); ++ /* clear stats */ ++ dev->sample = 0; ++ return 0; ++} ++ ++/* this enables gpio40 signal, used if connected to wide band input*/ ++static void ene_enable_gpio40(struct ene_device *dev, int enable) ++{ ++ ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, enable ? ++ 0 : ENE_CIR_CONF2_GPIO40DIS, ++ ENE_CIR_CONF2_GPIO40DIS); ++} ++ ++/* this enables the classic sampler */ ++static void ene_enable_normal_recieve(struct ene_device *dev, int enable) ++{ ++ ene_hw_write_reg(dev, ENE_CIR_CONF1, enable ? ENE_CIR_CONF1_ADC_ON : 0); ++} ++ ++/* this enables recieve via fan input */ ++static void ene_enable_fan_recieve(struct ene_device *dev, int enable) ++{ ++ if (!enable) ++ ene_hw_write_reg(dev, ENE_FAN_AS_IN1, 0); ++ else { ++ ene_hw_write_reg(dev, ENE_FAN_AS_IN1, ENE_FAN_AS_IN1_EN); ++ ene_hw_write_reg(dev, ENE_FAN_AS_IN2, ENE_FAN_AS_IN2_EN); ++ } ++ dev->fan_input_inuse = enable; ++} ++ ++/* determine which input to use*/ ++static void ene_set_inputs(struct ene_device *dev, int learning_enable) ++{ ++ ene_enable_normal_recieve(dev, 1); ++ ++ /* old hardware doesn't support learning mode for sure */ ++ if (dev->hw_revision <= ENE_HW_B) ++ return; ++ ++ /* reciever not learning capable, still set gpio40 correctly */ ++ if (!dev->hw_learning_and_tx_capable) { ++ ene_enable_gpio40(dev, !dev->hw_gpio40_learning); ++ return; ++ } ++ ++ /* enable learning mode */ ++ if (learning_enable) { ++ ene_enable_gpio40(dev, dev->hw_gpio40_learning); ++ ++ /* fan input is not used for learning */ ++ if (dev->hw_fan_as_normal_input) ++ ene_enable_fan_recieve(dev, 0); ++ ++ /* disable learning mode */ ++ } else { ++ if (dev->hw_fan_as_normal_input) { ++ ene_enable_fan_recieve(dev, 1); ++ ene_enable_normal_recieve(dev, 0); ++ } else ++ ene_enable_gpio40(dev, !dev->hw_gpio40_learning); ++ } ++ ++ /* set few additional settings for this mode */ ++ ene_hw_write_reg_mask(dev, ENE_CIR_CONF1, learning_enable ? ++ ENE_CIR_CONF1_LEARN1 : 0, ENE_CIR_CONF1_LEARN1); ++ ++ ene_hw_write_reg_mask(dev, ENE_CIR_CONF2, learning_enable ? ++ ENE_CIR_CONF2_LEARN2 : 0, ENE_CIR_CONF2_LEARN2); ++} ++ ++/* deinitialization */ ++static void ene_hw_deinit(void *data) ++{ ++ struct ene_device *dev = (struct ene_device *)data; ++ ++ /* disable samplers */ ++ ene_enable_normal_recieve(dev, 0); ++ ++ if (dev->hw_fan_as_normal_input) ++ ene_enable_fan_recieve(dev, 0); ++ ++ /* disable hardware IRQ and firmware flag */ ++ ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_ENABLE | ENE_FW1_IRQ); ++ ++ ene_set_idle(dev, 1); ++ dev->in_use = 0; ++} ++ ++/* sends current sample to userspace */ ++static void send_sample(struct ene_device *dev) ++{ ++ int value = abs(dev->sample) & PULSE_MASK; ++ ++ if (dev->sample > 0) ++ value |= PULSE_BIT; ++ ++ if (!lirc_buffer_full(dev->lirc_driver->rbuf)) { ++ lirc_buffer_write(dev->lirc_driver->rbuf, (void *)&value); ++ wake_up(&dev->lirc_driver->rbuf->wait_poll); ++ } ++ dev->sample = 0; ++} ++ ++/* this updates current sample */ ++static void update_sample(struct ene_device *dev, int sample) ++{ ++ if (!dev->sample) ++ dev->sample = sample; ++ else if (same_sign(dev->sample, sample)) ++ dev->sample += sample; ++ else { ++ send_sample(dev); ++ dev->sample = sample; ++ } ++} ++ ++/* enable or disable idle mode */ ++static void ene_set_idle(struct ene_device *dev, int idle) ++{ ++ struct timeval now; ++ int disable = idle && enable_idle && (dev->hw_revision < ENE_HW_C); ++ ++ ene_hw_write_reg_mask(dev, ENE_CIR_SAMPLE_PERIOD, ++ disable ? 0 : ENE_CIR_SAMPLE_OVERFLOW, ++ ENE_CIR_SAMPLE_OVERFLOW); ++ dev->idle = idle; ++ ++ /* remember when we have entered the idle mode */ ++ if (idle) { ++ do_gettimeofday(&dev->gap_start); ++ return; ++ } ++ ++ /* send the gap between keypresses now */ ++ do_gettimeofday(&now); ++ ++ if (now.tv_sec - dev->gap_start.tv_sec > 16) ++ dev->sample = space(PULSE_MASK); ++ else ++ dev->sample = dev->sample + ++ space(1000000ull * (now.tv_sec - dev->gap_start.tv_sec)) ++ + space(now.tv_usec - dev->gap_start.tv_usec); ++ ++ if (abs(dev->sample) > PULSE_MASK) ++ dev->sample = space(PULSE_MASK); ++ send_sample(dev); ++} ++ ++/* interrupt handler */ ++static irqreturn_t ene_hw_irq(int irq, void *data) ++{ ++ u16 hw_value; ++ int i, hw_sample; ++ int space; ++ int buffer_pointer; ++ int irq_status; ++ ++ struct ene_device *dev = (struct ene_device *)data; ++ irq_status = ene_hw_irq_status(dev, &buffer_pointer); ++ ++ if (!irq_status) ++ return IRQ_NONE; ++ ++ /* TODO: only RX for now */ ++ if (irq_status == ENE_IRQ_TX) ++ return IRQ_HANDLED; ++ ++ for (i = 0; i < ENE_SAMPLES_SIZE; i++) { ++ ++ hw_value = ene_hw_read_reg(dev, ++ ENE_SAMPLE_BUFFER + buffer_pointer + i); ++ ++ if (dev->fan_input_inuse) { ++ /* read high part of the sample */ ++ hw_value |= ene_hw_read_reg(dev, ++ ENE_SAMPLE_BUFFER_FAN + buffer_pointer + i) << 8; ++ ++ /* test for _space_ bit */ ++ space = !(hw_value & ENE_FAN_SMPL_PULS_MSK); ++ ++ /* clear space bit, and other unused bits */ ++ hw_value &= ENE_FAN_VALUE_MASK; ++ hw_sample = hw_value * ENE_SAMPLE_PERIOD_FAN; ++ ++ } else { ++ space = hw_value & ENE_SAMPLE_SPC_MASK; ++ hw_value &= ENE_SAMPLE_VALUE_MASK; ++ hw_sample = hw_value * sample_period; ++ } ++ ++ /* no more data */ ++ if (!(hw_value)) ++ break; ++ ++ if (space) ++ hw_sample *= -1; ++ ++ /* overflow sample recieved, handle it */ ++ ++ if (!dev->fan_input_inuse && hw_value == ENE_SAMPLE_OVERFLOW) { ++ ++ if (dev->idle) ++ continue; ++ ++ if (dev->sample > 0 || abs(dev->sample) <= ENE_MAXGAP) ++ update_sample(dev, hw_sample); ++ else ++ ene_set_idle(dev, 1); ++ ++ continue; ++ } ++ ++ /* normal first sample recieved */ ++ if (!dev->fan_input_inuse && dev->idle) { ++ ene_set_idle(dev, 0); ++ ++ /* discard first recieved value, its random ++ since its the time signal was off before ++ first pulse if idle mode is enabled, HW ++ does that for us */ ++ ++ if (!enable_idle) ++ continue; ++ } ++ update_sample(dev, hw_sample); ++ send_sample(dev); ++ } ++ return IRQ_HANDLED; ++} ++ ++static int ene_probe(struct pnp_dev *pnp_dev, ++ const struct pnp_device_id *dev_id) ++{ ++ struct ene_device *dev; ++ struct lirc_driver *lirc_driver; ++ int error = -ENOMEM; ++ ++ dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); ++ ++ if (!dev) ++ goto err1; ++ ++ dev->pnp_dev = pnp_dev; ++ pnp_set_drvdata(pnp_dev, dev); ++ ++ ++ /* prepare lirc interface */ ++ error = -ENOMEM; ++ lirc_driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ ++ if (!lirc_driver) ++ goto err2; ++ ++ dev->lirc_driver = lirc_driver; ++ ++ strcpy(lirc_driver->name, ENE_DRIVER_NAME); ++ lirc_driver->minor = -1; ++ lirc_driver->code_length = sizeof(int) * 8; ++ lirc_driver->features = LIRC_CAN_REC_MODE2; ++ lirc_driver->data = dev; ++ lirc_driver->set_use_inc = ene_hw_init; ++ lirc_driver->set_use_dec = ene_hw_deinit; ++ lirc_driver->dev = &pnp_dev->dev; ++ lirc_driver->owner = THIS_MODULE; ++ ++ lirc_driver->rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ ++ if (!lirc_driver->rbuf) ++ goto err3; ++ ++ if (lirc_buffer_init(lirc_driver->rbuf, sizeof(int), sizeof(int) * 256)) ++ goto err4; ++ ++ error = -ENODEV; ++ if (lirc_register_driver(lirc_driver)) ++ goto err5; ++ ++ /* validate resources */ ++ if (!pnp_port_valid(pnp_dev, 0) || ++ pnp_port_len(pnp_dev, 0) < ENE_MAX_IO) ++ goto err6; ++ ++ if (!pnp_irq_valid(pnp_dev, 0)) ++ goto err6; ++ ++ dev->hw_io = pnp_port_start(pnp_dev, 0); ++ dev->irq = pnp_irq(pnp_dev, 0); ++ ++ /* claim the resources */ ++ error = -EBUSY; ++ if (!request_region(dev->hw_io, ENE_MAX_IO, ENE_DRIVER_NAME)) ++ goto err6; ++ ++ if (request_irq(dev->irq, ene_hw_irq, ++ IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) ++ goto err7; ++ ++ /* detect hardware version and features */ ++ error = ene_hw_detect(dev); ++ if (error) ++ goto err8; ++ ++ ene_printk(KERN_NOTICE, "driver has been succesfully loaded\n"); ++ return 0; ++ ++err8: ++ free_irq(dev->irq, dev); ++err7: ++ release_region(dev->hw_io, ENE_MAX_IO); ++err6: ++ lirc_unregister_driver(lirc_driver->minor); ++err5: ++ lirc_buffer_free(lirc_driver->rbuf); ++err4: ++ kfree(lirc_driver->rbuf); ++err3: ++ kfree(lirc_driver); ++err2: ++ kfree(dev); ++err1: ++ return error; ++} ++ ++static void ene_remove(struct pnp_dev *pnp_dev) ++{ ++ struct ene_device *dev = pnp_get_drvdata(pnp_dev); ++ ene_hw_deinit(dev); ++ free_irq(dev->irq, dev); ++ release_region(dev->hw_io, ENE_MAX_IO); ++ lirc_unregister_driver(dev->lirc_driver->minor); ++ lirc_buffer_free(dev->lirc_driver->rbuf); ++ kfree(dev->lirc_driver); ++ kfree(dev); ++} ++ ++#ifdef CONFIG_PM ++ ++/* TODO: make 'wake on IR' configurable and add .shutdown */ ++/* currently impossible due to lack of kernel support */ ++ ++static int ene_suspend(struct pnp_dev *pnp_dev, pm_message_t state) ++{ ++ struct ene_device *dev = pnp_get_drvdata(pnp_dev); ++ ene_hw_write_reg_mask(dev, ENE_FW1, ENE_FW1_WAKE, ENE_FW1_WAKE); ++ return 0; ++} ++ ++static int ene_resume(struct pnp_dev *pnp_dev) ++{ ++ struct ene_device *dev = pnp_get_drvdata(pnp_dev); ++ if (dev->in_use) ++ ene_hw_init(dev); ++ ++ ene_hw_write_reg_mask(dev, ENE_FW1, 0, ENE_FW1_WAKE); ++ return 0; ++} ++ ++#endif ++ ++static const struct pnp_device_id ene_ids[] = { ++ {.id = "ENE0100",}, ++ {}, ++}; ++ ++static struct pnp_driver ene_driver = { ++ .name = ENE_DRIVER_NAME, ++ .id_table = ene_ids, ++ .flags = PNP_DRIVER_RES_DO_NOT_CHANGE, ++ ++ .probe = ene_probe, ++ .remove = __devexit_p(ene_remove), ++ ++#ifdef CONFIG_PM ++ .suspend = ene_suspend, ++ .resume = ene_resume, ++#endif ++}; ++ ++static int __init ene_init(void) ++{ ++ if (sample_period < 5) { ++ ene_printk(KERN_ERR, "sample period must be at\n"); ++ ene_printk(KERN_ERR, "least 5 us, (at least 30 recommended)\n"); ++ return -EINVAL; ++ } ++ return pnp_register_driver(&ene_driver); ++} ++ ++static void ene_exit(void) ++{ ++ pnp_unregister_driver(&ene_driver); ++} ++ ++module_param(sample_period, int, S_IRUGO); ++MODULE_PARM_DESC(sample_period, "Hardware sample period (75 us default)"); ++ ++module_param(enable_idle, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(enable_idle, ++ "Enables turning off signal sampling after long inactivity time; " ++ "if disabled might help detecting input signal (default: enabled)"); ++ ++module_param(enable_learning, bool, S_IRUGO); ++MODULE_PARM_DESC(enable_learning, "Use wide band (learning) reciever"); ++ ++MODULE_DEVICE_TABLE(pnp, ene_ids); ++MODULE_DESCRIPTION ++ ("LIRC driver for KB3926B/KB3926C/KB3926D (aka ENE0100) CIR port"); ++MODULE_AUTHOR("Maxim Levitsky"); ++MODULE_LICENSE("GPL"); ++ ++module_init(ene_init); ++module_exit(ene_exit); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_ene0100.h linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ene0100.h +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_ene0100.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ene0100.h 2010-08-02 09:28:03.933051519 +0200 +@@ -0,0 +1,169 @@ ++/* ++ * driver for ENE KB3926 B/C/D CIR (also known as ENE0100) ++ * ++ * Copyright (C) 2009 Maxim Levitsky ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ * USA ++ */ ++ ++#include ++#include "lirc_dev.h" ++ ++/* hardware address */ ++#define ENE_STATUS 0 /* hardware status - unused */ ++#define ENE_ADDR_HI 1 /* hi byte of register address */ ++#define ENE_ADDR_LO 2 /* low byte of register address */ ++#define ENE_IO 3 /* read/write window */ ++#define ENE_MAX_IO 4 ++ ++/* 8 bytes of samples, divided in 2 halfs*/ ++#define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */ ++#define ENE_SAMPLE_SPC_MASK (1 << 7) /* sample is space */ ++#define ENE_SAMPLE_VALUE_MASK 0x7F ++#define ENE_SAMPLE_OVERFLOW 0x7F ++#define ENE_SAMPLES_SIZE 4 ++ ++/* fan input sample buffer */ ++#define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */ ++ /* each sample of normal buffer */ ++ ++#define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */ ++ /* if set, says that sample is pulse */ ++#define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */ ++ ++/* first firmware register */ ++#define ENE_FW1 0xF8F8 ++#define ENE_FW1_ENABLE (1 << 0) /* enable fw processing */ ++#define ENE_FW1_TXIRQ (1 << 1) /* TX interrupt pending */ ++#define ENE_FW1_WAKE (1 << 6) /* enable wake from S3 */ ++#define ENE_FW1_IRQ (1 << 7) /* enable interrupt */ ++ ++/* second firmware register */ ++#define ENE_FW2 0xF8F9 ++#define ENE_FW2_BUF_HIGH (1 << 0) /* which half of the buffer to read */ ++#define ENE_FW2_IRQ_CLR (1 << 2) /* clear this on IRQ */ ++#define ENE_FW2_GP40_AS_LEARN (1 << 4) /* normal input is used as */ ++ /* learning input */ ++#define ENE_FW2_FAN_AS_NRML_IN (1 << 6) /* fan is used as normal input */ ++#define ENE_FW2_LEARNING (1 << 7) /* hardware supports learning and TX */ ++ ++/* fan as input settings - only if learning capable */ ++#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */ ++#define ENE_FAN_AS_IN1_EN 0xCD ++#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */ ++#define ENE_FAN_AS_IN2_EN 0x03 ++#define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */ ++ ++/* IRQ registers block (for revision B) */ ++#define ENEB_IRQ 0xFD09 /* IRQ number */ ++#define ENEB_IRQ_UNK1 0xFD17 /* unknown setting = 1 */ ++#define ENEB_IRQ_STATUS 0xFD80 /* irq status */ ++#define ENEB_IRQ_STATUS_IR (1 << 5) /* IR irq */ ++ ++/* IRQ registers block (for revision C,D) */ ++#define ENEC_IRQ 0xFE9B /* new irq settings register */ ++#define ENEC_IRQ_MASK 0x0F /* irq number mask */ ++#define ENEC_IRQ_UNK_EN (1 << 4) /* always enabled */ ++#define ENEC_IRQ_STATUS (1 << 5) /* irq status and ACK */ ++ ++/* CIR block settings */ ++#define ENE_CIR_CONF1 0xFEC0 ++#define ENE_CIR_CONF1_ADC_ON 0x7 /* reciever on gpio40 enabled */ ++#define ENE_CIR_CONF1_LEARN1 (1 << 3) /* enabled on learning mode */ ++#define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */ ++#define ENE_CIR_CONF1_TX_CARR (1 << 7) /* send TX carrier or not */ ++ ++#define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */ ++#define ENE_CIR_CONF2_LEARN2 (1 << 4) /* set on enable learning */ ++#define ENE_CIR_CONF2_GPIO40DIS (1 << 5) /* disable normal input via gpio40 */ ++ ++#define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */ ++#define ENE_CIR_SAMPLE_OVERFLOW (1 << 7) /* interrupt on overflows if set */ ++ ++ ++/* transmitter - not implemented yet */ ++/* KB3926C and higher */ ++/* transmission is very similiar to recieving, a byte is written to */ ++/* ENE_TX_INPUT, in same manner as it is read from sample buffer */ ++/* sample period is fixed*/ ++ ++ ++/* transmitter ports */ ++#define ENE_TX_PORT1 0xFC01 /* this enables one or both */ ++#define ENE_TX_PORT1_EN (1 << 5) /* TX ports */ ++#define ENE_TX_PORT2 0xFC08 ++#define ENE_TX_PORT2_EN (1 << 1) ++ ++#define ENE_TX_INPUT 0xFEC9 /* next byte to transmit */ ++#define ENE_TX_SPC_MASK (1 << 7) /* Transmitted sample is space */ ++#define ENE_TX_UNK1 0xFECB /* set to 0x63 */ ++#define ENE_TX_SMPL_PERIOD 50 /* transmit sample period */ ++ ++ ++#define ENE_TX_CARRIER 0xFECE /* TX carrier * 2 (khz) */ ++#define ENE_TX_CARRIER_UNKBIT 0x80 /* This bit set on transmit */ ++#define ENE_TX_CARRIER_LOW 0xFECF /* TX carrier / 2 */ ++ ++/* Hardware versions */ ++#define ENE_HW_VERSION 0xFF00 /* hardware revision */ ++#define ENE_HW_UNK 0xFF1D ++#define ENE_HW_UNK_CLR (1 << 2) ++#define ENE_HW_VER_MAJOR 0xFF1E /* chip version */ ++#define ENE_HW_VER_MINOR 0xFF1F ++#define ENE_HW_VER_OLD 0xFD00 ++ ++#define same_sign(a, b) ((((a) > 0) && (b) > 0) || ((a) < 0 && (b) < 0)) ++ ++#define ENE_DRIVER_NAME "enecir" ++#define ENE_MAXGAP 250000 /* this is amount of time we wait ++ before turning the sampler, chosen ++ arbitry */ ++ ++#define space(len) (-(len)) /* add a space */ ++ ++/* software defines */ ++#define ENE_IRQ_RX 1 ++#define ENE_IRQ_TX 2 ++ ++#define ENE_HW_B 1 /* 3926B */ ++#define ENE_HW_C 2 /* 3926C */ ++#define ENE_HW_D 3 /* 3926D */ ++ ++#define ene_printk(level, text, ...) \ ++ printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__) ++ ++struct ene_device { ++ struct pnp_dev *pnp_dev; ++ struct lirc_driver *lirc_driver; ++ ++ /* hw settings */ ++ unsigned long hw_io; ++ int irq; ++ ++ int hw_revision; /* hardware revision */ ++ int hw_learning_and_tx_capable; /* learning capable */ ++ int hw_gpio40_learning; /* gpio40 is learning */ ++ int hw_fan_as_normal_input; /* fan input is used as regular input */ ++ ++ /* device data */ ++ int idle; ++ int fan_input_inuse; ++ ++ int sample; ++ int in_use; ++ ++ struct timeval gap_start; ++}; +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_i2c.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_i2c.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_i2c.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_i2c.c 2010-08-02 09:28:03.935051970 +0200 +@@ -0,0 +1,536 @@ ++/* ++ * lirc_i2c.c ++ * ++ * i2c IR driver for the onboard IR port on many TV tuner cards, including: ++ * -Flavors of the Hauppauge PVR-150/250/350 ++ * -Hauppauge HVR-1300 ++ * -PixelView (BT878P+W/FM) ++ * -KNC ONE TV Station/Anubis Typhoon TView Tuner ++ * -Asus TV-Box and Creative/VisionTek BreakOut-Box ++ * -Leadtek Winfast PVR2000 ++ * ++ * Copyright (c) 2000 Gerd Knorr ++ * modified for PixelView (BT878P+W/FM) by ++ * Michal Kochanowicz ++ * Christoph Bartelmus ++ * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by ++ * Ulrich Mueller ++ * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by ++ * Stefan Jahn ++ * modified for inclusion into kernel sources by ++ * Jerome Brock ++ * modified for Leadtek Winfast PVR2000 by ++ * Thomas Reitmayr (treitmayr@yahoo.com) ++ * modified for Hauppauge HVR-1300 by ++ * Jan Frey (jfrey@gmx.de) ++ * ++ * parts are cut&pasted from the old lirc_haup.c driver ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "lirc_dev.h" ++ ++struct IR { ++ struct lirc_driver l; ++ struct i2c_client c; ++ int nextkey; ++ unsigned char b[3]; ++ unsigned char bits; ++ unsigned char flag; ++}; ++ ++#define DEVICE_NAME "lirc_i2c" ++ ++/* module parameters */ ++static int debug; /* debug output */ ++static int minor = -1; /* minor number */ ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG DEVICE_NAME ": " fmt, \ ++ ## args); \ ++ } while (0) ++ ++static int reverse(int data, int bits) ++{ ++ int i; ++ int c; ++ ++ for (c = 0, i = 0; i < bits; i++) ++ c |= ((data & (1<c, keybuf, 1); ++ /* poll IR chip */ ++ if (i2c_master_recv(&ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { ++ dprintk("read error\n"); ++ return -EIO; ++ } ++ ++ dprintk("key (0x%02x%02x%02x%02x)\n", ++ keybuf[0], keybuf[1], keybuf[2], keybuf[3]); ++ ++ /* key pressed ? */ ++ if (keybuf[2] == 0xff) ++ return -ENODATA; ++ ++ /* remove repeat bit */ ++ keybuf[2] &= 0x7f; ++ keybuf[3] |= 0x80; ++ ++ lirc_buffer_write(buf, keybuf); ++ return 0; ++} ++ ++static int add_to_buf_pcf8574(void *data, struct lirc_buffer *buf) ++{ ++ struct IR *ir = data; ++ int rc; ++ unsigned char all, mask; ++ unsigned char key; ++ ++ /* compute all valid bits (key code + pressed/release flag) */ ++ all = ir->bits | ir->flag; ++ ++ /* save IR writable mask bits */ ++ mask = i2c_smbus_read_byte(&ir->c) & ~all; ++ ++ /* send bit mask */ ++ rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask); ++ ++ /* receive scan code */ ++ rc = i2c_smbus_read_byte(&ir->c); ++ ++ if (rc == -1) { ++ dprintk("%s read error\n", ir->c.name); ++ return -EIO; ++ } ++ ++ /* drop duplicate polls */ ++ if (ir->b[0] == (rc & all)) ++ return -ENODATA; ++ ++ ir->b[0] = rc & all; ++ ++ dprintk("%s key 0x%02X %s\n", ir->c.name, rc & ir->bits, ++ (rc & ir->flag) ? "released" : "pressed"); ++ ++ /* ignore released buttons */ ++ if (rc & ir->flag) ++ return -ENODATA; ++ ++ /* set valid key code */ ++ key = rc & ir->bits; ++ lirc_buffer_write(buf, &key); ++ return 0; ++} ++ ++/* common for Hauppauge IR receivers */ ++static int add_to_buf_haup_common(void *data, struct lirc_buffer *buf, ++ unsigned char *keybuf, int size, int offset) ++{ ++ struct IR *ir = data; ++ __u16 code; ++ unsigned char codes[2]; ++ int ret; ++ ++ /* poll IR chip */ ++ ret = i2c_master_recv(&ir->c, keybuf, size); ++ if (ret == size) { ++ ir->b[0] = keybuf[offset]; ++ ir->b[1] = keybuf[offset+1]; ++ ir->b[2] = keybuf[offset+2]; ++ if (ir->b[0] != 0x00 && ir->b[1] != 0x00) ++ dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); ++ } else { ++ dprintk("read error (ret=%d)\n", ret); ++ /* keep last successful read buffer */ ++ } ++ ++ /* key pressed ? */ ++ if ((ir->b[0] & 0x80) == 0) ++ return -ENODATA; ++ ++ /* look what we have */ ++ code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2); ++ ++ codes[0] = (code >> 8) & 0xff; ++ codes[1] = code & 0xff; ++ ++ /* return it */ ++ dprintk("sending code 0x%02x%02x to lirc\n", codes[0], codes[1]); ++ lirc_buffer_write(buf, codes); ++ return 0; ++} ++ ++/* specific for the Hauppauge PVR150 IR receiver */ ++static int add_to_buf_haup_pvr150(void *data, struct lirc_buffer *buf) ++{ ++ unsigned char keybuf[6]; ++ /* fetch 6 bytes, first relevant is at offset 3 */ ++ return add_to_buf_haup_common(data, buf, keybuf, 6, 3); ++} ++ ++/* used for all Hauppauge IR receivers but the PVR150 */ ++static int add_to_buf_haup(void *data, struct lirc_buffer *buf) ++{ ++ unsigned char keybuf[3]; ++ /* fetch 3 bytes, first relevant is at offset 0 */ ++ return add_to_buf_haup_common(data, buf, keybuf, 3, 0); ++} ++ ++ ++static int add_to_buf_pvr2000(void *data, struct lirc_buffer *buf) ++{ ++ struct IR *ir = data; ++ unsigned char key; ++ s32 flags; ++ s32 code; ++ ++ /* poll IR chip */ ++ flags = i2c_smbus_read_byte_data(&ir->c, 0x10); ++ if (-1 == flags) { ++ dprintk("read error\n"); ++ return -ENODATA; ++ } ++ /* key pressed ? */ ++ if (0 == (flags & 0x80)) ++ return -ENODATA; ++ ++ /* read actual key code */ ++ code = i2c_smbus_read_byte_data(&ir->c, 0x00); ++ if (-1 == code) { ++ dprintk("read error\n"); ++ return -ENODATA; ++ } ++ ++ key = code & 0xFF; ++ ++ dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", key, flags & 0xFF); ++ ++ /* return it */ ++ lirc_buffer_write(buf, &key); ++ return 0; ++} ++ ++static int add_to_buf_pixelview(void *data, struct lirc_buffer *buf) ++{ ++ struct IR *ir = data; ++ unsigned char key; ++ ++ /* poll IR chip */ ++ if (1 != i2c_master_recv(&ir->c, &key, 1)) { ++ dprintk("read error\n"); ++ return -1; ++ } ++ dprintk("key %02x\n", key); ++ ++ /* return it */ ++ lirc_buffer_write(buf, &key); ++ return 0; ++} ++ ++static int add_to_buf_pv951(void *data, struct lirc_buffer *buf) ++{ ++ struct IR *ir = data; ++ unsigned char key; ++ unsigned char codes[4]; ++ ++ /* poll IR chip */ ++ if (1 != i2c_master_recv(&ir->c, &key, 1)) { ++ dprintk("read error\n"); ++ return -ENODATA; ++ } ++ /* ignore 0xaa */ ++ if (key == 0xaa) ++ return -ENODATA; ++ dprintk("key %02x\n", key); ++ ++ codes[0] = 0x61; ++ codes[1] = 0xD6; ++ codes[2] = reverse(key, 8); ++ codes[3] = (~codes[2])&0xff; ++ ++ lirc_buffer_write(buf, codes); ++ return 0; ++} ++ ++static int add_to_buf_knc1(void *data, struct lirc_buffer *buf) ++{ ++ static unsigned char last_key = 0xFF; ++ struct IR *ir = data; ++ unsigned char key; ++ ++ /* poll IR chip */ ++ if (1 != i2c_master_recv(&ir->c, &key, 1)) { ++ dprintk("read error\n"); ++ return -ENODATA; ++ } ++ ++ /* ++ * it seems that 0xFE indicates that a button is still held ++ * down, while 0xFF indicates that no button is held ++ * down. 0xFE sequences are sometimes interrupted by 0xFF ++ */ ++ ++ dprintk("key %02x\n", key); ++ ++ if (key == 0xFF) ++ return -ENODATA; ++ ++ if (key == 0xFE) ++ key = last_key; ++ ++ last_key = key; ++ lirc_buffer_write(buf, &key); ++ ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ struct IR *ir = data; ++ ++ dprintk("%s called\n", __func__); ++ ++ /* lock bttv in memory while /dev/lirc is in use */ ++ i2c_use_client(&ir->c); ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct IR *ir = data; ++ ++ dprintk("%s called\n", __func__); ++ ++ i2c_release_client(&ir->c); ++} ++ ++static struct lirc_driver lirc_template = { ++ .name = "lirc_i2c", ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .dev = NULL, ++ .owner = THIS_MODULE, ++}; ++ ++static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); ++static int ir_remove(struct i2c_client *client); ++static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); ++ ++static const struct i2c_device_id ir_receiver_id[] = { ++ /* Generic entry for any IR receiver */ ++ { "ir_video", 0 }, ++ /* IR device specific entries could be added here */ ++ { } ++}; ++ ++static struct i2c_driver driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "i2c ir driver", ++ }, ++ .probe = ir_probe, ++ .remove = ir_remove, ++ .id_table = ir_receiver_id, ++ .command = ir_command, ++}; ++ ++static void pcf_probe(struct i2c_client *client, struct IR *ir) ++{ ++ int ret1, ret2, ret3, ret4; ++ ++ ret1 = i2c_smbus_write_byte(client, 0xff); ++ ret2 = i2c_smbus_read_byte(client); ++ ret3 = i2c_smbus_write_byte(client, 0x00); ++ ret4 = i2c_smbus_read_byte(client); ++ ++ /* in the Asus TV-Box: bit 1-0 */ ++ if (((ret2 & 0x03) == 0x03) && ((ret4 & 0x03) == 0x00)) { ++ ir->bits = (unsigned char) ~0x07; ++ ir->flag = 0x04; ++ /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */ ++ } else if (((ret2 & 0xc0) == 0xc0) && ((ret4 & 0xc0) == 0x00)) { ++ ir->bits = (unsigned char) ~0xe0; ++ ir->flag = 0x20; ++ } ++ ++ return; ++} ++ ++static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ struct IR *ir; ++ struct i2c_adapter *adap = client->adapter; ++ unsigned short addr = client->addr; ++ int retval; ++ ++ ir = kzalloc(sizeof(struct IR), GFP_KERNEL); ++ if (!ir) ++ return -ENOMEM; ++ memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); ++ memcpy(&ir->c, client, sizeof(struct i2c_client)); ++ ++ i2c_set_clientdata(client, ir); ++ ir->l.data = ir; ++ ir->l.minor = minor; ++ ir->l.sample_rate = 10; ++ ir->l.dev = &ir->c.dev; ++ ir->nextkey = -1; ++ ++ switch (addr) { ++ case 0x64: ++ strlcpy(ir->c.name, "Pixelview IR", I2C_NAME_SIZE); ++ ir->l.code_length = 8; ++ ir->l.add_to_buf = add_to_buf_pixelview; ++ break; ++ case 0x4b: ++ strlcpy(ir->c.name, "PV951 IR", I2C_NAME_SIZE); ++ ir->l.code_length = 32; ++ ir->l.add_to_buf = add_to_buf_pv951; ++ break; ++ case 0x71: ++ if (adap->id == I2C_HW_B_CX2388x) ++ strlcpy(ir->c.name, "Hauppauge HVR1300", I2C_NAME_SIZE); ++ else /* bt8xx or cx2341x */ ++ /* ++ * The PVR150 IR receiver uses the same protocol as ++ * other Hauppauge cards, but the data flow is ++ * different, so we need to deal with it by its own. ++ */ ++ strlcpy(ir->c.name, "Hauppauge PVR150", I2C_NAME_SIZE); ++ ir->l.code_length = 13; ++ ir->l.add_to_buf = add_to_buf_haup_pvr150; ++ break; ++ case 0x6b: ++ strlcpy(ir->c.name, "Adaptec IR", I2C_NAME_SIZE); ++ ir->l.code_length = 32; ++ ir->l.add_to_buf = add_to_buf_adap; ++ break; ++ case 0x18: ++ case 0x1a: ++ if (adap->id == I2C_HW_B_CX2388x) { ++ strlcpy(ir->c.name, "Leadtek IR", I2C_NAME_SIZE); ++ ir->l.code_length = 8; ++ ir->l.add_to_buf = add_to_buf_pvr2000; ++ } else { /* bt8xx or cx2341x */ ++ strlcpy(ir->c.name, "Hauppauge IR", I2C_NAME_SIZE); ++ ir->l.code_length = 13; ++ ir->l.add_to_buf = add_to_buf_haup; ++ } ++ break; ++ case 0x30: ++ strlcpy(ir->c.name, "KNC ONE IR", I2C_NAME_SIZE); ++ ir->l.code_length = 8; ++ ir->l.add_to_buf = add_to_buf_knc1; ++ break; ++ case 0x21: ++ case 0x23: ++ pcf_probe(client, ir); ++ strlcpy(ir->c.name, "TV-Box IR", I2C_NAME_SIZE); ++ ir->l.code_length = 8; ++ ir->l.add_to_buf = add_to_buf_pcf8574; ++ break; ++ default: ++ /* shouldn't happen */ ++ printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n", addr); ++ kfree(ir); ++ return -EINVAL; ++ } ++ printk(KERN_INFO "lirc_i2c: chip 0x%x found @ 0x%02x (%s)\n", ++ adap->id, addr, ir->c.name); ++ ++ retval = lirc_register_driver(&ir->l); ++ ++ if (retval < 0) { ++ printk(KERN_ERR "lirc_i2c: failed to register driver!\n"); ++ kfree(ir); ++ return retval; ++ } ++ ++ ir->l.minor = retval; ++ ++ return 0; ++} ++ ++static int ir_remove(struct i2c_client *client) ++{ ++ struct IR *ir = i2c_get_clientdata(client); ++ ++ /* unregister device */ ++ lirc_unregister_driver(ir->l.minor); ++ ++ /* free memory */ ++ kfree(ir); ++ return 0; ++} ++ ++static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg) ++{ ++ /* nothing */ ++ return 0; ++} ++ ++static int __init lirc_i2c_init(void) ++{ ++ i2c_add_driver(&driver); ++ return 0; ++} ++ ++static void __exit lirc_i2c_exit(void) ++{ ++ i2c_del_driver(&driver); ++} ++ ++MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and " ++ "Pixelview cards (i2c stack)"); ++MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, " ++ "Ulrich Mueller, Stefan Jahn, Jerome Brock"); ++MODULE_LICENSE("GPL"); ++ ++module_param(minor, int, S_IRUGO); ++MODULE_PARM_DESC(minor, "Preferred minor device number"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); ++ ++module_init(lirc_i2c_init); ++module_exit(lirc_i2c_exit); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_igorplugusb.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_igorplugusb.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_igorplugusb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_igorplugusb.c 2010-08-02 09:30:58.093051447 +0200 +@@ -0,0 +1,555 @@ ++/* ++ * lirc_igorplugusb - USB remote support for LIRC ++ * ++ * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. ++ * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm ++ * ++ * The device can only record bursts of up to 36 pulses/spaces. ++ * Works fine with RC5. Longer commands lead to device buffer overrun. ++ * (Maybe a better firmware or a microcontroller with more ram can help?) ++ * ++ * Version 0.1 [beta status] ++ * ++ * Copyright (C) 2004 Jan M. Hochstein ++ * ++ * ++ * This driver was derived from: ++ * Paul Miller ++ * "lirc_atiusb" module ++ * Vladimir Dergachev 's 2002 ++ * "USB ATI Remote support" (input device) ++ * Adrian Dewhurst 's 2002 ++ * "USB StreamZap remote driver" (LIRC) ++ * Artur Lipowski 's 2002 ++ * "lirc_dev" and "lirc_gpio" LIRC modules ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++ ++/* module identification */ ++#define DRIVER_VERSION "0.1" ++#define DRIVER_AUTHOR \ ++ "Jan M. Hochstein " ++#define DRIVER_DESC "USB remote driver for LIRC" ++#define DRIVER_NAME "lirc_igorplugusb" ++ ++/* debugging support */ ++#ifdef CONFIG_USB_DEBUG ++static int debug = 1; ++#else ++static int debug; ++#endif ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG fmt, ## args); \ ++ } while (0) ++ ++/* One mode2 pulse/space has 4 bytes. */ ++#define CODE_LENGTH sizeof(int) ++ ++/* Igor's firmware cannot record bursts longer than 36. */ ++#define DEVICE_BUFLEN 36 ++ ++/* ++ * Header at the beginning of the device's buffer: ++ * unsigned char data_length ++ * unsigned char data_start (!=0 means ring-buffer overrun) ++ * unsigned char counter (incremented by each burst) ++ */ ++#define DEVICE_HEADERLEN 3 ++ ++/* This is for the gap */ ++#define ADDITIONAL_LIRC_BYTES 2 ++ ++/* times to poll per second */ ++#define SAMPLE_RATE 100 ++static int sample_rate = SAMPLE_RATE; ++ ++ ++/**** Igor's USB Request Codes */ ++ ++#define SET_INFRABUFFER_EMPTY 1 ++/** ++ * Params: none ++ * Answer: empty ++ */ ++ ++#define GET_INFRACODE 2 ++/** ++ * Params: ++ * wValue: offset to begin reading infra buffer ++ * ++ * Answer: infra data ++ */ ++ ++#define SET_DATAPORT_DIRECTION 3 ++/** ++ * Params: ++ * wValue: (byte) 1 bit for each data port pin (0=in, 1=out) ++ * ++ * Answer: empty ++ */ ++ ++#define GET_DATAPORT_DIRECTION 4 ++/** ++ * Params: none ++ * ++ * Answer: (byte) 1 bit for each data port pin (0=in, 1=out) ++ */ ++ ++#define SET_OUT_DATAPORT 5 ++/** ++ * Params: ++ * wValue: byte to write to output data port ++ * ++ * Answer: empty ++ */ ++ ++#define GET_OUT_DATAPORT 6 ++/** ++ * Params: none ++ * ++ * Answer: least significant 3 bits read from output data port ++ */ ++ ++#define GET_IN_DATAPORT 7 ++/** ++ * Params: none ++ * ++ * Answer: least significant 3 bits read from input data port ++ */ ++ ++#define READ_EEPROM 8 ++/** ++ * Params: ++ * wValue: offset to begin reading EEPROM ++ * ++ * Answer: EEPROM bytes ++ */ ++ ++#define WRITE_EEPROM 9 ++/** ++ * Params: ++ * wValue: offset to EEPROM byte ++ * wIndex: byte to write ++ * ++ * Answer: empty ++ */ ++ ++#define SEND_RS232 10 ++/** ++ * Params: ++ * wValue: byte to send ++ * ++ * Answer: empty ++ */ ++ ++#define RECV_RS232 11 ++/** ++ * Params: none ++ * ++ * Answer: byte received ++ */ ++ ++#define SET_RS232_BAUD 12 ++/** ++ * Params: ++ * wValue: byte to write to UART bit rate register (UBRR) ++ * ++ * Answer: empty ++ */ ++ ++#define GET_RS232_BAUD 13 ++/** ++ * Params: none ++ * ++ * Answer: byte read from UART bit rate register (UBRR) ++ */ ++ ++ ++/* data structure for each usb remote */ ++struct igorplug { ++ ++ /* usb */ ++ struct usb_device *usbdev; ++ struct urb *urb_in; ++ int devnum; ++ ++ unsigned char *buf_in; ++ unsigned int len_in; ++ int in_space; ++ struct timeval last_time; ++ ++ dma_addr_t dma_in; ++ ++ /* lirc */ ++ struct lirc_driver *d; ++ ++ /* handle sending (init strings) */ ++ int send_flags; ++ wait_queue_head_t wait_out; ++}; ++ ++static int unregister_from_lirc(struct igorplug *ir) ++{ ++ struct lirc_driver *d = ir->d; ++ int devnum; ++ ++ if (!ir->d) ++ return -EINVAL; ++ ++ devnum = ir->devnum; ++ dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); ++ ++ lirc_unregister_driver(d->minor); ++ ++ printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); ++ ++ kfree(d); ++ ir->d = NULL; ++ kfree(ir); ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ struct igorplug *ir = data; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); ++ return -EIO; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); ++ ++ if (!ir->usbdev) ++ return -ENODEV; ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct igorplug *ir = data; ++ ++ if (!ir) { ++ printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); ++ return; ++ } ++ dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); ++} ++ ++ ++/** ++ * Called in user context. ++ * return 0 if data was added to the buffer and ++ * -ENODATA if none was available. This should add some number of bits ++ * evenly divisible by code_length to the buffer ++ */ ++static int usb_remote_poll(void *data, struct lirc_buffer *buf) ++{ ++ int ret; ++ struct igorplug *ir = (struct igorplug *)data; ++ ++ if (!ir->usbdev) /* Has the device been removed? */ ++ return -ENODEV; ++ ++ memset(ir->buf_in, 0, ir->len_in); ++ ++ ret = usb_control_msg( ++ ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), ++ GET_INFRACODE, USB_TYPE_VENDOR|USB_DIR_IN, ++ 0/* offset */, /*unused*/0, ++ ir->buf_in, ir->len_in, ++ /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); ++ if (ret > 0) { ++ int i = DEVICE_HEADERLEN; ++ int code, timediff; ++ struct timeval now; ++ ++ if (ret <= 1) /* ACK packet has 1 byte --> ignore */ ++ return -ENODATA; ++ ++ dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", ++ ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); ++ ++ if (ir->buf_in[2] != 0) { ++ printk(DRIVER_NAME "[%d]: Device buffer overrun.\n", ++ ir->devnum); ++ /* start at earliest byte */ ++ i = DEVICE_HEADERLEN + ir->buf_in[2]; ++ /* where are we now? space, gap or pulse? */ ++ } ++ ++ do_gettimeofday(&now); ++ timediff = now.tv_sec - ir->last_time.tv_sec; ++ if (timediff + 1 > PULSE_MASK / 1000000) ++ timediff = PULSE_MASK; ++ else { ++ timediff *= 1000000; ++ timediff += now.tv_usec - ir->last_time.tv_usec; ++ } ++ ir->last_time.tv_sec = now.tv_sec; ++ ir->last_time.tv_usec = now.tv_usec; ++ ++ /* create leading gap */ ++ code = timediff; ++ lirc_buffer_write(buf, (unsigned char *)&code); ++ ir->in_space = 1; /* next comes a pulse */ ++ ++ /* MODE2: pulse/space (PULSE_BIT) in 1us units */ ++ ++ while (i < ret) { ++ /* 1 Igor-tick = 85.333333 us */ ++ code = (unsigned int)ir->buf_in[i] * 85 ++ + (unsigned int)ir->buf_in[i] / 3; ++ if (ir->in_space) ++ code |= PULSE_BIT; ++ lirc_buffer_write(buf, (unsigned char *)&code); ++ /* 1 chunk = CODE_LENGTH bytes */ ++ ir->in_space ^= 1; ++ ++i; ++ } ++ ++ ret = usb_control_msg( ++ ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), ++ SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, ++ /*unused*/0, /*unused*/0, ++ /*dummy*/ir->buf_in, /*dummy*/ir->len_in, ++ /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); ++ if (ret < 0) ++ printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " ++ "error %d\n", ir->devnum, ret); ++ return 0; ++ } else if (ret < 0) ++ printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", ++ ir->devnum, ret); ++ ++ return -ENODATA; ++} ++ ++ ++ ++static int usb_remote_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = NULL; ++ struct usb_host_interface *idesc = NULL; ++ struct usb_host_endpoint *ep_ctl2; ++ struct igorplug *ir = NULL; ++ struct lirc_driver *driver = NULL; ++ int devnum, pipe, maxp; ++ int minor = 0; ++ char buf[63], name[128] = ""; ++ int mem_failure = 0; ++ int ret; ++ ++ dprintk(DRIVER_NAME ": usb probe called.\n"); ++ ++ dev = interface_to_usbdev(intf); ++ ++ idesc = intf->cur_altsetting; ++ ++ if (idesc->desc.bNumEndpoints != 1) ++ return -ENODEV; ++ ep_ctl2 = idesc->endpoint; ++ if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ != USB_DIR_IN) ++ || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ != USB_ENDPOINT_XFER_CONTROL) ++ return -ENODEV; ++ pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); ++ devnum = dev->devnum; ++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ ++ dprintk(DRIVER_NAME "[%d]: bytes_in_key=%lu maxp=%d\n", ++ devnum, CODE_LENGTH, maxp); ++ ++ ++ mem_failure = 0; ++ ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); ++ if (!ir) { ++ mem_failure = 1; ++ goto mem_failure_switch; ++ } ++ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ if (!driver) { ++ mem_failure = 2; ++ goto mem_failure_switch; ++ } ++ ++ ir->buf_in = usb_alloc_coherent(dev, ++ DEVICE_BUFLEN+DEVICE_HEADERLEN, ++ GFP_ATOMIC, &ir->dma_in); ++ if (!ir->buf_in) { ++ mem_failure = 3; ++ goto mem_failure_switch; ++ } ++ ++ strcpy(driver->name, DRIVER_NAME " "); ++ driver->minor = -1; ++ driver->code_length = CODE_LENGTH * 8; /* in bits */ ++ driver->features = LIRC_CAN_REC_MODE2; ++ driver->data = ir; ++ driver->chunk_size = CODE_LENGTH; ++ driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES; ++ driver->set_use_inc = &set_use_inc; ++ driver->set_use_dec = &set_use_dec; ++ driver->sample_rate = sample_rate; /* per second */ ++ driver->add_to_buf = &usb_remote_poll; ++ driver->dev = &intf->dev; ++ driver->owner = THIS_MODULE; ++ ++ init_waitqueue_head(&ir->wait_out); ++ ++ minor = lirc_register_driver(driver); ++ if (minor < 0) ++ mem_failure = 9; ++ ++mem_failure_switch: ++ ++ switch (mem_failure) { ++ case 9: ++ usb_alloc_coherent(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, ++ ir->buf_in, ir->dma_in); ++ case 3: ++ kfree(driver); ++ case 2: ++ kfree(ir); ++ case 1: ++ printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", ++ devnum, mem_failure); ++ return -ENOMEM; ++ } ++ ++ driver->minor = minor; ++ ir->d = driver; ++ ir->devnum = devnum; ++ ir->usbdev = dev; ++ ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; ++ ir->in_space = 1; /* First mode2 event is a space. */ ++ do_gettimeofday(&ir->last_time); ++ ++ if (dev->descriptor.iManufacturer ++ && usb_string(dev, dev->descriptor.iManufacturer, ++ buf, sizeof(buf)) > 0) ++ strlcpy(name, buf, sizeof(name)); ++ if (dev->descriptor.iProduct ++ && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) ++ snprintf(name + strlen(name), sizeof(name) - strlen(name), ++ " %s", buf); ++ printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, ++ dev->bus->busnum, devnum); ++ ++ /* clear device buffer */ ++ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), ++ SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, ++ /*unused*/0, /*unused*/0, ++ /*dummy*/ir->buf_in, /*dummy*/ir->len_in, ++ /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); ++ if (ret < 0) ++ printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", ++ devnum, ret); ++ ++ usb_set_intfdata(intf, ir); ++ return 0; ++} ++ ++ ++static void usb_remote_disconnect(struct usb_interface *intf) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct igorplug *ir = usb_get_intfdata(intf); ++ usb_set_intfdata(intf, NULL); ++ ++ if (!ir || !ir->d) ++ return; ++ ++ ir->usbdev = NULL; ++ wake_up_all(&ir->wait_out); ++ ++ usb_alloc_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); ++ ++ unregister_from_lirc(ir); ++} ++ ++static struct usb_device_id usb_remote_id_table[] = { ++ /* Igor Plug USB (Atmel's Manufact. ID) */ ++ { USB_DEVICE(0x03eb, 0x0002) }, ++ ++ /* Terminating entry */ ++ { } ++}; ++ ++static struct usb_driver usb_remote_driver = { ++ .name = DRIVER_NAME, ++ .probe = usb_remote_probe, ++ .disconnect = usb_remote_disconnect, ++ .id_table = usb_remote_id_table ++}; ++ ++static int __init usb_remote_init(void) ++{ ++ int i; ++ ++ printk(KERN_INFO "\n" ++ DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); ++ printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); ++ dprintk(DRIVER_NAME ": debug mode enabled\n"); ++ ++ i = usb_register(&usb_remote_driver); ++ if (i < 0) { ++ printk(DRIVER_NAME ": usb register failed, result = %d\n", i); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit usb_remote_exit(void) ++{ ++ usb_deregister(&usb_remote_driver); ++} ++ ++module_init(usb_remote_init); ++module_exit(usb_remote_exit); ++ ++#include ++MODULE_INFO(vermagic, VERMAGIC_STRING); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, usb_remote_id_table); ++ ++module_param(sample_rate, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); ++ +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_imon.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_imon.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_imon.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_imon.c 2010-08-02 09:28:03.940927260 +0200 +@@ -0,0 +1,1053 @@ ++/* ++ * lirc_imon.c: LIRC/VFD/LCD driver for SoundGraph iMON IR/VFD/LCD ++ * including the iMON PAD model ++ * ++ * Copyright(C) 2004 Venky Raju(dev@venky.ws) ++ * Copyright(C) 2009 Jarod Wilson ++ * ++ * lirc_imon is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++ ++#define MOD_AUTHOR "Venky Raju " ++#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" ++#define MOD_NAME "lirc_imon" ++#define MOD_VERSION "0.8" ++ ++#define DISPLAY_MINOR_BASE 144 ++#define DEVICE_NAME "lcd%d" ++ ++#define BUF_CHUNK_SIZE 4 ++#define BUF_SIZE 128 ++ ++#define BIT_DURATION 250 /* each bit received is 250us */ ++ ++/*** P R O T O T Y P E S ***/ ++ ++/* USB Callback prototypes */ ++static int imon_probe(struct usb_interface *interface, ++ const struct usb_device_id *id); ++static void imon_disconnect(struct usb_interface *interface); ++static void usb_rx_callback(struct urb *urb); ++static void usb_tx_callback(struct urb *urb); ++ ++/* suspend/resume support */ ++static int imon_resume(struct usb_interface *intf); ++static int imon_suspend(struct usb_interface *intf, pm_message_t message); ++ ++/* Display file_operations function prototypes */ ++static int display_open(struct inode *inode, struct file *file); ++static int display_close(struct inode *inode, struct file *file); ++ ++/* VFD write operation */ ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos); ++ ++/* LIRC driver function prototypes */ ++static int ir_open(void *data); ++static void ir_close(void *data); ++ ++/* Driver init/exit prototypes */ ++static int __init imon_init(void); ++static void __exit imon_exit(void); ++ ++/*** G L O B A L S ***/ ++ ++struct imon_context { ++ struct usb_device *usbdev; ++ /* Newer devices have two interfaces */ ++ int display; /* not all controllers do */ ++ int display_isopen; /* display port has been opened */ ++ int ir_isopen; /* IR port open */ ++ int dev_present; /* USB device presence */ ++ struct mutex ctx_lock; /* to lock this object */ ++ wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ ++ ++ int vfd_proto_6p; /* some VFD require a 6th packet */ ++ ++ struct lirc_driver *driver; ++ struct usb_endpoint_descriptor *rx_endpoint; ++ struct usb_endpoint_descriptor *tx_endpoint; ++ struct urb *rx_urb; ++ struct urb *tx_urb; ++ unsigned char usb_rx_buf[8]; ++ unsigned char usb_tx_buf[8]; ++ ++ struct rx_data { ++ int count; /* length of 0 or 1 sequence */ ++ int prev_bit; /* logic level of sequence */ ++ int initial_space; /* initial space flag */ ++ } rx; ++ ++ struct tx_t { ++ unsigned char data_buf[35]; /* user data buffer */ ++ struct completion finished; /* wait for write to finish */ ++ atomic_t busy; /* write in progress */ ++ int status; /* status of tx completion */ ++ } tx; ++}; ++ ++static struct file_operations display_fops = { ++ .owner = THIS_MODULE, ++ .open = &display_open, ++ .write = &vfd_write, ++ .release = &display_close ++}; ++ ++/* ++ * USB Device ID for iMON USB Control Boards ++ * ++ * The Windows drivers contain 6 different inf files, more or less one for ++ * each new device until the 0x0034-0x0046 devices, which all use the same ++ * driver. Some of the devices in the 34-46 range haven't been definitively ++ * identified yet. Early devices have either a TriGem Computer, Inc. or a ++ * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later ++ * devices use the SoundGraph vendor ID (0x15c2). ++ */ ++static struct usb_device_id imon_usb_id_table[] = { ++ /* TriGem iMON (IR only) -- TG_iMON.inf */ ++ { USB_DEVICE(0x0aa8, 0x8001) }, ++ ++ /* SoundGraph iMON (IR only) -- sg_imon.inf */ ++ { USB_DEVICE(0x04e8, 0xff30) }, ++ ++ /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */ ++ { USB_DEVICE(0x0aa8, 0xffda) }, ++ ++ /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */ ++ { USB_DEVICE(0x15c2, 0xffda) }, ++ ++ {} ++}; ++ ++/* Some iMON VFD models requires a 6th packet for VFD writes */ ++static struct usb_device_id vfd_proto_6p_list[] = { ++ { USB_DEVICE(0x15c2, 0xffda) }, ++ {} ++}; ++ ++/* Some iMON devices have no lcd/vfd, don't set one up */ ++static struct usb_device_id ir_only_list[] = { ++ { USB_DEVICE(0x0aa8, 0x8001) }, ++ { USB_DEVICE(0x04e8, 0xff30) }, ++ {} ++}; ++ ++/* USB Device data */ ++static struct usb_driver imon_driver = { ++ .name = MOD_NAME, ++ .probe = imon_probe, ++ .disconnect = imon_disconnect, ++ .suspend = imon_suspend, ++ .resume = imon_resume, ++ .id_table = imon_usb_id_table, ++}; ++ ++static struct usb_class_driver imon_class = { ++ .name = DEVICE_NAME, ++ .fops = &display_fops, ++ .minor_base = DISPLAY_MINOR_BASE, ++}; ++ ++/* to prevent races between open() and disconnect(), probing, etc */ ++static DEFINE_MUTEX(driver_lock); ++ ++static int debug; ++ ++/*** M O D U L E C O D E ***/ ++ ++MODULE_AUTHOR(MOD_AUTHOR); ++MODULE_DESCRIPTION(MOD_DESC); ++MODULE_VERSION(MOD_VERSION); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, imon_usb_id_table); ++module_param(debug, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); ++ ++static void free_imon_context(struct imon_context *context) ++{ ++ struct device *dev = context->driver->dev; ++ usb_free_urb(context->tx_urb); ++ usb_free_urb(context->rx_urb); ++ lirc_buffer_free(context->driver->rbuf); ++ kfree(context->driver->rbuf); ++ kfree(context->driver); ++ kfree(context); ++ ++ dev_dbg(dev, "%s: iMON context freed\n", __func__); ++} ++ ++static void deregister_from_lirc(struct imon_context *context) ++{ ++ int retval; ++ int minor = context->driver->minor; ++ ++ retval = lirc_unregister_driver(minor); ++ if (retval) ++ err("%s: unable to deregister from lirc(%d)", ++ __func__, retval); ++ else ++ printk(KERN_INFO MOD_NAME ": Deregistered iMON driver " ++ "(minor:%d)\n", minor); ++ ++} ++ ++/** ++ * Called when the Display device (e.g. /dev/lcd0) ++ * is opened by the application. ++ */ ++static int display_open(struct inode *inode, struct file *file) ++{ ++ struct usb_interface *interface; ++ struct imon_context *context = NULL; ++ int subminor; ++ int retval = 0; ++ ++ /* prevent races with disconnect */ ++ mutex_lock(&driver_lock); ++ ++ subminor = iminor(inode); ++ interface = usb_find_interface(&imon_driver, subminor); ++ if (!interface) { ++ err("%s: could not find interface for minor %d", ++ __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ context = usb_get_intfdata(interface); ++ ++ if (!context) { ++ err("%s: no context found for minor %d", ++ __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (!context->display) { ++ err("%s: display not supported by device", __func__); ++ retval = -ENODEV; ++ } else if (context->display_isopen) { ++ err("%s: display port is already open", __func__); ++ retval = -EBUSY; ++ } else { ++ context->display_isopen = 1; ++ file->private_data = context; ++ dev_info(context->driver->dev, "display port opened\n"); ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ ++exit: ++ mutex_unlock(&driver_lock); ++ return retval; ++} ++ ++/** ++ * Called when the display device (e.g. /dev/lcd0) ++ * is closed by the application. ++ */ ++static int display_close(struct inode *inode, struct file *file) ++{ ++ struct imon_context *context = NULL; ++ int retval = 0; ++ ++ context = (struct imon_context *)file->private_data; ++ ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (!context->display) { ++ err("%s: display not supported by device", __func__); ++ retval = -ENODEV; ++ } else if (!context->display_isopen) { ++ err("%s: display is not open", __func__); ++ retval = -EIO; ++ } else { ++ context->display_isopen = 0; ++ dev_info(context->driver->dev, "display port closed\n"); ++ if (!context->dev_present && !context->ir_isopen) { ++ /* ++ * Device disconnected before close and IR port is not ++ * open. If IR port is open, context will be deleted by ++ * ir_close. ++ */ ++ mutex_unlock(&context->ctx_lock); ++ free_imon_context(context); ++ return retval; ++ } ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ return retval; ++} ++ ++/** ++ * Sends a packet to the device -- this function must be called ++ * with context->ctx_lock held. ++ */ ++static int send_packet(struct imon_context *context) ++{ ++ unsigned int pipe; ++ int interval = 0; ++ int retval = 0; ++ struct usb_ctrlrequest *control_req = NULL; ++ ++ /* Check if we need to use control or interrupt urb */ ++ pipe = usb_sndintpipe(context->usbdev, ++ context->tx_endpoint->bEndpointAddress); ++ interval = context->tx_endpoint->bInterval; ++ ++ usb_fill_int_urb(context->tx_urb, context->usbdev, pipe, ++ context->usb_tx_buf, ++ sizeof(context->usb_tx_buf), ++ usb_tx_callback, context, interval); ++ ++ context->tx_urb->actual_length = 0; ++ ++ init_completion(&context->tx.finished); ++ atomic_set(&(context->tx.busy), 1); ++ ++ retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); ++ if (retval) { ++ atomic_set(&(context->tx.busy), 0); ++ err("%s: error submitting urb(%d)", __func__, retval); ++ } else { ++ /* Wait for transmission to complete (or abort) */ ++ mutex_unlock(&context->ctx_lock); ++ retval = wait_for_completion_interruptible( ++ &context->tx.finished); ++ if (retval) ++ err("%s: task interrupted", __func__); ++ mutex_lock(&context->ctx_lock); ++ ++ retval = context->tx.status; ++ if (retval) ++ err("%s: packet tx failed (%d)", __func__, retval); ++ } ++ ++ kfree(control_req); ++ ++ return retval; ++} ++ ++/** ++ * Writes data to the VFD. The iMON VFD is 2x16 characters ++ * and requires data in 5 consecutive USB interrupt packets, ++ * each packet but the last carrying 7 bytes. ++ * ++ * I don't know if the VFD board supports features such as ++ * scrolling, clearing rows, blanking, etc. so at ++ * the caller must provide a full screen of data. If fewer ++ * than 32 bytes are provided spaces will be appended to ++ * generate a full screen. ++ */ ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos) ++{ ++ int i; ++ int offset; ++ int seq; ++ int retval = 0; ++ struct imon_context *context; ++ const unsigned char vfd_packet6[] = { ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; ++ ++ context = (struct imon_context *)file->private_data; ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (!context->dev_present) { ++ err("%s: no iMON device present", __func__); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ if (n_bytes <= 0 || n_bytes > 32) { ++ err("%s: invalid payload size", __func__); ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ if (copy_from_user(context->tx.data_buf, buf, n_bytes)) { ++ retval = -EFAULT; ++ goto exit; ++ } ++ ++ /* Pad with spaces */ ++ for (i = n_bytes; i < 32; ++i) ++ context->tx.data_buf[i] = ' '; ++ ++ for (i = 32; i < 35; ++i) ++ context->tx.data_buf[i] = 0xFF; ++ ++ offset = 0; ++ seq = 0; ++ ++ do { ++ memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7); ++ context->usb_tx_buf[7] = (unsigned char) seq; ++ ++ retval = send_packet(context); ++ if (retval) { ++ err("%s: send packet failed for packet #%d", ++ __func__, seq/2); ++ goto exit; ++ } else { ++ seq += 2; ++ offset += 7; ++ } ++ ++ } while (offset < 35); ++ ++ if (context->vfd_proto_6p) { ++ /* Send packet #6 */ ++ memcpy(context->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6)); ++ context->usb_tx_buf[7] = (unsigned char) seq; ++ retval = send_packet(context); ++ if (retval) ++ err("%s: send packet failed for packet #%d", ++ __func__, seq/2); ++ } ++ ++exit: ++ mutex_unlock(&context->ctx_lock); ++ ++ return (!retval) ? n_bytes : retval; ++} ++ ++/** ++ * Callback function for USB core API: transmit data ++ */ ++static void usb_tx_callback(struct urb *urb) ++{ ++ struct imon_context *context; ++ ++ if (!urb) ++ return; ++ context = (struct imon_context *)urb->context; ++ if (!context) ++ return; ++ ++ context->tx.status = urb->status; ++ ++ /* notify waiters that write has finished */ ++ atomic_set(&context->tx.busy, 0); ++ complete(&context->tx.finished); ++ ++ return; ++} ++ ++/** ++ * Called by lirc_dev when the application opens /dev/lirc ++ */ ++static int ir_open(void *data) ++{ ++ int retval = 0; ++ struct imon_context *context; ++ ++ /* prevent races with disconnect */ ++ mutex_lock(&driver_lock); ++ ++ context = (struct imon_context *)data; ++ ++ /* initial IR protocol decode variables */ ++ context->rx.count = 0; ++ context->rx.initial_space = 1; ++ context->rx.prev_bit = 0; ++ ++ context->ir_isopen = 1; ++ dev_info(context->driver->dev, "IR port opened\n"); ++ ++ mutex_unlock(&driver_lock); ++ return retval; ++} ++ ++/** ++ * Called by lirc_dev when the application closes /dev/lirc ++ */ ++static void ir_close(void *data) ++{ ++ struct imon_context *context; ++ ++ context = (struct imon_context *)data; ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ context->ir_isopen = 0; ++ dev_info(context->driver->dev, "IR port closed\n"); ++ ++ if (!context->dev_present) { ++ /* ++ * Device disconnected while IR port was still open. Driver ++ * was not deregistered at disconnect time, so do it now. ++ */ ++ deregister_from_lirc(context); ++ ++ if (!context->display_isopen) { ++ mutex_unlock(&context->ctx_lock); ++ free_imon_context(context); ++ return; ++ } ++ /* ++ * If display port is open, context will be deleted by ++ * display_close ++ */ ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ return; ++} ++ ++/** ++ * Convert bit count to time duration (in us) and submit ++ * the value to lirc_dev. ++ */ ++static void submit_data(struct imon_context *context) ++{ ++ unsigned char buf[4]; ++ int value = context->rx.count; ++ int i; ++ ++ dev_dbg(context->driver->dev, "submitting data to LIRC\n"); ++ ++ value *= BIT_DURATION; ++ value &= PULSE_MASK; ++ if (context->rx.prev_bit) ++ value |= PULSE_BIT; ++ ++ for (i = 0; i < 4; ++i) ++ buf[i] = value>>(i*8); ++ ++ lirc_buffer_write(context->driver->rbuf, buf); ++ wake_up(&context->driver->rbuf->wait_poll); ++ return; ++} ++ ++static inline int tv2int(const struct timeval *a, const struct timeval *b) ++{ ++ int usecs = 0; ++ int sec = 0; ++ ++ if (b->tv_usec > a->tv_usec) { ++ usecs = 1000000; ++ sec--; ++ } ++ ++ usecs += a->tv_usec - b->tv_usec; ++ ++ sec += a->tv_sec - b->tv_sec; ++ sec *= 1000; ++ usecs /= 1000; ++ sec += usecs; ++ ++ if (sec < 0) ++ sec = 1000; ++ ++ return sec; ++} ++ ++/** ++ * Process the incoming packet ++ */ ++static void imon_incoming_packet(struct imon_context *context, ++ struct urb *urb, int intf) ++{ ++ int len = urb->actual_length; ++ unsigned char *buf = urb->transfer_buffer; ++ struct device *dev = context->driver->dev; ++ int octet, bit; ++ unsigned char mask; ++ int i, chunk_num; ++ ++ /* ++ * just bail out if no listening IR client ++ */ ++ if (!context->ir_isopen) ++ return; ++ ++ if (len != 8) { ++ dev_warn(dev, "imon %s: invalid incoming packet " ++ "size (len = %d, intf%d)\n", __func__, len, intf); ++ return; ++ } ++ ++ if (debug) { ++ printk(KERN_INFO "raw packet: "); ++ for (i = 0; i < len; ++i) ++ printk("%02x ", buf[i]); ++ printk("\n"); ++ } ++ ++ /* ++ * Translate received data to pulse and space lengths. ++ * Received data is active low, i.e. pulses are 0 and ++ * spaces are 1. ++ * ++ * My original algorithm was essentially similar to ++ * Changwoo Ryu's with the exception that he switched ++ * the incoming bits to active high and also fed an ++ * initial space to LIRC at the start of a new sequence ++ * if the previous bit was a pulse. ++ * ++ * I've decided to adopt his algorithm. ++ */ ++ ++ if (buf[7] == 1 && context->rx.initial_space) { ++ /* LIRC requires a leading space */ ++ context->rx.prev_bit = 0; ++ context->rx.count = 4; ++ submit_data(context); ++ context->rx.count = 0; ++ } ++ ++ for (octet = 0; octet < 5; ++octet) { ++ mask = 0x80; ++ for (bit = 0; bit < 8; ++bit) { ++ int curr_bit = !(buf[octet] & mask); ++ if (curr_bit != context->rx.prev_bit) { ++ if (context->rx.count) { ++ submit_data(context); ++ context->rx.count = 0; ++ } ++ context->rx.prev_bit = curr_bit; ++ } ++ ++context->rx.count; ++ mask >>= 1; ++ } ++ } ++ ++ if (chunk_num == 10) { ++ if (context->rx.count) { ++ submit_data(context); ++ context->rx.count = 0; ++ } ++ context->rx.initial_space = context->rx.prev_bit; ++ } ++} ++ ++/** ++ * Callback function for USB core API: receive data ++ */ ++static void usb_rx_callback(struct urb *urb) ++{ ++ struct imon_context *context; ++ unsigned char *buf; ++ int len; ++ int intfnum = 0; ++ ++ if (!urb) ++ return; ++ ++ context = (struct imon_context *)urb->context; ++ if (!context) ++ return; ++ ++ buf = urb->transfer_buffer; ++ len = urb->actual_length; ++ ++ switch (urb->status) { ++ case -ENOENT: /* usbcore unlink successful! */ ++ return; ++ ++ case 0: ++ imon_incoming_packet(context, urb, intfnum); ++ break; ++ ++ default: ++ dev_warn(context->driver->dev, "imon %s: status(%d): ignored\n", ++ __func__, urb->status); ++ break; ++ } ++ ++ usb_submit_urb(context->rx_urb, GFP_ATOMIC); ++ ++ return; ++} ++ ++/** ++ * Callback function for USB core API: Probe ++ */ ++static int imon_probe(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *usbdev = NULL; ++ struct usb_host_interface *iface_desc = NULL; ++ struct usb_endpoint_descriptor *rx_endpoint = NULL; ++ struct usb_endpoint_descriptor *tx_endpoint = NULL; ++ struct urb *rx_urb = NULL; ++ struct urb *tx_urb = NULL; ++ struct lirc_driver *driver = NULL; ++ struct lirc_buffer *rbuf = NULL; ++ struct device *dev = &interface->dev; ++ int ifnum; ++ int lirc_minor = 0; ++ int num_endpts; ++ int retval = 0; ++ int display_ep_found = 0; ++ int ir_ep_found = 0; ++ int alloc_status = 0; ++ int vfd_proto_6p = 0; ++ int code_length; ++ struct imon_context *context = NULL; ++ int i; ++ u16 vendor, product; ++ ++ context = kzalloc(sizeof(struct imon_context), GFP_KERNEL); ++ if (!context) { ++ err("%s: kzalloc failed for context", __func__); ++ alloc_status = 1; ++ goto alloc_status_switch; ++ } ++ ++ /* ++ * Try to auto-detect the type of display if the user hasn't set ++ * it by hand via the display_type modparam. Default is VFD. ++ */ ++ if (usb_match_id(interface, ir_only_list)) ++ context->display = 0; ++ else ++ context->display = 1; ++ ++ code_length = BUF_CHUNK_SIZE * 8; ++ ++ usbdev = usb_get_dev(interface_to_usbdev(interface)); ++ iface_desc = interface->cur_altsetting; ++ num_endpts = iface_desc->desc.bNumEndpoints; ++ ifnum = iface_desc->desc.bInterfaceNumber; ++ vendor = le16_to_cpu(usbdev->descriptor.idVendor); ++ product = le16_to_cpu(usbdev->descriptor.idProduct); ++ ++ dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n", ++ __func__, vendor, product, ifnum); ++ ++ /* prevent races probing devices w/multiple interfaces */ ++ mutex_lock(&driver_lock); ++ ++ /* ++ * Scan the endpoint list and set: ++ * first input endpoint = IR endpoint ++ * first output endpoint = display endpoint ++ */ ++ for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) { ++ struct usb_endpoint_descriptor *ep; ++ int ep_dir; ++ int ep_type; ++ ep = &iface_desc->endpoint[i].desc; ++ ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ++ ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ ++ if (!ir_ep_found && ++ ep_dir == USB_DIR_IN && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ ++ rx_endpoint = ep; ++ ir_ep_found = 1; ++ dev_dbg(dev, "%s: found IR endpoint\n", __func__); ++ ++ } else if (!display_ep_found && ep_dir == USB_DIR_OUT && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ tx_endpoint = ep; ++ display_ep_found = 1; ++ dev_dbg(dev, "%s: found display endpoint\n", __func__); ++ } ++ } ++ ++ /* ++ * Some iMON receivers have no display. Unfortunately, it seems ++ * that SoundGraph recycles device IDs between devices both with ++ * and without... :\ ++ */ ++ if (context->display == 0) { ++ display_ep_found = 0; ++ dev_dbg(dev, "%s: device has no display\n", __func__); ++ } ++ ++ /* Input endpoint is mandatory */ ++ if (!ir_ep_found) { ++ err("%s: no valid input (IR) endpoint found.", __func__); ++ retval = -ENODEV; ++ alloc_status = 2; ++ goto alloc_status_switch; ++ } ++ ++ /* Determine if display requires 6 packets */ ++ if (display_ep_found) { ++ if (usb_match_id(interface, vfd_proto_6p_list)) ++ vfd_proto_6p = 1; ++ ++ dev_dbg(dev, "%s: vfd_proto_6p: %d\n", ++ __func__, vfd_proto_6p); ++ } ++ ++ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ if (!driver) { ++ err("%s: kzalloc failed for lirc_driver", __func__); ++ alloc_status = 2; ++ goto alloc_status_switch; ++ } ++ rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!rbuf) { ++ err("%s: kmalloc failed for lirc_buffer", __func__); ++ alloc_status = 3; ++ goto alloc_status_switch; ++ } ++ if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { ++ err("%s: lirc_buffer_init failed", __func__); ++ alloc_status = 4; ++ goto alloc_status_switch; ++ } ++ rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!rx_urb) { ++ err("%s: usb_alloc_urb failed for IR urb", __func__); ++ alloc_status = 5; ++ goto alloc_status_switch; ++ } ++ tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!tx_urb) { ++ err("%s: usb_alloc_urb failed for display urb", ++ __func__); ++ alloc_status = 6; ++ goto alloc_status_switch; ++ } ++ ++ mutex_init(&context->ctx_lock); ++ context->vfd_proto_6p = vfd_proto_6p; ++ ++ strcpy(driver->name, MOD_NAME); ++ driver->minor = -1; ++ driver->code_length = sizeof(int) * 8; ++ driver->sample_rate = 0; ++ driver->features = LIRC_CAN_REC_MODE2; ++ driver->data = context; ++ driver->rbuf = rbuf; ++ driver->set_use_inc = ir_open; ++ driver->set_use_dec = ir_close; ++ driver->dev = &interface->dev; ++ driver->owner = THIS_MODULE; ++ ++ mutex_lock(&context->ctx_lock); ++ ++ context->driver = driver; ++ /* start out in keyboard mode */ ++ ++ lirc_minor = lirc_register_driver(driver); ++ if (lirc_minor < 0) { ++ err("%s: lirc_register_driver failed", __func__); ++ alloc_status = 7; ++ goto alloc_status_switch; ++ } else ++ dev_info(dev, "Registered iMON driver " ++ "(lirc minor: %d)\n", lirc_minor); ++ ++ /* Needed while unregistering! */ ++ driver->minor = lirc_minor; ++ ++ context->usbdev = usbdev; ++ context->dev_present = 1; ++ context->rx_endpoint = rx_endpoint; ++ context->rx_urb = rx_urb; ++ ++ /* ++ * tx is used to send characters to lcd/vfd, associate RF ++ * remotes, set IR protocol, and maybe more... ++ */ ++ context->tx_endpoint = tx_endpoint; ++ context->tx_urb = tx_urb; ++ ++ if (display_ep_found) ++ context->display = 1; ++ ++ usb_fill_int_urb(context->rx_urb, context->usbdev, ++ usb_rcvintpipe(context->usbdev, ++ context->rx_endpoint->bEndpointAddress), ++ context->usb_rx_buf, sizeof(context->usb_rx_buf), ++ usb_rx_callback, context, ++ context->rx_endpoint->bInterval); ++ ++ retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); ++ ++ if (retval) { ++ err("%s: usb_submit_urb failed for intf0 (%d)", ++ __func__, retval); ++ mutex_unlock(&context->ctx_lock); ++ goto exit; ++ } ++ ++ usb_set_intfdata(interface, context); ++ ++ if (context->display && ifnum == 0) { ++ dev_dbg(dev, "%s: Registering iMON display with sysfs\n", ++ __func__); ++ ++ if (usb_register_dev(interface, &imon_class)) { ++ /* Not a fatal error, so ignore */ ++ dev_info(dev, "%s: could not get a minor number for " ++ "display\n", __func__); ++ } ++ } ++ ++ dev_info(dev, "iMON device (%04x:%04x, intf%d) on " ++ "usb<%d:%d> initialized\n", vendor, product, ifnum, ++ usbdev->bus->busnum, usbdev->devnum); ++ ++alloc_status_switch: ++ mutex_unlock(&context->ctx_lock); ++ ++ switch (alloc_status) { ++ case 7: ++ usb_free_urb(tx_urb); ++ case 6: ++ usb_free_urb(rx_urb); ++ case 5: ++ if (rbuf) ++ lirc_buffer_free(rbuf); ++ case 4: ++ kfree(rbuf); ++ case 3: ++ kfree(driver); ++ case 2: ++ kfree(context); ++ context = NULL; ++ case 1: ++ if (retval != -ENODEV) ++ retval = -ENOMEM; ++ break; ++ case 0: ++ retval = 0; ++ } ++ ++exit: ++ mutex_unlock(&driver_lock); ++ ++ return retval; ++} ++ ++/** ++ * Callback function for USB core API: disconnect ++ */ ++static void imon_disconnect(struct usb_interface *interface) ++{ ++ struct imon_context *context; ++ int ifnum; ++ ++ /* prevent races with ir_open()/display_open() */ ++ mutex_lock(&driver_lock); ++ ++ context = usb_get_intfdata(interface); ++ ifnum = interface->cur_altsetting->desc.bInterfaceNumber; ++ ++ mutex_lock(&context->ctx_lock); ++ ++ usb_set_intfdata(interface, NULL); ++ ++ /* Abort ongoing write */ ++ if (atomic_read(&context->tx.busy)) { ++ usb_kill_urb(context->tx_urb); ++ complete_all(&context->tx.finished); ++ } ++ ++ context->dev_present = 0; ++ usb_kill_urb(context->rx_urb); ++ if (context->display) ++ usb_deregister_dev(interface, &imon_class); ++ ++ if (!context->ir_isopen && !context->dev_present) { ++ deregister_from_lirc(context); ++ mutex_unlock(&context->ctx_lock); ++ if (!context->display_isopen) ++ free_imon_context(context); ++ } else ++ mutex_unlock(&context->ctx_lock); ++ ++ mutex_unlock(&driver_lock); ++ ++ printk(KERN_INFO "%s: iMON device (intf%d) disconnected\n", ++ __func__, ifnum); ++} ++ ++static int imon_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct imon_context *context = usb_get_intfdata(intf); ++ ++ usb_kill_urb(context->rx_urb); ++ ++ return 0; ++} ++ ++static int imon_resume(struct usb_interface *intf) ++{ ++ int rc = 0; ++ struct imon_context *context = usb_get_intfdata(intf); ++ ++ usb_fill_int_urb(context->rx_urb, context->usbdev, ++ usb_rcvintpipe(context->usbdev, ++ context->rx_endpoint->bEndpointAddress), ++ context->usb_rx_buf, sizeof(context->usb_rx_buf), ++ usb_rx_callback, context, ++ context->rx_endpoint->bInterval); ++ ++ rc = usb_submit_urb(context->rx_urb, GFP_ATOMIC); ++ ++ return rc; ++} ++ ++static int __init imon_init(void) ++{ ++ int rc; ++ ++ printk(KERN_INFO MOD_NAME ": " MOD_DESC ", v" MOD_VERSION "\n"); ++ ++ rc = usb_register(&imon_driver); ++ if (rc) { ++ err("%s: usb register failed(%d)", __func__, rc); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit imon_exit(void) ++{ ++ usb_deregister(&imon_driver); ++ printk(KERN_INFO MOD_NAME ": module removed. Goodbye!\n"); ++} ++ ++module_init(imon_init); ++module_exit(imon_exit); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_it87.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_it87.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_it87.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_it87.c 2010-08-02 09:28:03.947926779 +0200 +@@ -0,0 +1,1021 @@ ++/* ++ * LIRC driver for ITE IT8712/IT8705 CIR port ++ * ++ * Copyright (C) 2001 Hans-Gunter Lutke Uphues ++ * ++ * 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 ++ * ++ * ITE IT8705 and IT8712(not tested) and IT8720 CIR-port support for lirc based ++ * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula ++ * ++ * Attention: Sendmode only tested with debugging logs ++ * ++ * 2001/02/27 Christoph Bartelmus : ++ * reimplemented read function ++ * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix, ++ * based on work of the following member of the Outertrack Digimatrix ++ * Forum: Art103 ++ * 2009/12/24 James Edwards implemeted support ++ * for ITE8704/ITE8718, on my machine, the DSDT reports 8704, but the ++ * chip identifies as 18. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++#include "lirc_it87.h" ++ ++#ifdef LIRC_IT87_DIGIMATRIX ++static int digimatrix = 1; ++static int it87_freq = 36; /* kHz */ ++static int irq = 9; ++#else ++static int digimatrix; ++static int it87_freq = 38; /* kHz */ ++static int irq = IT87_CIR_DEFAULT_IRQ; ++#endif ++ ++static unsigned long it87_bits_in_byte_out; ++static unsigned long it87_send_counter; ++static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN; ++ ++#define RBUF_LEN 1024 ++#define WBUF_LEN 1024 ++ ++#define LIRC_DRIVER_NAME "lirc_it87" ++ ++/* timeout for sequences in jiffies (=5/100s) */ ++/* must be longer than TIME_CONST */ ++#define IT87_TIMEOUT (HZ*5/100) ++ ++/* module parameters */ ++static int debug; ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ ++ fmt, ## args); \ ++ } while (0) ++ ++static int io = IT87_CIR_DEFAULT_IOBASE; ++/* receiver demodulator default: off */ ++static int it87_enable_demodulator; ++ ++static int timer_enabled; ++static DEFINE_SPINLOCK(timer_lock); ++static struct timer_list timerlist; ++/* time of last signal change detected */ ++static struct timeval last_tv = {0, 0}; ++/* time of last UART data ready interrupt */ ++static struct timeval last_intr_tv = {0, 0}; ++static int last_value; ++ ++static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); ++ ++static DEFINE_SPINLOCK(hardware_lock); ++static DEFINE_SPINLOCK(dev_lock); ++ ++static int rx_buf[RBUF_LEN]; ++unsigned int rx_tail, rx_head; ++static int tx_buf[WBUF_LEN]; ++ ++static struct pnp_driver it87_pnp_driver; ++ ++/* SECTION: Prototypes */ ++ ++/* Communication with user-space */ ++static int lirc_open(struct inode *inode, struct file *file); ++static int lirc_close(struct inode *inode, struct file *file); ++static unsigned int lirc_poll(struct file *file, poll_table *wait); ++static ssize_t lirc_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos); ++static ssize_t lirc_write(struct file *file, const char *buf, ++ size_t n, loff_t *pos); ++static int lirc_ioctl(struct inode *node, struct file *filep, ++ unsigned int cmd, unsigned long arg); ++static void add_read_queue(int flag, unsigned long val); ++static int init_chrdev(void); ++static void drop_chrdev(void); ++/* Hardware */ ++static irqreturn_t it87_interrupt(int irq, void *dev_id); ++static void send_space(unsigned long len); ++static void send_pulse(unsigned long len); ++static void init_send(void); ++static void terminate_send(unsigned long len); ++static int init_hardware(void); ++static void drop_hardware(void); ++/* Initialisation */ ++static int init_port(void); ++static void drop_port(void); ++ ++ ++/* SECTION: Communication with user-space */ ++ ++static int lirc_open(struct inode *inode, struct file *file) ++{ ++ spin_lock(&dev_lock); ++ if (module_refcount(THIS_MODULE)) { ++ spin_unlock(&dev_lock); ++ return -EBUSY; ++ } ++ spin_unlock(&dev_lock); ++ return 0; ++} ++ ++ ++static int lirc_close(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++ ++static unsigned int lirc_poll(struct file *file, poll_table *wait) ++{ ++ poll_wait(file, &lirc_read_queue, wait); ++ if (rx_head != rx_tail) ++ return POLLIN | POLLRDNORM; ++ return 0; ++} ++ ++ ++static ssize_t lirc_read(struct file *file, char *buf, ++ size_t count, loff_t *ppos) ++{ ++ int n = 0; ++ int retval = 0; ++ ++ while (n < count) { ++ if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) { ++ retval = -EAGAIN; ++ break; ++ } ++ retval = wait_event_interruptible(lirc_read_queue, ++ rx_head != rx_tail); ++ if (retval) ++ break; ++ ++ if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head), ++ sizeof(int))) { ++ retval = -EFAULT; ++ break; ++ } ++ rx_head = (rx_head + 1) & (RBUF_LEN - 1); ++ n += sizeof(int); ++ } ++ if (n) ++ return n; ++ return retval; ++} ++ ++ ++static ssize_t lirc_write(struct file *file, const char *buf, ++ size_t n, loff_t *pos) ++{ ++ int i = 0; ++ ++ if (n % sizeof(int) || (n / sizeof(int)) > WBUF_LEN) ++ return -EINVAL; ++ if (copy_from_user(tx_buf, buf, n)) ++ return -EFAULT; ++ n /= sizeof(int); ++ init_send(); ++ while (1) { ++ if (i >= n) ++ break; ++ if (tx_buf[i]) ++ send_pulse(tx_buf[i]); ++ i++; ++ if (i >= n) ++ break; ++ if (tx_buf[i]) ++ send_space(tx_buf[i]); ++ i++; ++ } ++ terminate_send(tx_buf[i - 1]); ++ return n; ++} ++ ++ ++static int lirc_ioctl(struct inode *node, struct file *filep, ++ unsigned int cmd, unsigned long arg) ++{ ++ int retval = 0; ++ unsigned long value = 0; ++ unsigned int ivalue; ++ unsigned long hw_flags; ++ ++ if (cmd == LIRC_GET_FEATURES) ++ value = LIRC_CAN_SEND_PULSE | ++ LIRC_CAN_SET_SEND_CARRIER | ++ LIRC_CAN_REC_MODE2; ++ else if (cmd == LIRC_GET_SEND_MODE) ++ value = LIRC_MODE_PULSE; ++ else if (cmd == LIRC_GET_REC_MODE) ++ value = LIRC_MODE_MODE2; ++ ++ switch (cmd) { ++ case LIRC_GET_FEATURES: ++ case LIRC_GET_SEND_MODE: ++ case LIRC_GET_REC_MODE: ++ retval = put_user(value, (unsigned long *) arg); ++ break; ++ ++ case LIRC_SET_SEND_MODE: ++ case LIRC_SET_REC_MODE: ++ retval = get_user(value, (unsigned long *) arg); ++ break; ++ ++ case LIRC_SET_SEND_CARRIER: ++ retval = get_user(ivalue, (unsigned int *) arg); ++ if (retval) ++ return retval; ++ ivalue /= 1000; ++ if (ivalue > IT87_CIR_FREQ_MAX || ++ ivalue < IT87_CIR_FREQ_MIN) ++ return -EINVAL; ++ ++ it87_freq = ivalue; ++ ++ spin_lock_irqsave(&hardware_lock, hw_flags); ++ outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | ++ (it87_freq - IT87_CIR_FREQ_MIN) << 3), ++ io + IT87_CIR_TCR2); ++ spin_unlock_irqrestore(&hardware_lock, hw_flags); ++ dprintk("demodulation frequency: %d kHz\n", it87_freq); ++ ++ break; ++ ++ default: ++ retval = -EINVAL; ++ } ++ ++ if (retval) ++ return retval; ++ ++ if (cmd == LIRC_SET_REC_MODE) { ++ if (value != LIRC_MODE_MODE2) ++ retval = -ENOSYS; ++ } else if (cmd == LIRC_SET_SEND_MODE) { ++ if (value != LIRC_MODE_PULSE) ++ retval = -ENOSYS; ++ } ++ return retval; ++} ++ ++static void add_read_queue(int flag, unsigned long val) ++{ ++ unsigned int new_rx_tail; ++ int newval; ++ ++ dprintk("add flag %d with val %lu\n", flag, val); ++ ++ newval = val & PULSE_MASK; ++ ++ /* ++ * statistically, pulses are ~TIME_CONST/2 too long. we could ++ * maybe make this more exact, but this is good enough ++ */ ++ if (flag) { ++ /* pulse */ ++ if (newval > TIME_CONST / 2) ++ newval -= TIME_CONST / 2; ++ else /* should not ever happen */ ++ newval = 1; ++ newval |= PULSE_BIT; ++ } else ++ newval += TIME_CONST / 2; ++ new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); ++ if (new_rx_tail == rx_head) { ++ dprintk("Buffer overrun.\n"); ++ return; ++ } ++ rx_buf[rx_tail] = newval; ++ rx_tail = new_rx_tail; ++ wake_up_interruptible(&lirc_read_queue); ++} ++ ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .read = lirc_read, ++ .write = lirc_write, ++ .poll = lirc_poll, ++ .ioctl = lirc_ioctl, ++ .open = lirc_open, ++ .release = lirc_close, ++}; ++ ++static int set_use_inc(void *data) ++{ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++} ++ ++static struct lirc_driver driver = { ++ .name = LIRC_DRIVER_NAME, ++ .minor = -1, ++ .code_length = 1, ++ .sample_rate = 0, ++ .data = NULL, ++ .add_to_buf = NULL, ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .fops = &lirc_fops, ++ .dev = NULL, ++ .owner = THIS_MODULE, ++}; ++ ++ ++#ifdef MODULE ++static int init_chrdev(void) ++{ ++ driver.minor = lirc_register_driver(&driver); ++ ++ if (driver.minor < 0) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++ ++static void drop_chrdev(void) ++{ ++ lirc_unregister_driver(driver.minor); ++} ++#endif ++ ++ ++/* SECTION: Hardware */ ++static long delta(struct timeval *tv1, struct timeval *tv2) ++{ ++ unsigned long deltv; ++ ++ deltv = tv2->tv_sec - tv1->tv_sec; ++ if (deltv > 15) ++ deltv = 0xFFFFFF; ++ else ++ deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec; ++ return deltv; ++} ++ ++static void it87_timeout(unsigned long data) ++{ ++ unsigned long flags; ++ ++ /* avoid interference with interrupt */ ++ spin_lock_irqsave(&timer_lock, flags); ++ ++ if (digimatrix) { ++ /* We have timed out. Disable the RX mechanism. */ ++ ++ outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) | ++ IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR); ++ if (it87_RXEN_mask) ++ outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, ++ io + IT87_CIR_RCR); ++ dprintk(" TIMEOUT\n"); ++ timer_enabled = 0; ++ ++ /* fifo clear */ ++ outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR, ++ io+IT87_CIR_TCR1); ++ ++ } else { ++ /* ++ * if last received signal was a pulse, but receiving stopped ++ * within the 9 bit frame, we need to finish this pulse and ++ * simulate a signal change to from pulse to space. Otherwise ++ * upper layers will receive two sequences next time. ++ */ ++ ++ if (last_value) { ++ unsigned long pulse_end; ++ ++ /* determine 'virtual' pulse end: */ ++ pulse_end = delta(&last_tv, &last_intr_tv); ++ dprintk("timeout add %d for %lu usec\n", ++ last_value, pulse_end); ++ add_read_queue(last_value, pulse_end); ++ last_value = 0; ++ last_tv = last_intr_tv; ++ } ++ } ++ spin_unlock_irqrestore(&timer_lock, flags); ++} ++ ++static irqreturn_t it87_interrupt(int irq, void *dev_id) ++{ ++ unsigned char data; ++ struct timeval curr_tv; ++ static unsigned long deltv; ++ unsigned long deltintrtv; ++ unsigned long flags, hw_flags; ++ int iir, lsr; ++ int fifo = 0; ++ static char lastbit; ++ char bit; ++ ++ /* Bit duration in microseconds */ ++ const unsigned long bit_duration = 1000000ul / ++ (115200 / IT87_CIR_BAUDRATE_DIVISOR); ++ ++ ++ iir = inb(io + IT87_CIR_IIR); ++ ++ switch (iir & IT87_CIR_IIR_IID) { ++ case 0x4: ++ case 0x6: ++ lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO | ++ IT87_CIR_RSR_RXFBC); ++ fifo = lsr & IT87_CIR_RSR_RXFBC; ++ dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr); ++ ++ /* avoid interference with timer */ ++ spin_lock_irqsave(&timer_lock, flags); ++ spin_lock_irqsave(&hardware_lock, hw_flags); ++ if (digimatrix) { ++ static unsigned long acc_pulse; ++ static unsigned long acc_space; ++ ++ do { ++ data = inb(io + IT87_CIR_DR); ++ data = ~data; ++ fifo--; ++ if (data != 0x00) { ++ if (timer_enabled) ++ del_timer(&timerlist); ++ /* ++ * start timer for end of ++ * sequence detection ++ */ ++ timerlist.expires = jiffies + ++ IT87_TIMEOUT; ++ add_timer(&timerlist); ++ timer_enabled = 1; ++ } ++ /* Loop through */ ++ for (bit = 0; bit < 8; ++bit) { ++ if ((data >> bit) & 1) { ++ ++acc_pulse; ++ if (lastbit == 0) { ++ add_read_queue(0, ++ acc_space * ++ bit_duration); ++ acc_space = 0; ++ } ++ } else { ++ ++acc_space; ++ if (lastbit == 1) { ++ add_read_queue(1, ++ acc_pulse * ++ bit_duration); ++ acc_pulse = 0; ++ } ++ } ++ lastbit = (data >> bit) & 1; ++ } ++ ++ } while (fifo != 0); ++ } else { /* Normal Operation */ ++ do { ++ del_timer(&timerlist); ++ data = inb(io + IT87_CIR_DR); ++ ++ dprintk("data=%02x\n", data); ++ do_gettimeofday(&curr_tv); ++ deltv = delta(&last_tv, &curr_tv); ++ deltintrtv = delta(&last_intr_tv, &curr_tv); ++ ++ dprintk("t %lu , d %d\n", ++ deltintrtv, (int)data); ++ ++ /* ++ * if nothing came in last 2 cycles, ++ * it was gap ++ */ ++ if (deltintrtv > TIME_CONST * 2) { ++ if (last_value) { ++ dprintk("GAP\n"); ++ ++ /* simulate signal change */ ++ add_read_queue(last_value, ++ deltv - ++ deltintrtv); ++ last_value = 0; ++ last_tv.tv_sec = ++ last_intr_tv.tv_sec; ++ last_tv.tv_usec = ++ last_intr_tv.tv_usec; ++ deltv = deltintrtv; ++ } ++ } ++ data = 1; ++ if (data ^ last_value) { ++ /* ++ * deltintrtv > 2*TIME_CONST, ++ * remember ? the other case is ++ * timeout ++ */ ++ add_read_queue(last_value, ++ deltv-TIME_CONST); ++ last_value = data; ++ last_tv = curr_tv; ++ if (last_tv.tv_usec >= TIME_CONST) ++ last_tv.tv_usec -= TIME_CONST; ++ else { ++ last_tv.tv_sec--; ++ last_tv.tv_usec += 1000000 - ++ TIME_CONST; ++ } ++ } ++ last_intr_tv = curr_tv; ++ if (data) { ++ /* ++ * start timer for end of ++ * sequence detection ++ */ ++ timerlist.expires = ++ jiffies + IT87_TIMEOUT; ++ add_timer(&timerlist); ++ } ++ outb((inb(io + IT87_CIR_RCR) & ++ ~IT87_CIR_RCR_RXEN) | ++ IT87_CIR_RCR_RXACT, ++ io + IT87_CIR_RCR); ++ if (it87_RXEN_mask) ++ outb(inb(io + IT87_CIR_RCR) | ++ IT87_CIR_RCR_RXEN, ++ io + IT87_CIR_RCR); ++ fifo--; ++ } while (fifo != 0); ++ } ++ spin_unlock_irqrestore(&hardware_lock, hw_flags); ++ spin_unlock_irqrestore(&timer_lock, flags); ++ ++ return IRQ_RETVAL(IRQ_HANDLED); ++ ++ default: ++ /* not our irq */ ++ dprintk("unknown IRQ (shouldn't happen) !!\n"); ++ return IRQ_RETVAL(IRQ_NONE); ++ } ++} ++ ++ ++static void send_it87(unsigned long len, unsigned long stime, ++ unsigned char send_byte, unsigned int count_bits) ++{ ++ long count = len / stime; ++ long time_left = 0; ++ static unsigned char byte_out; ++ unsigned long hw_flags; ++ ++ dprintk("%s: len=%ld, sb=%d\n", __func__, len, send_byte); ++ ++ time_left = (long)len - (long)count * (long)stime; ++ count += ((2 * time_left) / stime); ++ while (count) { ++ long i = 0; ++ for (i = 0; i < count_bits; i++) { ++ byte_out = (byte_out << 1) | (send_byte & 1); ++ it87_bits_in_byte_out++; ++ } ++ if (it87_bits_in_byte_out == 8) { ++ dprintk("out=0x%x, tsr_txfbc: 0x%x\n", ++ byte_out, ++ inb(io + IT87_CIR_TSR) & ++ IT87_CIR_TSR_TXFBC); ++ ++ while ((inb(io + IT87_CIR_TSR) & ++ IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE) ++ ; ++ ++ spin_lock_irqsave(&hardware_lock, hw_flags); ++ outb(byte_out, io + IT87_CIR_DR); ++ spin_unlock_irqrestore(&hardware_lock, hw_flags); ++ ++ it87_bits_in_byte_out = 0; ++ it87_send_counter++; ++ byte_out = 0; ++ } ++ count--; ++ } ++} ++ ++ ++/*TODO: maybe exchange space and pulse because it8705 only modulates 0-bits */ ++ ++static void send_space(unsigned long len) ++{ ++ send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR); ++} ++ ++static void send_pulse(unsigned long len) ++{ ++ send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR); ++} ++ ++ ++static void init_send() ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hardware_lock, flags); ++ /* RXEN=0: receiver disable */ ++ it87_RXEN_mask = 0; ++ outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN, ++ io + IT87_CIR_RCR); ++ spin_unlock_irqrestore(&hardware_lock, flags); ++ it87_bits_in_byte_out = 0; ++ it87_send_counter = 0; ++} ++ ++ ++static void terminate_send(unsigned long len) ++{ ++ unsigned long flags; ++ unsigned long last = 0; ++ ++ last = it87_send_counter; ++ /* make sure all necessary data has been sent */ ++ while (last == it87_send_counter) ++ send_space(len); ++ /* wait until all data sent */ ++ while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0) ++ ; ++ /* then re-enable receiver */ ++ spin_lock_irqsave(&hardware_lock, flags); ++ it87_RXEN_mask = IT87_CIR_RCR_RXEN; ++ outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, ++ io + IT87_CIR_RCR); ++ spin_unlock_irqrestore(&hardware_lock, flags); ++} ++ ++ ++static int init_hardware(void) ++{ ++ unsigned long flags; ++ unsigned char it87_rcr = 0; ++ ++ spin_lock_irqsave(&hardware_lock, flags); ++ /* init cir-port */ ++ /* enable r/w-access to Baudrate-Register */ ++ outb(IT87_CIR_IER_BR, io + IT87_CIR_IER); ++ outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR); ++ outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR); ++ /* Baudrate Register off, define IRQs: Input only */ ++ if (digimatrix) { ++ outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER); ++ /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */ ++ } else { ++ outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER); ++ /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */ ++ } ++ it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1; ++ if (it87_enable_demodulator) ++ it87_rcr |= IT87_CIR_RCR_RXEND; ++ outb(it87_rcr, io + IT87_CIR_RCR); ++ if (digimatrix) { ++ /* Set FIFO depth to 1 byte, and disable TX */ ++ outb(inb(io + IT87_CIR_TCR1) | 0x00, ++ io + IT87_CIR_TCR1); ++ ++ /* ++ * TX: it87_freq (36kHz), 'reserved' sensitivity ++ * setting (0x00) ++ */ ++ outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00, ++ io + IT87_CIR_TCR2); ++ } else { ++ /* TX: 38kHz, 13,3us (pulse-width) */ ++ outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06, ++ io + IT87_CIR_TCR2); ++ } ++ spin_unlock_irqrestore(&hardware_lock, flags); ++ return 0; ++} ++ ++ ++static void drop_hardware(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hardware_lock, flags); ++ disable_irq(irq); ++ /* receiver disable */ ++ it87_RXEN_mask = 0; ++ outb(0x1, io + IT87_CIR_RCR); ++ /* turn off irqs */ ++ outb(0, io + IT87_CIR_IER); ++ /* fifo clear */ ++ outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1); ++ /* reset */ ++ outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); ++ enable_irq(irq); ++ spin_unlock_irqrestore(&hardware_lock, flags); ++} ++ ++ ++static unsigned char it87_read(unsigned char port) ++{ ++ outb(port, IT87_ADRPORT); ++ return inb(IT87_DATAPORT); ++} ++ ++ ++static void it87_write(unsigned char port, unsigned char data) ++{ ++ outb(port, IT87_ADRPORT); ++ outb(data, IT87_DATAPORT); ++} ++ ++ ++/* SECTION: Initialisation */ ++ ++static int init_port(void) ++{ ++ unsigned long hw_flags; ++ int retval = 0; ++ ++ unsigned char init_bytes[4] = IT87_INIT; ++ unsigned char it87_chipid = 0; ++ unsigned char ldn = 0; ++ unsigned int it87_io = 0; ++ unsigned int it87_irq = 0; ++ ++ /* Enter MB PnP Mode */ ++ outb(init_bytes[0], IT87_ADRPORT); ++ outb(init_bytes[1], IT87_ADRPORT); ++ outb(init_bytes[2], IT87_ADRPORT); ++ outb(init_bytes[3], IT87_ADRPORT); ++ ++ /* 8712 or 8705 ? */ ++ it87_chipid = it87_read(IT87_CHIP_ID1); ++ if (it87_chipid != 0x87) { ++ retval = -ENXIO; ++ return retval; ++ } ++ it87_chipid = it87_read(IT87_CHIP_ID2); ++ if ((it87_chipid != 0x05) && ++ (it87_chipid != 0x12) && ++ (it87_chipid != 0x18) && ++ (it87_chipid != 0x20)) { ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": no IT8704/05/12/18/20 found (claimed IT87%02x), " ++ "exiting..\n", it87_chipid); ++ retval = -ENXIO; ++ return retval; ++ } ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": found IT87%02x.\n", ++ it87_chipid); ++ ++ /* get I/O-Port and IRQ */ ++ if (it87_chipid == 0x12 || it87_chipid == 0x18) ++ ldn = IT8712_CIR_LDN; ++ else ++ ldn = IT8705_CIR_LDN; ++ it87_write(IT87_LDN, ldn); ++ ++ it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 + ++ it87_read(IT87_CIR_BASE_LSB); ++ if (it87_io == 0) { ++ if (io == 0) ++ io = IT87_CIR_DEFAULT_IOBASE; ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": set default io 0x%x\n", ++ io); ++ it87_write(IT87_CIR_BASE_MSB, io / 0x100); ++ it87_write(IT87_CIR_BASE_LSB, io % 0x100); ++ } else ++ io = it87_io; ++ ++ it87_irq = it87_read(IT87_CIR_IRQ); ++ if (digimatrix || it87_irq == 0) { ++ if (irq == 0) ++ irq = IT87_CIR_DEFAULT_IRQ; ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": set default irq 0x%x\n", ++ irq); ++ it87_write(IT87_CIR_IRQ, irq); ++ } else ++ irq = it87_irq; ++ ++ spin_lock_irqsave(&hardware_lock, hw_flags); ++ /* reset */ ++ outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); ++ /* fifo clear */ ++ outb(IT87_CIR_TCR1_FIFOCLR | ++ /* IT87_CIR_TCR1_ILE | */ ++ IT87_CIR_TCR1_TXRLE | ++ IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1); ++ spin_unlock_irqrestore(&hardware_lock, hw_flags); ++ ++ /* get I/O port access and IRQ line */ ++ if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": i/o port 0x%.4x already in use.\n", io); ++ /* Leaving MB PnP Mode */ ++ it87_write(IT87_CFGCTRL, 0x2); ++ return -EBUSY; ++ } ++ ++ /* activate CIR-Device */ ++ it87_write(IT87_CIR_ACT, 0x1); ++ ++ /* Leaving MB PnP Mode */ ++ it87_write(IT87_CFGCTRL, 0x2); ++ ++ retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/, ++ LIRC_DRIVER_NAME, NULL); ++ if (retval < 0) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": IRQ %d already in use.\n", ++ irq); ++ release_region(io, 8); ++ return retval; ++ } ++ ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": I/O port 0x%.4x, IRQ %d.\n", io, irq); ++ ++ init_timer(&timerlist); ++ timerlist.function = it87_timeout; ++ timerlist.data = 0xabadcafe; ++ ++ return 0; ++} ++ ++ ++static void drop_port(void) ++{ ++#if 0 ++ unsigned char init_bytes[4] = IT87_INIT; ++ ++ /* Enter MB PnP Mode */ ++ outb(init_bytes[0], IT87_ADRPORT); ++ outb(init_bytes[1], IT87_ADRPORT); ++ outb(init_bytes[2], IT87_ADRPORT); ++ outb(init_bytes[3], IT87_ADRPORT); ++ ++ /* deactivate CIR-Device */ ++ it87_write(IT87_CIR_ACT, 0x0); ++ ++ /* Leaving MB PnP Mode */ ++ it87_write(IT87_CFGCTRL, 0x2); ++#endif ++ ++ del_timer_sync(&timerlist); ++ free_irq(irq, NULL); ++ release_region(io, 8); ++} ++ ++ ++static int init_lirc_it87(void) ++{ ++ int retval; ++ ++ init_waitqueue_head(&lirc_read_queue); ++ retval = init_port(); ++ if (retval < 0) ++ return retval; ++ init_hardware(); ++ printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n"); ++ return 0; ++} ++ ++static int it87_probe(struct pnp_dev *pnp_dev, ++ const struct pnp_device_id *dev_id) ++{ ++ int retval; ++ ++ driver.dev = &pnp_dev->dev; ++ ++ retval = init_chrdev(); ++ if (retval < 0) ++ return retval; ++ ++ retval = init_lirc_it87(); ++ if (retval) ++ goto init_lirc_it87_failed; ++ ++ return 0; ++ ++init_lirc_it87_failed: ++ drop_chrdev(); ++ ++ return retval; ++} ++ ++static int __init lirc_it87_init(void) ++{ ++ return pnp_register_driver(&it87_pnp_driver); ++} ++ ++ ++static void __exit lirc_it87_exit(void) ++{ ++ drop_hardware(); ++ drop_chrdev(); ++ drop_port(); ++ pnp_unregister_driver(&it87_pnp_driver); ++ printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); ++} ++ ++/* SECTION: PNP for ITE8704/18 */ ++ ++static const struct pnp_device_id pnp_dev_table[] = { ++ {"ITE8704", 0}, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(pnp, pnp_dev_table); ++ ++static struct pnp_driver it87_pnp_driver = { ++ .name = LIRC_DRIVER_NAME, ++ .id_table = pnp_dev_table, ++ .probe = it87_probe, ++}; ++ ++module_init(lirc_it87_init); ++module_exit(lirc_it87_exit); ++ ++MODULE_DESCRIPTION("LIRC driver for ITE IT8704/05/12/18/20 CIR port"); ++MODULE_AUTHOR("Hans-Gunter Lutke Uphues"); ++MODULE_LICENSE("GPL"); ++ ++module_param(io, int, S_IRUGO); ++MODULE_PARM_DESC(io, "I/O base address (default: 0x310)"); ++ ++module_param(irq, int, S_IRUGO); ++#ifdef LIRC_IT87_DIGIMATRIX ++MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)"); ++#else ++MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)"); ++#endif ++ ++module_param(it87_enable_demodulator, bool, S_IRUGO); ++MODULE_PARM_DESC(it87_enable_demodulator, ++ "Receiver demodulator enable/disable (1/0), default: 0"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); ++ ++module_param(digimatrix, bool, S_IRUGO | S_IWUSR); ++#ifdef LIRC_IT87_DIGIMATRIX ++MODULE_PARM_DESC(digimatrix, ++ "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1"); ++#else ++MODULE_PARM_DESC(digimatrix, ++ "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0"); ++#endif ++ ++ ++module_param(it87_freq, int, S_IRUGO); ++#ifdef LIRC_IT87_DIGIMATRIX ++MODULE_PARM_DESC(it87_freq, ++ "Carrier demodulator frequency (kHz), (default: 36)"); ++#else ++MODULE_PARM_DESC(it87_freq, ++ "Carrier demodulator frequency (kHz), (default: 38)"); ++#endif +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_it87.h linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_it87.h +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_it87.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_it87.h 2010-08-02 09:28:03.948926690 +0200 +@@ -0,0 +1,116 @@ ++/* lirc_it87.h */ ++/* SECTION: Definitions */ ++ ++/********************************* ITE IT87xx ************************/ ++ ++/* based on the following documentation from ITE: ++ a) IT8712F Preliminary CIR Programming Guide V0.1 ++ b) IT8705F Simple LPC I/O Preliminary Specification V0.3 ++ c) IT8712F EC-LPC I/O Preliminary Specification V0.5 ++*/ ++ ++/* IT8712/05 Ports: */ ++#define IT87_ADRPORT 0x2e ++#define IT87_DATAPORT 0x2f ++#define IT87_INIT {0x87, 0x01, 0x55, 0x55} ++ ++/* alternate Ports: */ ++/* ++#define IT87_ADRPORT 0x4e ++#define IT87_DATAPORT 0x4f ++#define IT87_INIT {0x87, 0x01, 0x55, 0xaa} ++ */ ++ ++/* IT8712/05 Registers */ ++#define IT87_CFGCTRL 0x2 ++#define IT87_LDN 0x7 ++#define IT87_CHIP_ID1 0x20 ++#define IT87_CHIP_ID2 0x21 ++#define IT87_CFG_VERSION 0x22 ++#define IT87_SWSUSPEND 0x23 ++ ++#define IT8712_CIR_LDN 0xa ++#define IT8705_CIR_LDN 0x7 ++ ++/* CIR Configuration Registers: */ ++#define IT87_CIR_ACT 0x30 ++#define IT87_CIR_BASE_MSB 0x60 ++#define IT87_CIR_BASE_LSB 0x61 ++#define IT87_CIR_IRQ 0x70 ++#define IT87_CIR_CONFIG 0xf0 ++ ++/* List of IT87_CIR registers: offset to BaseAddr */ ++#define IT87_CIR_DR 0 ++#define IT87_CIR_IER 1 ++#define IT87_CIR_RCR 2 ++#define IT87_CIR_TCR1 3 ++#define IT87_CIR_TCR2 4 ++#define IT87_CIR_TSR 5 ++#define IT87_CIR_RSR 6 ++#define IT87_CIR_BDLR 5 ++#define IT87_CIR_BDHR 6 ++#define IT87_CIR_IIR 7 ++ ++/* Bit Definition */ ++/* IER: */ ++#define IT87_CIR_IER_TM_EN 0x80 ++#define IT87_CIR_IER_RESEVED 0x40 ++#define IT87_CIR_IER_RESET 0x20 ++#define IT87_CIR_IER_BR 0x10 ++#define IT87_CIR_IER_IEC 0x8 ++#define IT87_CIR_IER_RFOIE 0x4 ++#define IT87_CIR_IER_RDAIE 0x2 ++#define IT87_CIR_IER_TLDLIE 0x1 ++ ++/* RCR: */ ++#define IT87_CIR_RCR_RDWOS 0x80 ++#define IT87_CIR_RCR_HCFS 0x40 ++#define IT87_CIR_RCR_RXEN 0x20 ++#define IT87_CIR_RCR_RXEND 0x10 ++#define IT87_CIR_RCR_RXACT 0x8 ++#define IT87_CIR_RCR_RXDCR 0x7 ++ ++/* TCR1: */ ++#define IT87_CIR_TCR1_FIFOCLR 0x80 ++#define IT87_CIR_TCR1_ILE 0x40 ++#define IT87_CIR_TCR1_FIFOTL 0x30 ++#define IT87_CIR_TCR1_TXRLE 0x8 ++#define IT87_CIR_TCR1_TXENDF 0x4 ++#define IT87_CIR_TCR1_TXMPM 0x3 ++ ++/* TCR2: */ ++#define IT87_CIR_TCR2_CFQ 0xf8 ++#define IT87_CIR_TCR2_TXMPW 0x7 ++ ++/* TSR: */ ++#define IT87_CIR_TSR_RESERVED 0xc0 ++#define IT87_CIR_TSR_TXFBC 0x3f ++ ++/* RSR: */ ++#define IT87_CIR_RSR_RXFTO 0x80 ++#define IT87_CIR_RSR_RESERVED 0x40 ++#define IT87_CIR_RSR_RXFBC 0x3f ++ ++/* IIR: */ ++#define IT87_CIR_IIR_RESERVED 0xf8 ++#define IT87_CIR_IIR_IID 0x6 ++#define IT87_CIR_IIR_IIP 0x1 ++ ++/* TM: */ ++#define IT87_CIR_TM_IL_SEL 0x80 ++#define IT87_CIR_TM_RESERVED 0x40 ++#define IT87_CIR_TM_TM_REG 0x3f ++ ++#define IT87_CIR_FIFO_SIZE 32 ++ ++/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */ ++#define IT87_CIR_BAUDRATE_DIVISOR 0x1 ++#define IT87_CIR_DEFAULT_IOBASE 0x310 ++#define IT87_CIR_DEFAULT_IRQ 0x7 ++#define IT87_CIR_SPACE 0x00 ++#define IT87_CIR_PULSE 0xff ++#define IT87_CIR_FREQ_MIN 27 ++#define IT87_CIR_FREQ_MAX 58 ++#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul) ++ ++/********************************* ITE IT87xx ************************/ +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_ite8709.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ite8709.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_ite8709.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ite8709.c 2010-08-02 09:28:03.950926583 +0200 +@@ -0,0 +1,540 @@ ++/* ++ * LIRC driver for ITE8709 CIR port ++ * ++ * Copyright (C) 2008 Grégory Lardière ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ * USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++#define LIRC_DRIVER_NAME "lirc_ite8709" ++ ++#define BUF_CHUNK_SIZE sizeof(int) ++#define BUF_SIZE (128*BUF_CHUNK_SIZE) ++ ++/* ++ * The ITE8709 device seems to be the combination of IT8512 superIO chip and ++ * a specific firmware running on the IT8512's embedded micro-controller. ++ * In addition of the embedded micro-controller, the IT8512 chip contains a ++ * CIR module and several other modules. A few modules are directly accessible ++ * by the host CPU, but most of them are only accessible by the ++ * micro-controller. The CIR module is only accessible by the micro-controller. ++ * The battery-backed SRAM module is accessible by the host CPU and the ++ * micro-controller. So one of the MC's firmware role is to act as a bridge ++ * between the host CPU and the CIR module. The firmware implements a kind of ++ * communication protocol using the SRAM module as a shared memory. The IT8512 ++ * specification is publicly available on ITE's web site, but the communication ++ * protocol is not, so it was reverse-engineered. ++ */ ++ ++/* ITE8709 Registers addresses and values (reverse-engineered) */ ++#define ITE8709_MODE 0x1a ++#define ITE8709_REG_ADR 0x1b ++#define ITE8709_REG_VAL 0x1c ++#define ITE8709_IIR 0x1e /* Interrupt identification register */ ++#define ITE8709_RFSR 0x1f /* Receiver FIFO status register */ ++#define ITE8709_FIFO_START 0x20 ++ ++#define ITE8709_MODE_READY 0X00 ++#define ITE8709_MODE_WRITE 0X01 ++#define ITE8709_MODE_READ 0X02 ++#define ITE8709_IIR_RDAI 0x02 /* Receiver data available interrupt */ ++#define ITE8709_IIR_RFOI 0x04 /* Receiver FIFO overrun interrupt */ ++#define ITE8709_RFSR_MASK 0x3f /* FIFO byte count mask */ ++ ++/* ++ * IT8512 CIR-module registers addresses and values ++ * (from IT8512 E/F specification v0.4.1) ++ */ ++#define IT8512_REG_MSTCR 0x01 /* Master control register */ ++#define IT8512_REG_IER 0x02 /* Interrupt enable register */ ++#define IT8512_REG_CFR 0x04 /* Carrier frequency register */ ++#define IT8512_REG_RCR 0x05 /* Receive control register */ ++#define IT8512_REG_BDLR 0x08 /* Baud rate divisor low byte register */ ++#define IT8512_REG_BDHR 0x09 /* Baud rate divisor high byte register */ ++ ++#define IT8512_MSTCR_RESET 0x01 /* Reset registers to default value */ ++#define IT8512_MSTCR_FIFOCLR 0x02 /* Clear FIFO */ ++#define IT8512_MSTCR_FIFOTL_7 0x04 /* FIFO threshold level : 7 */ ++#define IT8512_MSTCR_FIFOTL_25 0x0c /* FIFO threshold level : 25 */ ++#define IT8512_IER_RDAIE 0x02 /* Enable data interrupt request */ ++#define IT8512_IER_RFOIE 0x04 /* Enable FIFO overrun interrupt req */ ++#define IT8512_IER_IEC 0x80 /* Enable interrupt request */ ++#define IT8512_CFR_CF_36KHZ 0x09 /* Carrier freq : low speed, 36kHz */ ++#define IT8512_RCR_RXDCR_1 0x01 /* Demodulation carrier range : 1 */ ++#define IT8512_RCR_RXACT 0x08 /* Receiver active */ ++#define IT8512_RCR_RXEN 0x80 /* Receiver enable */ ++#define IT8512_BDR_6 6 /* Baud rate divisor : 6 */ ++ ++/* Actual values used by this driver */ ++#define CFG_FIFOTL IT8512_MSTCR_FIFOTL_25 ++#define CFG_CR_FREQ IT8512_CFR_CF_36KHZ ++#define CFG_DCR IT8512_RCR_RXDCR_1 ++#define CFG_BDR IT8512_BDR_6 ++#define CFG_TIMEOUT 100000 /* Rearm interrupt when a space is > 100 ms */ ++ ++static int debug; ++ ++struct ite8709_device { ++ int use_count; ++ int io; ++ int irq; ++ spinlock_t hardware_lock; ++ unsigned long long acc_pulse; ++ unsigned long long acc_space; ++ char lastbit; ++ struct timeval last_tv; ++ struct lirc_driver driver; ++ struct tasklet_struct tasklet; ++ char force_rearm; ++ char rearmed; ++ char device_busy; ++}; ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ ++ fmt, ## args); \ ++ } while (0) ++ ++ ++static unsigned char ite8709_read(struct ite8709_device *dev, ++ unsigned char port) ++{ ++ outb(port, dev->io); ++ return inb(dev->io+1); ++} ++ ++static void ite8709_write(struct ite8709_device *dev, unsigned char port, ++ unsigned char data) ++{ ++ outb(port, dev->io); ++ outb(data, dev->io+1); ++} ++ ++static void ite8709_wait_device(struct ite8709_device *dev) ++{ ++ int i = 0; ++ /* ++ * loop until device tells it's ready to continue ++ * iterations count is usually ~750 but can sometimes achieve 13000 ++ */ ++ for (i = 0; i < 15000; i++) { ++ udelay(2); ++ if (ite8709_read(dev, ITE8709_MODE) == ITE8709_MODE_READY) ++ break; ++ } ++} ++ ++static void ite8709_write_register(struct ite8709_device *dev, ++ unsigned char reg_adr, unsigned char reg_value) ++{ ++ ite8709_wait_device(dev); ++ ++ ite8709_write(dev, ITE8709_REG_VAL, reg_value); ++ ite8709_write(dev, ITE8709_REG_ADR, reg_adr); ++ ite8709_write(dev, ITE8709_MODE, ITE8709_MODE_WRITE); ++} ++ ++static void ite8709_init_hardware(struct ite8709_device *dev) ++{ ++ spin_lock_irq(&dev->hardware_lock); ++ dev->device_busy = 1; ++ spin_unlock_irq(&dev->hardware_lock); ++ ++ ite8709_write_register(dev, IT8512_REG_BDHR, (CFG_BDR >> 8) & 0xff); ++ ite8709_write_register(dev, IT8512_REG_BDLR, CFG_BDR & 0xff); ++ ite8709_write_register(dev, IT8512_REG_CFR, CFG_CR_FREQ); ++ ite8709_write_register(dev, IT8512_REG_IER, ++ IT8512_IER_IEC | IT8512_IER_RFOIE | IT8512_IER_RDAIE); ++ ite8709_write_register(dev, IT8512_REG_RCR, CFG_DCR); ++ ite8709_write_register(dev, IT8512_REG_MSTCR, ++ CFG_FIFOTL | IT8512_MSTCR_FIFOCLR); ++ ite8709_write_register(dev, IT8512_REG_RCR, ++ IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR); ++ ++ spin_lock_irq(&dev->hardware_lock); ++ dev->device_busy = 0; ++ spin_unlock_irq(&dev->hardware_lock); ++ ++ tasklet_enable(&dev->tasklet); ++} ++ ++static void ite8709_drop_hardware(struct ite8709_device *dev) ++{ ++ tasklet_disable(&dev->tasklet); ++ ++ spin_lock_irq(&dev->hardware_lock); ++ dev->device_busy = 1; ++ spin_unlock_irq(&dev->hardware_lock); ++ ++ ite8709_write_register(dev, IT8512_REG_RCR, 0); ++ ite8709_write_register(dev, IT8512_REG_MSTCR, ++ IT8512_MSTCR_RESET | IT8512_MSTCR_FIFOCLR); ++ ++ spin_lock_irq(&dev->hardware_lock); ++ dev->device_busy = 0; ++ spin_unlock_irq(&dev->hardware_lock); ++} ++ ++static int ite8709_set_use_inc(void *data) ++{ ++ struct ite8709_device *dev; ++ dev = data; ++ if (dev->use_count == 0) ++ ite8709_init_hardware(dev); ++ dev->use_count++; ++ return 0; ++} ++ ++static void ite8709_set_use_dec(void *data) ++{ ++ struct ite8709_device *dev; ++ dev = data; ++ dev->use_count--; ++ if (dev->use_count == 0) ++ ite8709_drop_hardware(dev); ++} ++ ++static void ite8709_add_read_queue(struct ite8709_device *dev, int flag, ++ unsigned long long val) ++{ ++ int value; ++ ++ dprintk("add a %llu usec %s\n", val, flag ? "pulse" : "space"); ++ ++ value = (val > PULSE_MASK) ? PULSE_MASK : val; ++ if (flag) ++ value |= PULSE_BIT; ++ ++ if (!lirc_buffer_full(dev->driver.rbuf)) { ++ lirc_buffer_write(dev->driver.rbuf, (void *) &value); ++ wake_up(&dev->driver.rbuf->wait_poll); ++ } ++} ++ ++static irqreturn_t ite8709_interrupt(int irq, void *dev_id) ++{ ++ unsigned char data; ++ int iir, rfsr, i; ++ int fifo = 0; ++ char bit; ++ struct timeval curr_tv; ++ ++ /* Bit duration in microseconds */ ++ const unsigned long bit_duration = 1000000ul / (115200 / CFG_BDR); ++ ++ struct ite8709_device *dev; ++ dev = dev_id; ++ ++ /* ++ * If device is busy, we simply discard data because we are in one of ++ * these two cases : shutting down or rearming the device, so this ++ * doesn't really matter and this avoids waiting too long in IRQ ctx ++ */ ++ spin_lock(&dev->hardware_lock); ++ if (dev->device_busy) { ++ spin_unlock(&dev->hardware_lock); ++ return IRQ_RETVAL(IRQ_HANDLED); ++ } ++ ++ iir = ite8709_read(dev, ITE8709_IIR); ++ ++ switch (iir) { ++ case ITE8709_IIR_RFOI: ++ dprintk("fifo overrun, scheduling forced rearm just in case\n"); ++ dev->force_rearm = 1; ++ tasklet_schedule(&dev->tasklet); ++ spin_unlock(&dev->hardware_lock); ++ return IRQ_RETVAL(IRQ_HANDLED); ++ ++ case ITE8709_IIR_RDAI: ++ rfsr = ite8709_read(dev, ITE8709_RFSR); ++ fifo = rfsr & ITE8709_RFSR_MASK; ++ if (fifo > 32) ++ fifo = 32; ++ dprintk("iir: 0x%x rfsr: 0x%x fifo: %d\n", iir, rfsr, fifo); ++ ++ if (dev->rearmed) { ++ do_gettimeofday(&curr_tv); ++ dev->acc_space += 1000000ull ++ * (curr_tv.tv_sec - dev->last_tv.tv_sec) ++ + (curr_tv.tv_usec - dev->last_tv.tv_usec); ++ dev->rearmed = 0; ++ } ++ for (i = 0; i < fifo; i++) { ++ data = ite8709_read(dev, i+ITE8709_FIFO_START); ++ data = ~data; ++ /* Loop through */ ++ for (bit = 0; bit < 8; ++bit) { ++ if ((data >> bit) & 1) { ++ dev->acc_pulse += bit_duration; ++ if (dev->lastbit == 0) { ++ ite8709_add_read_queue(dev, 0, ++ dev->acc_space); ++ dev->acc_space = 0; ++ } ++ } else { ++ dev->acc_space += bit_duration; ++ if (dev->lastbit == 1) { ++ ite8709_add_read_queue(dev, 1, ++ dev->acc_pulse); ++ dev->acc_pulse = 0; ++ } ++ } ++ dev->lastbit = (data >> bit) & 1; ++ } ++ } ++ ite8709_write(dev, ITE8709_RFSR, 0); ++ ++ if (dev->acc_space > CFG_TIMEOUT) { ++ dprintk("scheduling rearm IRQ\n"); ++ do_gettimeofday(&dev->last_tv); ++ dev->force_rearm = 0; ++ tasklet_schedule(&dev->tasklet); ++ } ++ ++ spin_unlock(&dev->hardware_lock); ++ return IRQ_RETVAL(IRQ_HANDLED); ++ ++ default: ++ /* not our irq */ ++ dprintk("unknown IRQ (shouldn't happen) !!\n"); ++ spin_unlock(&dev->hardware_lock); ++ return IRQ_RETVAL(IRQ_NONE); ++ } ++} ++ ++static void ite8709_rearm_irq(unsigned long data) ++{ ++ struct ite8709_device *dev; ++ unsigned long flags; ++ dev = (struct ite8709_device *) data; ++ ++ spin_lock_irqsave(&dev->hardware_lock, flags); ++ dev->device_busy = 1; ++ spin_unlock_irqrestore(&dev->hardware_lock, flags); ++ ++ if (dev->force_rearm || dev->acc_space > CFG_TIMEOUT) { ++ dprintk("rearming IRQ\n"); ++ ite8709_write_register(dev, IT8512_REG_RCR, ++ IT8512_RCR_RXACT | CFG_DCR); ++ ite8709_write_register(dev, IT8512_REG_MSTCR, ++ CFG_FIFOTL | IT8512_MSTCR_FIFOCLR); ++ ite8709_write_register(dev, IT8512_REG_RCR, ++ IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR); ++ if (!dev->force_rearm) ++ dev->rearmed = 1; ++ dev->force_rearm = 0; ++ } ++ ++ spin_lock_irqsave(&dev->hardware_lock, flags); ++ dev->device_busy = 0; ++ spin_unlock_irqrestore(&dev->hardware_lock, flags); ++} ++ ++static int ite8709_cleanup(struct ite8709_device *dev, int stage, int errno, ++ char *msg) ++{ ++ if (msg != NULL) ++ printk(KERN_ERR LIRC_DRIVER_NAME ": %s\n", msg); ++ ++ switch (stage) { ++ case 6: ++ if (dev->use_count > 0) ++ ite8709_drop_hardware(dev); ++ case 5: ++ free_irq(dev->irq, dev); ++ case 4: ++ release_region(dev->io, 2); ++ case 3: ++ lirc_unregister_driver(dev->driver.minor); ++ case 2: ++ lirc_buffer_free(dev->driver.rbuf); ++ kfree(dev->driver.rbuf); ++ case 1: ++ kfree(dev); ++ case 0: ++ ; ++ } ++ ++ return errno; ++} ++ ++static int __devinit ite8709_pnp_probe(struct pnp_dev *dev, ++ const struct pnp_device_id *dev_id) ++{ ++ struct lirc_driver *driver; ++ struct ite8709_device *ite8709_dev; ++ int ret; ++ ++ /* Check resources validity */ ++ if (!pnp_irq_valid(dev, 0)) ++ return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IRQ"); ++ if (!pnp_port_valid(dev, 2)) ++ return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IO port"); ++ ++ /* Allocate memory for device struct */ ++ ite8709_dev = kzalloc(sizeof(struct ite8709_device), GFP_KERNEL); ++ if (ite8709_dev == NULL) ++ return ite8709_cleanup(NULL, 0, -ENOMEM, "kzalloc failed"); ++ pnp_set_drvdata(dev, ite8709_dev); ++ ++ /* Initialize device struct */ ++ ite8709_dev->use_count = 0; ++ ite8709_dev->irq = pnp_irq(dev, 0); ++ ite8709_dev->io = pnp_port_start(dev, 2); ++ ite8709_dev->hardware_lock = ++ __SPIN_LOCK_UNLOCKED(ite8709_dev->hardware_lock); ++ ite8709_dev->acc_pulse = 0; ++ ite8709_dev->acc_space = 0; ++ ite8709_dev->lastbit = 0; ++ do_gettimeofday(&ite8709_dev->last_tv); ++ tasklet_init(&ite8709_dev->tasklet, ite8709_rearm_irq, ++ (long) ite8709_dev); ++ ite8709_dev->force_rearm = 0; ++ ite8709_dev->rearmed = 0; ++ ite8709_dev->device_busy = 0; ++ ++ /* Initialize driver struct */ ++ driver = &ite8709_dev->driver; ++ strcpy(driver->name, LIRC_DRIVER_NAME); ++ driver->minor = -1; ++ driver->code_length = sizeof(int) * 8; ++ driver->sample_rate = 0; ++ driver->features = LIRC_CAN_REC_MODE2; ++ driver->data = ite8709_dev; ++ driver->add_to_buf = NULL; ++ driver->set_use_inc = ite8709_set_use_inc; ++ driver->set_use_dec = ite8709_set_use_dec; ++ driver->dev = &dev->dev; ++ driver->owner = THIS_MODULE; ++ ++ /* Initialize LIRC buffer */ ++ driver->rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!driver->rbuf) ++ return ite8709_cleanup(ite8709_dev, 1, -ENOMEM, ++ "can't allocate lirc_buffer"); ++ if (lirc_buffer_init(driver->rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) ++ return ite8709_cleanup(ite8709_dev, 1, -ENOMEM, ++ "lirc_buffer_init() failed"); ++ ++ /* Register LIRC driver */ ++ ret = lirc_register_driver(driver); ++ if (ret < 0) ++ return ite8709_cleanup(ite8709_dev, 2, ret, ++ "lirc_register_driver() failed"); ++ ++ /* Reserve I/O port access */ ++ if (!request_region(ite8709_dev->io, 2, LIRC_DRIVER_NAME)) ++ return ite8709_cleanup(ite8709_dev, 3, -EBUSY, ++ "i/o port already in use"); ++ ++ /* Reserve IRQ line */ ++ ret = request_irq(ite8709_dev->irq, ite8709_interrupt, 0, ++ LIRC_DRIVER_NAME, ite8709_dev); ++ if (ret < 0) ++ return ite8709_cleanup(ite8709_dev, 4, ret, ++ "IRQ already in use"); ++ ++ /* Initialize hardware */ ++ ite8709_drop_hardware(ite8709_dev); /* Shutdown hw until first use */ ++ ++ printk(KERN_INFO LIRC_DRIVER_NAME ": device found : irq=%d io=0x%x\n", ++ ite8709_dev->irq, ite8709_dev->io); ++ ++ return 0; ++} ++ ++static void __devexit ite8709_pnp_remove(struct pnp_dev *dev) ++{ ++ struct ite8709_device *ite8709_dev; ++ ite8709_dev = pnp_get_drvdata(dev); ++ ++ ite8709_cleanup(ite8709_dev, 6, 0, NULL); ++ ++ printk(KERN_INFO LIRC_DRIVER_NAME ": device removed\n"); ++} ++ ++#ifdef CONFIG_PM ++static int ite8709_pnp_suspend(struct pnp_dev *dev, pm_message_t state) ++{ ++ struct ite8709_device *ite8709_dev; ++ ite8709_dev = pnp_get_drvdata(dev); ++ ++ if (ite8709_dev->use_count > 0) ++ ite8709_drop_hardware(ite8709_dev); ++ ++ return 0; ++} ++ ++static int ite8709_pnp_resume(struct pnp_dev *dev) ++{ ++ struct ite8709_device *ite8709_dev; ++ ite8709_dev = pnp_get_drvdata(dev); ++ ++ if (ite8709_dev->use_count > 0) ++ ite8709_init_hardware(ite8709_dev); ++ ++ return 0; ++} ++#else ++#define ite8709_pnp_suspend NULL ++#define ite8709_pnp_resume NULL ++#endif ++ ++static const struct pnp_device_id pnp_dev_table[] = { ++ {"ITE8709", 0}, ++ {} ++}; ++ ++MODULE_DEVICE_TABLE(pnp, pnp_dev_table); ++ ++static struct pnp_driver ite8709_pnp_driver = { ++ .name = LIRC_DRIVER_NAME, ++ .probe = ite8709_pnp_probe, ++ .remove = __devexit_p(ite8709_pnp_remove), ++ .suspend = ite8709_pnp_suspend, ++ .resume = ite8709_pnp_resume, ++ .id_table = pnp_dev_table, ++}; ++ ++int init_module(void) ++{ ++ return pnp_register_driver(&ite8709_pnp_driver); ++} ++ ++void cleanup_module(void) ++{ ++ pnp_unregister_driver(&ite8709_pnp_driver); ++} ++ ++MODULE_DESCRIPTION("LIRC driver for ITE8709 CIR port"); ++MODULE_AUTHOR("Grégory Lardière"); ++MODULE_LICENSE("GPL"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_mceusb.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_mceusb.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_mceusb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_mceusb.c 2010-08-02 09:31:40.968050721 +0200 +@@ -0,0 +1,1385 @@ ++/* ++ * LIRC driver for Windows Media Center Edition USB Infrared Transceivers ++ * ++ * (C) by Martin A. Blatter ++ * ++ * Transmitter support and reception code cleanup. ++ * (C) by Daniel Melander ++ * ++ * Original lirc_mceusb driver for 1st-gen device: ++ * Copyright (c) 2003-2004 Dan Conti ++ * ++ * Original lirc_mceusb driver deprecated in favor of this driver, which ++ * supports the 1st-gen device now too. Transmit and receive support for ++ * the 1st-gen device added June-September 2009, ++ * by Jarod Wilson and Patrick Calhoun ++ * ++ * Derived from ATI USB driver by Paul Miller and the original ++ * MCE USB driver by Dan Conti (and now including chunks of the latter ++ * relevant to the 1st-gen device initialization) ++ * ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++#define DRIVER_VERSION "1.90" ++#define DRIVER_AUTHOR "Daniel Melander , " \ ++ "Martin Blatter , " \ ++ "Dan Conti " ++#define DRIVER_DESC "Windows Media Center Edition USB IR Transceiver " \ ++ "driver for LIRC" ++#define DRIVER_NAME "lirc_mceusb" ++ ++#define USB_BUFLEN 32 /* USB reception buffer length */ ++#define LIRCBUF_SIZE 256 /* LIRC work buffer length */ ++ ++/* MCE constants */ ++#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ ++#define MCE_TIME_UNIT 50 /* Approx 50us resolution */ ++#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ ++#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ ++#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ ++#define MCE_CONTROL_HEADER 0x9F /* MCE status header */ ++#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ ++#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ ++#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ ++#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ ++#define MCE_PULSE_MASK 0x7F /* Pulse mask */ ++#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ ++#define MCE_PACKET_LENGTH_MASK 0x7F /* Pulse mask */ ++ ++ ++/* module parameters */ ++#ifdef CONFIG_USB_DEBUG ++static int debug = 1; ++#else ++static int debug; ++#endif ++ ++/* general constants */ ++#define SEND_FLAG_IN_PROGRESS 1 ++#define SEND_FLAG_COMPLETE 2 ++#define RECV_FLAG_IN_PROGRESS 3 ++#define RECV_FLAG_COMPLETE 4 ++ ++#define MCEUSB_INBOUND 1 ++#define MCEUSB_OUTBOUND 2 ++ ++#define VENDOR_PHILIPS 0x0471 ++#define VENDOR_SMK 0x0609 ++#define VENDOR_TATUNG 0x1460 ++#define VENDOR_GATEWAY 0x107b ++#define VENDOR_SHUTTLE 0x1308 ++#define VENDOR_SHUTTLE2 0x051c ++#define VENDOR_MITSUMI 0x03ee ++#define VENDOR_TOPSEED 0x1784 ++#define VENDOR_RICAVISION 0x179d ++#define VENDOR_ITRON 0x195d ++#define VENDOR_FIC 0x1509 ++#define VENDOR_LG 0x043e ++#define VENDOR_MICROSOFT 0x045e ++#define VENDOR_FORMOSA 0x147a ++#define VENDOR_FINTEK 0x1934 ++#define VENDOR_PINNACLE 0x2304 ++#define VENDOR_ECS 0x1019 ++#define VENDOR_WISTRON 0x0fb8 ++#define VENDOR_COMPRO 0x185b ++#define VENDOR_NORTHSTAR 0x04eb ++#define VENDOR_REALTEK 0x0bda ++#define VENDOR_TIVO 0x105a ++ ++static struct usb_device_id mceusb_dev_table[] = { ++ /* Original Microsoft MCE IR Transceiver (often HP-branded) */ ++ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, ++ /* Philips Infrared Transceiver - Sahara branded */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x0608) }, ++ /* Philips Infrared Transceiver - HP branded */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, ++ /* Philips SRM5100 */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, ++ /* Philips Infrared Transceiver - Omaura */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x060f) }, ++ /* Philips Infrared Transceiver - Spinel plus */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x0613) }, ++ /* Philips eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, ++ /* Realtek MCE IR Receiver */ ++ { USB_DEVICE(VENDOR_REALTEK, 0x0161) }, ++ /* SMK/Toshiba G83C0004D410 */ ++ { USB_DEVICE(VENDOR_SMK, 0x031d) }, ++ /* SMK eHome Infrared Transceiver (Sony VAIO) */ ++ { USB_DEVICE(VENDOR_SMK, 0x0322) }, ++ /* bundled with Hauppauge PVR-150 */ ++ { USB_DEVICE(VENDOR_SMK, 0x0334) }, ++ /* SMK eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_SMK, 0x0338) }, ++ /* Tatung eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, ++ /* Shuttle eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) }, ++ /* Shuttle eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) }, ++ /* Gateway eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_GATEWAY, 0x3009) }, ++ /* Mitsumi */ ++ { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, ++ /* Topseed eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, ++ /* Topseed HP eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, ++ /* Topseed eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, ++ /* Topseed eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, ++ /* Topseed eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, ++ /* Topseed eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, ++ /* Ricavision internal Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, ++ /* Itron ione Libra Q-11 */ ++ { USB_DEVICE(VENDOR_ITRON, 0x7002) }, ++ /* FIC eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_FIC, 0x9242) }, ++ /* LG eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_LG, 0x9803) }, ++ /* Microsoft MCE Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) }, ++ /* Formosa eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, ++ /* Formosa21 / eHome Infrared Receiver */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe016) }, ++ /* Formosa aim / Trust MCE Infrared Receiver */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, ++ /* Formosa Industrial Computing / Beanbag Emulation Device */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, ++ /* Formosa21 / eHome Infrared Receiver */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) }, ++ /* Formosa Industrial Computing AIM IR605/A */ ++ { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, ++ /* Fintek eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, ++ /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ ++ { USB_DEVICE(VENDOR_FINTEK, 0x0702) }, ++ /* Pinnacle Remote Kit */ ++ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, ++ /* Elitegroup Computer Systems IR */ ++ { USB_DEVICE(VENDOR_ECS, 0x0f38) }, ++ /* Wistron Corp. eHome Infrared Receiver */ ++ { USB_DEVICE(VENDOR_WISTRON, 0x0002) }, ++ /* Compro K100 */ ++ { USB_DEVICE(VENDOR_COMPRO, 0x3020) }, ++ /* Compro K100 v2 */ ++ { USB_DEVICE(VENDOR_COMPRO, 0x3082) }, ++ /* Northstar Systems, Inc. eHome Infrared Transceiver */ ++ { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, ++ /* TiVo PC IR Receiver */ ++ { USB_DEVICE(VENDOR_TIVO, 0x2000) }, ++ /* Terminating entry */ ++ { } ++}; ++ ++static struct usb_device_id gen3_list[] = { ++ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, ++ {} ++}; ++ ++static struct usb_device_id pinnacle_list[] = { ++ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, ++ {} ++}; ++ ++static struct usb_device_id microsoft_gen1_list[] = { ++ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, ++ {} ++}; ++ ++static struct usb_device_id transmitter_mask_list[] = { ++ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) }, ++ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, ++ { USB_DEVICE(VENDOR_SMK, 0x031d) }, ++ { USB_DEVICE(VENDOR_SMK, 0x0322) }, ++ { USB_DEVICE(VENDOR_SMK, 0x0334) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) }, ++ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) }, ++ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) }, ++ {} ++}; ++ ++/* data structure for each usb transceiver */ ++struct mceusb_dev { ++ ++ /* usb */ ++ struct usb_device *usbdev; ++ struct urb *urb_in; ++ int devnum; ++ struct usb_endpoint_descriptor *usb_ep_in; ++ struct usb_endpoint_descriptor *usb_ep_out; ++ ++ /* buffers and dma */ ++ unsigned char *buf_in; ++ unsigned int len_in; ++ dma_addr_t dma_in; ++ dma_addr_t dma_out; ++ unsigned int overflow_len; ++ ++ /* lirc */ ++ struct lirc_driver *d; ++ int lircdata; ++ unsigned char is_pulse; ++ struct { ++ u32 connected:1; ++ u32 gen3:1; ++ u32 transmitter_mask_inverted:1; ++ u32 microsoft_gen1:1; ++ u32 reserved:28; ++ } flags; ++ ++ unsigned char transmitter_mask; ++ unsigned int carrier_freq; ++ ++ /* handle sending (init strings) */ ++ int send_flags; ++ wait_queue_head_t wait_out; ++ ++ struct mutex dev_lock; ++}; ++ ++/* ++ * MCE Device Command Strings ++ * Device command responses vary from device to device... ++ * - DEVICE_RESET resets the hardware to its default state ++ * - GET_REVISION fetches the hardware/software revision, common ++ * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42 ++ * - GET_CARRIER_FREQ gets the carrier mode and frequency of the ++ * device, with replies in the form of 9f 06 MM FF, where MM is 0-3, ++ * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is ++ * ((clk / frequency) - 1) ++ * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us, ++ * response in the form of 9f 0c msb lsb ++ * - GET_TX_BITMASK fetches the transmitter bitmask, replies in ++ * the form of 9f 08 bm, where bm is the bitmask ++ * - GET_RX_SENSOR fetches the RX sensor setting -- long-range ++ * general use one or short-range learning one, in the form of ++ * 9f 14 ss, where ss is either 01 for long-range or 02 for short ++ * - SET_CARRIER_FREQ sets a new carrier mode and frequency ++ * - SET_TX_BITMASK sets the transmitter bitmask ++ * - SET_RX_TIMEOUT sets the receiver timeout ++ * - SET_RX_SENSOR sets which receiver sensor to use ++ */ ++static char DEVICE_RESET[] = {0x00, 0xff, 0xaa}; ++static char GET_REVISION[] = {0xff, 0x0b}; ++static char GET_UNKNOWN[] = {0xff, 0x18}; ++static char GET_CARRIER_FREQ[] = {0x9f, 0x07}; ++static char GET_RX_TIMEOUT[] = {0x9f, 0x0d}; ++static char GET_TX_BITMASK[] = {0x9f, 0x13}; ++static char GET_RX_SENSOR[] = {0x9f, 0x15}; ++/* sub in desired values in lower byte or bytes for full command */ ++//static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00}; ++//static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00}; ++//static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00}; ++//static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00}; ++ ++static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, ++ int len, bool out) ++{ ++ char codes[USB_BUFLEN * 3 + 1]; ++ char inout[9]; ++ int i; ++ u8 cmd, subcmd, data1, data2; ++ struct device *dev = ir->d->dev; ++ ++ if (len <= 0) ++ return; ++ ++ if (ir->flags.microsoft_gen1 && len <= 2) ++ return; ++ ++ for (i = 0; i < len && i < USB_BUFLEN; i++) ++ snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF); ++ ++ dev_info(dev, "%sbound data: %s (length=%d)\n", ++ (out ? "out" : " in"), codes, len); ++ ++ if (out) ++ strcpy(inout, "Request\0"); ++ else ++ strcpy(inout, "Got\0"); ++ ++ cmd = buf[0] & 0xff; ++ subcmd = buf[1] & 0xff; ++ data1 = buf[2] & 0xff; ++ data2 = buf[3] & 0xff; ++ ++ switch (cmd) { ++ case 0x00: ++ if (subcmd == 0xff && data1 == 0xaa) ++ dev_info(dev, "Device reset requested\n"); ++ else ++ dev_info(dev, "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ case 0xff: ++ switch (subcmd) { ++ case 0x0b: ++ if (len == 2) ++ dev_info(dev, "Get hw/sw rev?\n"); ++ else ++ dev_info(dev, "hw/sw rev 0x%02x 0x%02x " ++ "0x%02x 0x%02x\n", data1, data2, ++ buf[4], buf[5]); ++ break; ++ case 0xaa: ++ dev_info(dev, "Device reset requested\n"); ++ break; ++ case 0xfe: ++ dev_info(dev, "Previous command not supported\n"); ++ break; ++ case 0x18: ++ case 0x1b: ++ default: ++ dev_info(dev, "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ } ++ break; ++ case 0x9f: ++ switch (subcmd) { ++ case 0x03: ++ dev_info(dev, "Ping\n"); ++ break; ++ case 0x04: ++ dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n", ++ data1, data2); ++ break; ++ case 0x06: ++ dev_info(dev, "%s carrier mode and freq of 0x%02x 0x%02x\n", ++ inout, data1, data2); ++ break; ++ case 0x07: ++ dev_info(dev, "Get carrier mode and freq\n"); ++ break; ++ case 0x08: ++ dev_info(dev, "%s transmit blaster mask of 0x%02x\n", ++ inout, data1); ++ break; ++ case 0x0c: ++ /* value is in units of 50us, so x*50/100 or x/2 ms */ ++ dev_info(dev, "%s receive timeout of %d ms\n", ++ inout, ((data1 << 8) | data2) / 2); ++ break; ++ case 0x0d: ++ dev_info(dev, "Get receive timeout\n"); ++ break; ++ case 0x13: ++ dev_info(dev, "Get transmit blaster mask\n"); ++ break; ++ case 0x14: ++ dev_info(dev, "%s %s-range receive sensor in use\n", ++ inout, data1 == 0x02 ? "short" : "long"); ++ break; ++ case 0x15: ++ if (len == 2) ++ dev_info(dev, "Get receive sensor\n"); ++ else ++ dev_info(dev, "Received pulse count is %d\n", ++ ((data1 << 8) | data2)); ++ break; ++ case 0xfe: ++ dev_info(dev, "Error! Hardware is likely wedged...\n"); ++ break; ++ case 0x05: ++ case 0x09: ++ case 0x0f: ++ default: ++ dev_info(dev, "Unknown command 0x%02x 0x%02x\n", ++ cmd, subcmd); ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++} ++ ++static void usb_async_callback(struct urb *urb, struct pt_regs *regs) ++{ ++ struct mceusb_dev *ir; ++ int len; ++ ++ if (!urb) ++ return; ++ ++ ir = urb->context; ++ if (ir) { ++ len = urb->actual_length; ++ ++ dev_dbg(ir->d->dev, "callback called (status=%d len=%d)\n", ++ urb->status, len); ++ ++ if (debug) ++ mceusb_dev_printdata(ir, urb->transfer_buffer, len, true); ++ } ++ ++} ++ ++/* request incoming or send outgoing usb packet - used to initialize remote */ ++static void mce_request_packet(struct mceusb_dev *ir, ++ struct usb_endpoint_descriptor *ep, ++ unsigned char *data, int size, int urb_type) ++{ ++ int res; ++ struct urb *async_urb; ++ unsigned char *async_buf; ++ ++ if (urb_type == MCEUSB_OUTBOUND) { ++ async_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (unlikely(!async_urb)) { ++ dev_err(ir->d->dev, "Error, couldn't allocate urb!\n"); ++ return; ++ } ++ ++ async_buf = kzalloc(size, GFP_KERNEL); ++ if (!async_buf) { ++ dev_err(ir->d->dev, "Error, couldn't allocate buf!\n"); ++ usb_free_urb(async_urb); ++ return; ++ } ++ ++ /* outbound data */ ++ usb_fill_int_urb(async_urb, ir->usbdev, ++ usb_sndintpipe(ir->usbdev, ep->bEndpointAddress), ++ async_buf, size, (usb_complete_t) usb_async_callback, ++ ir, ep->bInterval); ++ memcpy(async_buf, data, size); ++ ++ } else if (urb_type == MCEUSB_INBOUND) { ++ /* standard request */ ++ async_urb = ir->urb_in; ++ ir->send_flags = RECV_FLAG_IN_PROGRESS; ++ ++ } else { ++ dev_err(ir->d->dev, "Error! Unknown urb type %d\n", urb_type); ++ return; ++ } ++ ++ dev_dbg(ir->d->dev, "receive request called (size=%#x)\n", size); ++ ++ async_urb->transfer_buffer_length = size; ++ async_urb->dev = ir->usbdev; ++ ++ res = usb_submit_urb(async_urb, GFP_ATOMIC); ++ if (res) { ++ dev_dbg(ir->d->dev, "receive request FAILED! (res=%d)\n", res); ++ return; ++ } ++ dev_dbg(ir->d->dev, "receive request complete (res=%d)\n", res); ++} ++ ++static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) ++{ ++ mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_OUTBOUND); ++} ++ ++static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) ++{ ++ mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_INBOUND); ++} ++ ++static int unregister_from_lirc(struct mceusb_dev *ir) ++{ ++ struct lirc_driver *d = ir->d; ++ int devnum; ++ int rtn; ++ ++ devnum = ir->devnum; ++ dev_dbg(ir->d->dev, "unregister from lirc called\n"); ++ ++ rtn = lirc_unregister_driver(d->minor); ++ if (rtn > 0) { ++ dev_info(ir->d->dev, "error in lirc_unregister minor: %d\n" ++ "Trying again...\n", d->minor); ++ if (rtn == -EBUSY) { ++ dev_info(ir->d->dev, "device is opened, will " ++ "unregister on close\n"); ++ return -EAGAIN; ++ } ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(HZ); ++ ++ rtn = lirc_unregister_driver(d->minor); ++ if (rtn > 0) ++ dev_info(ir->d->dev, "lirc_unregister failed\n"); ++ } ++ ++ if (rtn) { ++ dev_info(ir->d->dev, "didn't free resources\n"); ++ return -EAGAIN; ++ } ++ ++ dev_info(ir->d->dev, "usb remote disconnected\n"); ++ ++ lirc_buffer_free(d->rbuf); ++ kfree(d->rbuf); ++ kfree(d); ++ kfree(ir); ++ return 0; ++} ++ ++static int mceusb_ir_open(void *data) ++{ ++ struct mceusb_dev *ir = data; ++ ++ if (!ir) { ++ printk(KERN_WARNING DRIVER_NAME ++ "[?]: %s called with no context\n", __func__); ++ return -EIO; ++ } ++ ++ dev_dbg(ir->d->dev, "mceusb IR device opened\n"); ++ ++ if (!ir->flags.connected) { ++ if (!ir->usbdev) ++ return -ENOENT; ++ ir->flags.connected = 1; ++ } ++ ++ return 0; ++} ++ ++static void mceusb_ir_close(void *data) ++{ ++ struct mceusb_dev *ir = data; ++ ++ if (!ir) { ++ printk(KERN_WARNING DRIVER_NAME ++ "[?]: %s called with no context\n", __func__); ++ return; ++ } ++ ++ dev_dbg(ir->d->dev, "mceusb IR device closed\n"); ++ ++ if (ir->flags.connected) { ++ mutex_lock(&ir->dev_lock); ++ ir->flags.connected = 0; ++ mutex_unlock(&ir->dev_lock); ++ } ++} ++ ++static void send_packet_to_lirc(struct mceusb_dev *ir) ++{ ++ if (ir->lircdata) { ++ lirc_buffer_write(ir->d->rbuf, ++ (unsigned char *) &ir->lircdata); ++ wake_up(&ir->d->rbuf->wait_poll); ++ ir->lircdata = 0; ++ } ++} ++ ++static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) ++{ ++ int i, j; ++ int packet_len = 0; ++ int start_index = 0; ++ ++ /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ ++ if (ir->flags.microsoft_gen1) ++ start_index = 2; ++ ++ /* this should only trigger w/the 1st-gen mce receiver */ ++ for (i = start_index; i < (start_index + ir->overflow_len) && ++ i < buf_len; i++) { ++ /* rising/falling flank */ ++ if (ir->is_pulse != (ir->buf_in[i] & MCE_PULSE_BIT)) { ++ send_packet_to_lirc(ir); ++ ir->is_pulse = ir->buf_in[i] & MCE_PULSE_BIT; ++ } ++ ++ /* accumulate mce pulse/space values */ ++ ir->lircdata += (ir->buf_in[i] & MCE_PULSE_MASK) * ++ MCE_TIME_UNIT; ++ ir->lircdata |= (ir->is_pulse ? PULSE_BIT : 0); ++ } ++ start_index += ir->overflow_len; ++ ir->overflow_len = 0; ++ ++ for (i = start_index; i < buf_len; i++) { ++ /* decode mce packets of the form (84),AA,BB,CC,DD */ ++ ++ /* data headers */ ++ if (ir->buf_in[i] >= 0x80 && ir->buf_in[i] <= 0x9e) { ++ /* decode packet data */ ++ packet_len = ir->buf_in[i] & MCE_PACKET_LENGTH_MASK; ++ ir->overflow_len = i + 1 + packet_len - buf_len; ++ for (j = 1; j <= packet_len && (i + j < buf_len); j++) { ++ /* rising/falling flank */ ++ if (ir->is_pulse != ++ (ir->buf_in[i + j] & MCE_PULSE_BIT)) { ++ send_packet_to_lirc(ir); ++ ir->is_pulse = ++ ir->buf_in[i + j] & ++ MCE_PULSE_BIT; ++ } ++ ++ /* accumulate mce pulse/space values */ ++ ir->lircdata += ++ (ir->buf_in[i + j] & MCE_PULSE_MASK) * ++ MCE_TIME_UNIT; ++ ir->lircdata |= (ir->is_pulse ? PULSE_BIT : 0); ++ } ++ ++ i += packet_len; ++ ++ /* status header (0x9F) */ ++ } else if (ir->buf_in[i] == MCE_CONTROL_HEADER) { ++ /* ++ * A transmission containing one or more consecutive ir ++ * commands always ends with a GAP of 100ms followed by ++ * the sequence 0x9F 0x01 0x01 0x9F 0x15 0x00 0x00 0x80 ++ */ ++ ++#if 0 ++ Uncomment this if the last 100ms "infinity"-space should be transmitted ++ to lirc directly instead of at the beginning of the next transmission. ++ Changes pulse/space order. ++ ++ if (++i < buf_len && ir->buf_in[i] == 0x01) ++ send_packet_to_lirc(ir); ++ ++#endif ++ ++ /* end decode loop */ ++ dev_dbg(ir->d->dev, "[%d] %s: found control header\n", ++ ir->devnum, __func__); ++ ir->overflow_len = 0; ++ break; ++ } else { ++ dev_dbg(ir->d->dev, "[%d] %s: stray packet?\n", ++ ir->devnum, __func__); ++ ir->overflow_len = 0; ++ } ++ } ++ ++ return; ++} ++ ++static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) ++{ ++ struct mceusb_dev *ir; ++ int buf_len; ++ ++ if (!urb) ++ return; ++ ++ ir = urb->context; ++ if (!ir) { ++ usb_unlink_urb(urb); ++ return; ++ } ++ ++ buf_len = urb->actual_length; ++ ++ if (debug) ++ mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false); ++ ++ if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { ++ ir->send_flags = SEND_FLAG_COMPLETE; ++ dev_dbg(ir->d->dev, "setup answer received %d bytes\n", ++ buf_len); ++ } ++ ++ switch (urb->status) { ++ /* success */ ++ case 0: ++ mceusb_process_ir_data(ir, buf_len); ++ break; ++ ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ usb_unlink_urb(urb); ++ return; ++ ++ case -EPIPE: ++ default: ++ break; ++ } ++ ++ usb_submit_urb(urb, GFP_ATOMIC); ++} ++ ++ ++static ssize_t mceusb_transmit_ir(struct file *file, const char *buf, ++ size_t n, loff_t *ppos) ++{ ++ int i, count = 0, cmdcount = 0; ++ struct mceusb_dev *ir = NULL; ++ int wbuf[LIRCBUF_SIZE]; /* Workbuffer with values from lirc */ ++ unsigned char cmdbuf[MCE_CMDBUF_SIZE]; /* MCE command buffer */ ++ unsigned long signal_duration = 0; /* Singnal length in us */ ++ struct timeval start_time, end_time; ++ ++ do_gettimeofday(&start_time); ++ ++ /* Retrieve lirc_driver data for the device */ ++ ir = lirc_get_pdata(file); ++ if (!ir || !ir->usb_ep_out) ++ return -EFAULT; ++ ++ if (n % sizeof(int)) ++ return -EINVAL; ++ count = n / sizeof(int); ++ ++ /* Check if command is within limits */ ++ if (count > LIRCBUF_SIZE || count%2 == 0) ++ return -EINVAL; ++ if (copy_from_user(wbuf, buf, n)) ++ return -EFAULT; ++ ++ /* MCE tx init header */ ++ cmdbuf[cmdcount++] = MCE_CONTROL_HEADER; ++ cmdbuf[cmdcount++] = 0x08; ++ cmdbuf[cmdcount++] = ir->transmitter_mask; ++ ++ /* Generate mce packet data */ ++ for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) { ++ signal_duration += wbuf[i]; ++ wbuf[i] = wbuf[i] / MCE_TIME_UNIT; ++ ++ do { /* loop to support long pulses/spaces > 127*50us=6.35ms */ ++ ++ /* Insert mce packet header every 4th entry */ ++ if ((cmdcount < MCE_CMDBUF_SIZE) && ++ (cmdcount - MCE_TX_HEADER_LENGTH) % ++ MCE_CODE_LENGTH == 0) ++ cmdbuf[cmdcount++] = MCE_PACKET_HEADER; ++ ++ /* Insert mce packet data */ ++ if (cmdcount < MCE_CMDBUF_SIZE) ++ cmdbuf[cmdcount++] = ++ (wbuf[i] < MCE_PULSE_BIT ? ++ wbuf[i] : MCE_MAX_PULSE_LENGTH) | ++ (i & 1 ? 0x00 : MCE_PULSE_BIT); ++ else ++ return -EINVAL; ++ } while ((wbuf[i] > MCE_MAX_PULSE_LENGTH) && ++ (wbuf[i] -= MCE_MAX_PULSE_LENGTH)); ++ } ++ ++ /* Fix packet length in last header */ ++ cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = ++ 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1; ++ ++ /* Check if we have room for the empty packet at the end */ ++ if (cmdcount >= MCE_CMDBUF_SIZE) ++ return -EINVAL; ++ ++ /* All mce commands end with an empty packet (0x80) */ ++ cmdbuf[cmdcount++] = 0x80; ++ ++ /* Transmit the command to the mce device */ ++ mce_async_out(ir, cmdbuf, cmdcount); ++ ++ /* ++ * The lircd gap calculation expects the write function to ++ * wait the time it takes for the ircommand to be sent before ++ * it returns. ++ */ ++ do_gettimeofday(&end_time); ++ signal_duration -= (end_time.tv_usec - start_time.tv_usec) + ++ (end_time.tv_sec - start_time.tv_sec) * 1000000; ++ ++ /* delay with the closest number of ticks */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(usecs_to_jiffies(signal_duration)); ++ ++ return n; ++} ++ ++static void set_transmitter_mask(struct mceusb_dev *ir, unsigned int mask) ++{ ++ if (ir->flags.transmitter_mask_inverted) ++ ir->transmitter_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1; ++ else ++ ir->transmitter_mask = mask; ++} ++ ++ ++/* Sets the send carrier frequency */ ++static int set_send_carrier(struct mceusb_dev *ir, int carrier) ++{ ++ int clk = 10000000; ++ int prescaler = 0, divisor = 0; ++ unsigned char cmdbuf[] = { 0x9F, 0x06, 0x01, 0x80 }; ++ ++ /* Carrier is changed */ ++ if (ir->carrier_freq != carrier) { ++ ++ if (carrier <= 0) { ++ ir->carrier_freq = carrier; ++ dev_dbg(ir->d->dev, "SET_CARRIER disabling carrier " ++ "modulation\n"); ++ mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); ++ return carrier; ++ } ++ ++ for (prescaler = 0; prescaler < 4; ++prescaler) { ++ divisor = (clk >> (2 * prescaler)) / carrier; ++ if (divisor <= 0xFF) { ++ ir->carrier_freq = carrier; ++ cmdbuf[2] = prescaler; ++ cmdbuf[3] = divisor; ++ dev_dbg(ir->d->dev, "SET_CARRIER requesting " ++ "%d Hz\n", carrier); ++ ++ /* Transmit new carrier to mce device */ ++ mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); ++ return carrier; ++ } ++ } ++ ++ return -EINVAL; ++ ++ } ++ ++ return carrier; ++} ++ ++ ++static int mceusb_lirc_ioctl(struct inode *node, struct file *filep, ++ unsigned int cmd, unsigned long arg) ++{ ++ int result; ++ unsigned int ivalue; ++ unsigned long lvalue; ++ struct mceusb_dev *ir = NULL; ++ ++ /* Retrieve lirc_driver data for the device */ ++ ir = lirc_get_pdata(filep); ++ if (!ir || !ir->usb_ep_out) ++ return -EFAULT; ++ ++ ++ switch (cmd) { ++ case LIRC_SET_TRANSMITTER_MASK: ++ ++ result = get_user(ivalue, (unsigned int *) arg); ++ if (result) ++ return result; ++ switch (ivalue) { ++ case 0x01: /* Transmitter 1 => 0x04 */ ++ case 0x02: /* Transmitter 2 => 0x02 */ ++ case 0x03: /* Transmitter 1 & 2 => 0x06 */ ++ set_transmitter_mask(ir, ivalue); ++ break; ++ ++ default: /* Unsupported transmitter mask */ ++ return MCE_MAX_CHANNELS; ++ } ++ ++ dev_dbg(ir->d->dev, ": SET_TRANSMITTERS mask=%d\n", ivalue); ++ break; ++ ++ case LIRC_GET_SEND_MODE: ++ ++ result = put_user(LIRC_SEND2MODE(LIRC_CAN_SEND_PULSE & ++ LIRC_CAN_SEND_MASK), ++ (unsigned long *) arg); ++ ++ if (result) ++ return result; ++ break; ++ ++ case LIRC_SET_SEND_MODE: ++ ++ result = get_user(lvalue, (unsigned long *) arg); ++ ++ if (result) ++ return result; ++ if (lvalue != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) ++ return -EINVAL; ++ break; ++ ++ case LIRC_SET_SEND_CARRIER: ++ ++ result = get_user(ivalue, (unsigned int *) arg); ++ if (result) ++ return result; ++ ++ set_send_carrier(ir, ivalue); ++ break; ++ ++ default: ++ return lirc_dev_fop_ioctl(node, filep, cmd, arg); ++ } ++ ++ return 0; ++} ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .write = mceusb_transmit_ir, ++ .ioctl = mceusb_lirc_ioctl, ++ .read = lirc_dev_fop_read, ++ .poll = lirc_dev_fop_poll, ++ .open = lirc_dev_fop_open, ++ .release = lirc_dev_fop_close, ++}; ++ ++static int mceusb_gen1_init(struct mceusb_dev *ir) ++{ ++ int i, ret; ++ char junk[64], data[8]; ++ int partial = 0; ++ ++ /* ++ * Clear off the first few messages. These look like calibration ++ * or test data, I can't really tell. This also flushes in case ++ * we have random ir data queued up. ++ */ ++ for (i = 0; i < 40; i++) ++ usb_bulk_msg(ir->usbdev, ++ usb_rcvbulkpipe(ir->usbdev, ++ ir->usb_ep_in->bEndpointAddress), ++ junk, 64, &partial, HZ * 10); ++ ++ ir->is_pulse = 1; ++ ++ memset(data, 0, 8); ++ ++ /* Get Status */ ++ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), ++ USB_REQ_GET_STATUS, USB_DIR_IN, ++ 0, 0, data, 2, HZ * 3); ++ ++ /* ret = usb_get_status( ir->usbdev, 0, 0, data ); */ ++ dev_dbg(ir->d->dev, "%s - ret = %d status = 0x%x 0x%x\n", __func__, ++ ret, data[0], data[1]); ++ ++ /* ++ * This is a strange one. They issue a set address to the device ++ * on the receive control pipe and expect a certain value pair back ++ */ ++ memset(data, 0, 8); ++ ++ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), ++ USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, ++ data, 2, HZ * 3); ++ dev_dbg(ir->d->dev, "%s - ret = %d, devnum = %d\n", ++ __func__, ret, ir->usbdev->devnum); ++ dev_dbg(ir->d->dev, "%s - data[0] = %d, data[1] = %d\n", ++ __func__, data[0], data[1]); ++ ++ /* set feature: bit rate 38400 bps */ ++ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), ++ USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, ++ 0xc04e, 0x0000, NULL, 0, HZ * 3); ++ ++ dev_dbg(ir->d->dev, "%s - ret = %d\n", __func__, ret); ++ ++ /* bRequest 4: set char length to 8 bits */ ++ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), ++ 4, USB_TYPE_VENDOR, ++ 0x0808, 0x0000, NULL, 0, HZ * 3); ++ dev_dbg(ir->d->dev, "%s - retB = %d\n", __func__, ret); ++ ++ /* bRequest 2: set handshaking to use DTR/DSR */ ++ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), ++ 2, USB_TYPE_VENDOR, ++ 0x0000, 0x0100, NULL, 0, HZ * 3); ++ dev_dbg(ir->d->dev, "%s - retC = %d\n", __func__, ret); ++ ++ return ret; ++ ++}; ++ ++static int mceusb_dev_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct usb_host_interface *idesc; ++ struct usb_endpoint_descriptor *ep = NULL; ++ struct usb_endpoint_descriptor *ep_in = NULL; ++ struct usb_endpoint_descriptor *ep_out = NULL; ++ struct usb_host_config *config; ++ struct mceusb_dev *ir = NULL; ++ struct lirc_driver *driver = NULL; ++ struct lirc_buffer *rbuf = NULL; ++ int devnum, pipe, maxp; ++ int minor = 0; ++ int i; ++ char buf[63], name[128] = ""; ++ int mem_failure = 0; ++ bool is_gen3; ++ bool is_microsoft_gen1; ++ bool is_pinnacle; ++ ++ dev_dbg(&intf->dev, ": %s called\n", __func__); ++ ++ usb_reset_device(dev); ++ ++ config = dev->actconfig; ++ ++ idesc = intf->cur_altsetting; ++ ++ is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0; ++ ++ is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0; ++ ++ is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0; ++ ++ /* step through the endpoints to find first bulk in and out endpoint */ ++ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { ++ ep = &idesc->endpoint[i].desc; ++ ++ if ((ep_in == NULL) ++ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ == USB_DIR_IN) ++ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_BULK) ++ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_INT))) { ++ ++ dev_dbg(&intf->dev, ": acceptable inbound endpoint " ++ "found\n"); ++ ep_in = ep; ++ ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; ++ if (!is_pinnacle) ++ /* ++ * Ideally, we'd use what the device offers up, ++ * but that leads to non-functioning first and ++ * second-gen devices, and many devices have an ++ * invalid bInterval of 0. Pinnacle devices ++ * don't work witha bInterval of 1 though. ++ */ ++ ep_in->bInterval = 1; ++ } ++ ++ if ((ep_out == NULL) ++ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ == USB_DIR_OUT) ++ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_BULK) ++ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ == USB_ENDPOINT_XFER_INT))) { ++ ++ dev_dbg(&intf->dev, ": acceptable outbound endpoint " ++ "found\n"); ++ ep_out = ep; ++ ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; ++ if (!is_pinnacle) ++ /* ++ * Ideally, we'd use what the device offers up, ++ * but that leads to non-functioning first and ++ * second-gen devices, and many devices have an ++ * invalid bInterval of 0. Pinnacle devices ++ * don't work witha bInterval of 1 though. ++ */ ++ ep_out->bInterval = 1; ++ } ++ } ++ if (ep_in == NULL) { ++ dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n"); ++ return -ENODEV; ++ } ++ ++ devnum = dev->devnum; ++ pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); ++ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); ++ ++ mem_failure = 0; ++ ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); ++ if (!ir) ++ goto mem_alloc_fail; ++ ++ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ if (!driver) ++ goto mem_alloc_fail; ++ ++ rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!rbuf) ++ goto mem_alloc_fail; ++ ++ if (lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE)) ++ goto mem_alloc_fail; ++ ++ ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in); ++ if (!ir->buf_in) ++ goto buf_in_alloc_fail; ++ ++ ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); ++ if (!ir->urb_in) ++ goto urb_in_alloc_fail; ++ ++ strcpy(driver->name, DRIVER_NAME); ++ driver->minor = -1; ++ driver->features = LIRC_CAN_SEND_PULSE | ++ LIRC_CAN_SET_TRANSMITTER_MASK | ++ LIRC_CAN_REC_MODE2 | ++ LIRC_CAN_SET_SEND_CARRIER; ++ driver->data = ir; ++ driver->rbuf = rbuf; ++ driver->set_use_inc = &mceusb_ir_open; ++ driver->set_use_dec = &mceusb_ir_close; ++ driver->code_length = sizeof(int) * 8; ++ driver->fops = &lirc_fops; ++ driver->dev = &intf->dev; ++ driver->owner = THIS_MODULE; ++ ++ mutex_init(&ir->dev_lock); ++ init_waitqueue_head(&ir->wait_out); ++ ++ minor = lirc_register_driver(driver); ++ if (minor < 0) ++ goto lirc_register_fail; ++ ++ driver->minor = minor; ++ ir->d = driver; ++ ir->devnum = devnum; ++ ir->usbdev = dev; ++ ir->len_in = maxp; ++ ir->overflow_len = 0; ++ ir->flags.connected = 0; ++ ir->flags.gen3 = is_gen3; ++ ir->flags.microsoft_gen1 = is_microsoft_gen1; ++ ir->flags.transmitter_mask_inverted = ++ usb_match_id(intf, transmitter_mask_list) ? 0 : 1; ++ ++ ir->lircdata = PULSE_MASK; ++ ir->is_pulse = 0; ++ ++ /* ir->flags.transmitter_mask_inverted must be set */ ++ set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK); ++ /* Saving usb interface data for use by the transmitter routine */ ++ ir->usb_ep_in = ep_in; ++ ir->usb_ep_out = ep_out; ++ ++ if (dev->descriptor.iManufacturer ++ && usb_string(dev, dev->descriptor.iManufacturer, ++ buf, sizeof(buf)) > 0) ++ strlcpy(name, buf, sizeof(name)); ++ if (dev->descriptor.iProduct ++ && usb_string(dev, dev->descriptor.iProduct, ++ buf, sizeof(buf)) > 0) ++ snprintf(name + strlen(name), sizeof(name) - strlen(name), ++ " %s", buf); ++ ++ /* inbound data */ ++ usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, ++ maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); ++ ir->urb_in->transfer_dma = ir->dma_in; ++ ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ if (is_pinnacle) { ++ int usbret; ++ ++ /* ++ * I have no idea why but this reset seems to be crucial to ++ * getting the device to do outbound IO correctly - without ++ * this the device seems to hang, ignoring all input - although ++ * IR signals are correctly sent from the device, no input is ++ * interpreted by the device and the host never does the ++ * completion routine ++ */ ++ usbret = usb_reset_configuration(dev); ++ dev_info(ir->d->dev, "usb reset config ret %x\n", usbret); ++ } ++ ++ /* initialize device */ ++ if (ir->flags.gen3) { ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* device reset */ ++ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get the carrier and frequency */ ++ mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get the transmitter bitmask */ ++ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get receiver timeout value */ ++ mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get receiver sensor setting */ ++ mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ } else if (ir->flags.microsoft_gen1) { ++ /* original ms mce device requires some additional setup */ ++ mceusb_gen1_init(ir); ++ ++ } else { ++ mce_sync_in(ir, NULL, maxp); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* device reset */ ++ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* get hw/sw revision? */ ++ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); ++ mce_sync_in(ir, NULL, maxp); ++ ++ /* unknown what this actually returns... */ ++ mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); ++ mce_sync_in(ir, NULL, maxp); ++ } ++ ++ /* ++ * if we don't issue the correct number of receives (mce_sync_in()) ++ * for each outbound, then the first few ir pulses will be interpreted ++ * by the usb_async_callback routine - we should ensure we have the ++ * right amount OR less - as the mceusb_dev_recv routine will handle ++ * the control packets OK - they start with 0x9f - but the async ++ * callback doesn't handle ir pulse packets ++ */ ++ mce_sync_in(ir, NULL, maxp); ++ ++ usb_set_intfdata(intf, ir); ++ ++ dev_info(ir->d->dev, "Registered %s on usb%d:%d\n", name, ++ dev->bus->busnum, devnum); ++ ++ return 0; ++ ++ /* Error-handling path */ ++lirc_register_fail: ++ usb_free_urb(ir->urb_in); ++urb_in_alloc_fail: ++ usb_alloc_coherent(dev, maxp, ir->buf_in, ir->dma_in); ++buf_in_alloc_fail: ++ lirc_buffer_free(rbuf); ++mem_alloc_fail: ++ kfree(rbuf); ++ kfree(driver); ++ kfree(ir); ++ dev_info(&intf->dev, "out of memory (code=%d)\n", mem_failure); ++ ++ return -ENOMEM; ++} ++ ++ ++static void mceusb_dev_disconnect(struct usb_interface *intf) ++{ ++ struct usb_device *dev = interface_to_usbdev(intf); ++ struct mceusb_dev *ir = usb_get_intfdata(intf); ++ ++ usb_set_intfdata(intf, NULL); ++ ++ if (!ir || !ir->d) ++ return; ++ ++ ir->usbdev = NULL; ++ wake_up_all(&ir->wait_out); ++ ++ mutex_lock(&ir->dev_lock); ++ usb_kill_urb(ir->urb_in); ++ usb_free_urb(ir->urb_in); ++ usb_alloc_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in); ++ mutex_unlock(&ir->dev_lock); ++ ++ unregister_from_lirc(ir); ++} ++ ++static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct mceusb_dev *ir = usb_get_intfdata(intf); ++ dev_info(ir->d->dev, "suspend\n"); ++ usb_kill_urb(ir->urb_in); ++ return 0; ++} ++ ++static int mceusb_dev_resume(struct usb_interface *intf) ++{ ++ struct mceusb_dev *ir = usb_get_intfdata(intf); ++ dev_info(ir->d->dev, "resume\n"); ++ if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) ++ return -EIO; ++ return 0; ++} ++ ++static struct usb_driver mceusb_dev_driver = { ++ .name = DRIVER_NAME, ++ .probe = mceusb_dev_probe, ++ .disconnect = mceusb_dev_disconnect, ++ .suspend = mceusb_dev_suspend, ++ .resume = mceusb_dev_resume, ++ .reset_resume = mceusb_dev_resume, ++ .id_table = mceusb_dev_table ++}; ++ ++static int __init mceusb_dev_init(void) ++{ ++ int i; ++ ++ printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " " DRIVER_VERSION "\n"); ++ printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n"); ++ if (debug) ++ printk(KERN_DEBUG DRIVER_NAME ": debug mode enabled\n"); ++ ++ i = usb_register(&mceusb_dev_driver); ++ if (i < 0) { ++ printk(KERN_ERR DRIVER_NAME ++ ": usb register failed, result = %d\n", i); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static void __exit mceusb_dev_exit(void) ++{ ++ usb_deregister(&mceusb_dev_driver); ++} ++ ++module_init(mceusb_dev_init); ++module_exit(mceusb_dev_exit); ++ ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_AUTHOR(DRIVER_AUTHOR); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, mceusb_dev_table); ++/* this was originally lirc_mceusb2, lirc_mceusb and lirc_mceusb2 merged now */ ++MODULE_ALIAS("lirc_mceusb2"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug enabled or not"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_parallel.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_parallel.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_parallel.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_parallel.c 2010-08-02 09:28:03.957927009 +0200 +@@ -0,0 +1,709 @@ ++/* ++ * lirc_parallel.c ++ * ++ * lirc_parallel - device driver for infra-red signal receiving and ++ * transmitting unit built by the author ++ * ++ * Copyright (C) 1998 Christoph Bartelmus ++ * ++ * 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 ++ * ++ */ ++ ++/*** Includes ***/ ++ ++#ifdef CONFIG_SMP ++#error "--- Sorry, this driver is not SMP safe. ---" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++#include "lirc_parallel.h" ++ ++#define LIRC_DRIVER_NAME "lirc_parallel" ++ ++#ifndef LIRC_IRQ ++#define LIRC_IRQ 7 ++#endif ++#ifndef LIRC_PORT ++#define LIRC_PORT 0x378 ++#endif ++#ifndef LIRC_TIMER ++#define LIRC_TIMER 65536 ++#endif ++ ++/*** Global Variables ***/ ++ ++static int debug; ++static int check_pselecd; ++ ++unsigned int irq = LIRC_IRQ; ++unsigned int io = LIRC_PORT; ++#ifdef LIRC_TIMER ++unsigned int timer; ++unsigned int default_timer = LIRC_TIMER; ++#endif ++ ++#define WBUF_SIZE (256) ++#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */ ++ ++static int wbuf[WBUF_SIZE]; ++static int rbuf[RBUF_SIZE]; ++ ++DECLARE_WAIT_QUEUE_HEAD(lirc_wait); ++ ++unsigned int rptr; ++unsigned int wptr; ++unsigned int lost_irqs; ++int is_open; ++ ++struct parport *pport; ++struct pardevice *ppdevice; ++int is_claimed; ++ ++unsigned int tx_mask = 1; ++ ++/*** Internal Functions ***/ ++ ++static unsigned int in(int offset) ++{ ++ switch (offset) { ++ case LIRC_LP_BASE: ++ return parport_read_data(pport); ++ case LIRC_LP_STATUS: ++ return parport_read_status(pport); ++ case LIRC_LP_CONTROL: ++ return parport_read_control(pport); ++ } ++ return 0; /* make compiler happy */ ++} ++ ++static void out(int offset, int value) ++{ ++ switch (offset) { ++ case LIRC_LP_BASE: ++ parport_write_data(pport, value); ++ break; ++ case LIRC_LP_CONTROL: ++ parport_write_control(pport, value); ++ break; ++ case LIRC_LP_STATUS: ++ printk(KERN_INFO "%s: attempt to write to status register\n", ++ LIRC_DRIVER_NAME); ++ break; ++ } ++} ++ ++static unsigned int lirc_get_timer(void) ++{ ++ return in(LIRC_PORT_TIMER) & LIRC_PORT_TIMER_BIT; ++} ++ ++static unsigned int lirc_get_signal(void) ++{ ++ return in(LIRC_PORT_SIGNAL) & LIRC_PORT_SIGNAL_BIT; ++} ++ ++static void lirc_on(void) ++{ ++ out(LIRC_PORT_DATA, tx_mask); ++} ++ ++static void lirc_off(void) ++{ ++ out(LIRC_PORT_DATA, 0); ++} ++ ++static unsigned int init_lirc_timer(void) ++{ ++ struct timeval tv, now; ++ unsigned int level, newlevel, timeelapsed, newtimer; ++ int count = 0; ++ ++ do_gettimeofday(&tv); ++ tv.tv_sec++; /* wait max. 1 sec. */ ++ level = lirc_get_timer(); ++ do { ++ newlevel = lirc_get_timer(); ++ if (level == 0 && newlevel != 0) ++ count++; ++ level = newlevel; ++ do_gettimeofday(&now); ++ } while (count < 1000 && (now.tv_sec < tv.tv_sec ++ || (now.tv_sec == tv.tv_sec ++ && now.tv_usec < tv.tv_usec))); ++ ++ timeelapsed = ((now.tv_sec + 1 - tv.tv_sec)*1000000 ++ + (now.tv_usec - tv.tv_usec)); ++ if (count >= 1000 && timeelapsed > 0) { ++ if (default_timer == 0) { ++ /* autodetect timer */ ++ newtimer = (1000000*count)/timeelapsed; ++ printk(KERN_INFO "%s: %u Hz timer detected\n", ++ LIRC_DRIVER_NAME, newtimer); ++ return newtimer; ++ } else { ++ newtimer = (1000000*count)/timeelapsed; ++ if (abs(newtimer - default_timer) > default_timer/10) { ++ /* bad timer */ ++ printk(KERN_NOTICE "%s: bad timer: %u Hz\n", ++ LIRC_DRIVER_NAME, newtimer); ++ printk(KERN_NOTICE "%s: using default timer: " ++ "%u Hz\n", ++ LIRC_DRIVER_NAME, default_timer); ++ return default_timer; ++ } else { ++ printk(KERN_INFO "%s: %u Hz timer detected\n", ++ LIRC_DRIVER_NAME, newtimer); ++ return newtimer; /* use detected value */ ++ } ++ } ++ } else { ++ printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME); ++ return 0; ++ } ++} ++ ++static int lirc_claim(void) ++{ ++ if (parport_claim(ppdevice) != 0) { ++ printk(KERN_WARNING "%s: could not claim port\n", ++ LIRC_DRIVER_NAME); ++ printk(KERN_WARNING "%s: waiting for port becoming available" ++ "\n", LIRC_DRIVER_NAME); ++ if (parport_claim_or_block(ppdevice) < 0) { ++ printk(KERN_NOTICE "%s: could not claim port, giving" ++ " up\n", LIRC_DRIVER_NAME); ++ return 0; ++ } ++ } ++ out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); ++ is_claimed = 1; ++ return 1; ++} ++ ++/*** interrupt handler ***/ ++ ++static void rbuf_write(int signal) ++{ ++ unsigned int nwptr; ++ ++ nwptr = (wptr + 1) & (RBUF_SIZE - 1); ++ if (nwptr == rptr) { ++ /* no new signals will be accepted */ ++ lost_irqs++; ++ printk(KERN_NOTICE "%s: buffer overrun\n", LIRC_DRIVER_NAME); ++ return; ++ } ++ rbuf[wptr] = signal; ++ wptr = nwptr; ++} ++ ++static void irq_handler(void *blah) ++{ ++ struct timeval tv; ++ static struct timeval lasttv; ++ static int init; ++ long signal; ++ int data; ++ unsigned int level, newlevel; ++ unsigned int timeout; ++ ++ if (!module_refcount(THIS_MODULE)) ++ return; ++ ++ if (!is_claimed) ++ return; ++ ++#if 0 ++ /* disable interrupt */ ++ disable_irq(irq); ++ out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN)); ++#endif ++ if (check_pselecd && (in(1) & LP_PSELECD)) ++ return; ++ ++#ifdef LIRC_TIMER ++ if (init) { ++ do_gettimeofday(&tv); ++ ++ signal = tv.tv_sec - lasttv.tv_sec; ++ if (signal > 15) ++ /* really long time */ ++ data = PULSE_MASK; ++ else ++ data = (int) (signal*1000000 + ++ tv.tv_usec - lasttv.tv_usec + ++ LIRC_SFH506_DELAY); ++ ++ rbuf_write(data); /* space */ ++ } else { ++ if (timer == 0) { ++ /* ++ * wake up; we'll lose this signal, but it will be ++ * garbage if the device is turned on anyway ++ */ ++ timer = init_lirc_timer(); ++ /* enable_irq(irq); */ ++ return; ++ } ++ init = 1; ++ } ++ ++ timeout = timer/10; /* timeout after 1/10 sec. */ ++ signal = 1; ++ level = lirc_get_timer(); ++ do { ++ newlevel = lirc_get_timer(); ++ if (level == 0 && newlevel != 0) ++ signal++; ++ level = newlevel; ++ ++ /* giving up */ ++ if (signal > timeout ++ || (check_pselecd && (in(1) & LP_PSELECD))) { ++ signal = 0; ++ printk(KERN_NOTICE "%s: timeout\n", LIRC_DRIVER_NAME); ++ break; ++ } ++ } while (lirc_get_signal()); ++ ++ if (signal != 0) { ++ /* ajust value to usecs */ ++ unsigned long long helper; ++ ++ helper = ((unsigned long long) signal)*1000000; ++ do_div(helper, timer); ++ signal = (long) helper; ++ ++ if (signal > LIRC_SFH506_DELAY) ++ data = signal - LIRC_SFH506_DELAY; ++ else ++ data = 1; ++ rbuf_write(PULSE_BIT|data); /* pulse */ ++ } ++ do_gettimeofday(&lasttv); ++#else ++ /* add your code here */ ++#endif ++ ++ wake_up_interruptible(&lirc_wait); ++ ++ /* enable interrupt */ ++ /* ++ enable_irq(irq); ++ out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN); ++ */ ++} ++ ++/*** file operations ***/ ++ ++static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig) ++{ ++ return -ESPIPE; ++} ++ ++static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos) ++{ ++ int result = 0; ++ int count = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ if (n % sizeof(int)) ++ return -EINVAL; ++ ++ add_wait_queue(&lirc_wait, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ while (count < n) { ++ if (rptr != wptr) { ++ if (copy_to_user(buf+count, (char *) &rbuf[rptr], ++ sizeof(int))) { ++ result = -EFAULT; ++ break; ++ } ++ rptr = (rptr + 1) & (RBUF_SIZE - 1); ++ count += sizeof(int); ++ } else { ++ if (filep->f_flags & O_NONBLOCK) { ++ result = -EAGAIN; ++ break; ++ } ++ if (signal_pending(current)) { ++ result = -ERESTARTSYS; ++ break; ++ } ++ schedule(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ } ++ } ++ remove_wait_queue(&lirc_wait, &wait); ++ set_current_state(TASK_RUNNING); ++ return count ? count : result; ++} ++ ++static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, ++ loff_t *ppos) ++{ ++ int count; ++ unsigned int i; ++ unsigned int level, newlevel; ++ unsigned long flags; ++ int counttimer; ++ ++ if (!is_claimed) ++ return -EBUSY; ++ ++ if (n % sizeof(int)) ++ return -EINVAL; ++ ++ count = n / sizeof(int); ++ ++ if (count > WBUF_SIZE || count % 2 == 0) ++ return -EINVAL; ++ ++ if (copy_from_user(wbuf, buf, n)) ++ return -EFAULT; ++ ++#ifdef LIRC_TIMER ++ if (timer == 0) { ++ /* try again if device is ready */ ++ timer = init_lirc_timer(); ++ if (timer == 0) ++ return -EIO; ++ } ++ ++ /* adjust values from usecs */ ++ for (i = 0; i < count; i++) { ++ unsigned long long helper; ++ ++ helper = ((unsigned long long) wbuf[i])*timer; ++ do_div(helper, 1000000); ++ wbuf[i] = (int) helper; ++ } ++ ++ local_irq_save(flags); ++ i = 0; ++ while (i < count) { ++ level = lirc_get_timer(); ++ counttimer = 0; ++ lirc_on(); ++ do { ++ newlevel = lirc_get_timer(); ++ if (level == 0 && newlevel != 0) ++ counttimer++; ++ level = newlevel; ++ if (check_pselecd && (in(1) & LP_PSELECD)) { ++ lirc_off(); ++ local_irq_restore(flags); ++ return -EIO; ++ } ++ } while (counttimer < wbuf[i]); ++ i++; ++ ++ lirc_off(); ++ if (i == count) ++ break; ++ counttimer = 0; ++ do { ++ newlevel = lirc_get_timer(); ++ if (level == 0 && newlevel != 0) ++ counttimer++; ++ level = newlevel; ++ if (check_pselecd && (in(1) & LP_PSELECD)) { ++ local_irq_restore(flags); ++ return -EIO; ++ } ++ } while (counttimer < wbuf[i]); ++ i++; ++ } ++ local_irq_restore(flags); ++#else ++ /* place code that handles write without external timer here */ ++#endif ++ return n; ++} ++ ++static unsigned int lirc_poll(struct file *file, poll_table *wait) ++{ ++ poll_wait(file, &lirc_wait, wait); ++ if (rptr != wptr) ++ return POLLIN | POLLRDNORM; ++ return 0; ++} ++ ++static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, ++ unsigned long arg) ++{ ++ int result; ++ unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; ++ unsigned long mode; ++ unsigned int ivalue; ++ ++ switch (cmd) { ++ case LIRC_GET_FEATURES: ++ result = put_user(features, (unsigned long *) arg); ++ if (result) ++ return result; ++ break; ++ case LIRC_GET_SEND_MODE: ++ result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); ++ if (result) ++ return result; ++ break; ++ case LIRC_GET_REC_MODE: ++ result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg); ++ if (result) ++ return result; ++ break; ++ case LIRC_SET_SEND_MODE: ++ result = get_user(mode, (unsigned long *) arg); ++ if (result) ++ return result; ++ if (mode != LIRC_MODE_PULSE) ++ return -EINVAL; ++ break; ++ case LIRC_SET_REC_MODE: ++ result = get_user(mode, (unsigned long *) arg); ++ if (result) ++ return result; ++ if (mode != LIRC_MODE_MODE2) ++ return -ENOSYS; ++ break; ++ case LIRC_SET_TRANSMITTER_MASK: ++ result = get_user(ivalue, (unsigned int *) arg); ++ if (result) ++ return result; ++ if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue) ++ return LIRC_PARALLEL_MAX_TRANSMITTERS; ++ tx_mask = ivalue; ++ break; ++ default: ++ return -ENOIOCTLCMD; ++ } ++ return 0; ++} ++ ++static int lirc_open(struct inode *node, struct file *filep) ++{ ++ if (module_refcount(THIS_MODULE) || !lirc_claim()) ++ return -EBUSY; ++ ++ parport_enable_irq(pport); ++ ++ /* init read ptr */ ++ rptr = 0; ++ wptr = 0; ++ lost_irqs = 0; ++ ++ is_open = 1; ++ return 0; ++} ++ ++static int lirc_close(struct inode *node, struct file *filep) ++{ ++ if (is_claimed) { ++ is_claimed = 0; ++ parport_release(ppdevice); ++ } ++ is_open = 0; ++ return 0; ++} ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .llseek = lirc_lseek, ++ .read = lirc_read, ++ .write = lirc_write, ++ .poll = lirc_poll, ++ .ioctl = lirc_ioctl, ++ .open = lirc_open, ++ .release = lirc_close ++}; ++ ++static int set_use_inc(void *data) ++{ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++} ++ ++static struct lirc_driver driver = { ++ .name = LIRC_DRIVER_NAME, ++ .minor = -1, ++ .code_length = 1, ++ .sample_rate = 0, ++ .data = NULL, ++ .add_to_buf = NULL, ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .fops = &lirc_fops, ++ .dev = NULL, ++ .owner = THIS_MODULE, ++}; ++ ++static int pf(void *handle); ++static void kf(void *handle); ++ ++static struct timer_list poll_timer; ++static void poll_state(unsigned long ignored); ++ ++static void poll_state(unsigned long ignored) ++{ ++ printk(KERN_NOTICE "%s: time\n", ++ LIRC_DRIVER_NAME); ++ del_timer(&poll_timer); ++ if (is_claimed) ++ return; ++ kf(NULL); ++ if (!is_claimed) { ++ printk(KERN_NOTICE "%s: could not claim port, giving up\n", ++ LIRC_DRIVER_NAME); ++ init_timer(&poll_timer); ++ poll_timer.expires = jiffies + HZ; ++ poll_timer.data = (unsigned long)current; ++ poll_timer.function = poll_state; ++ add_timer(&poll_timer); ++ } ++} ++ ++static int pf(void *handle) ++{ ++ parport_disable_irq(pport); ++ is_claimed = 0; ++ return 0; ++} ++ ++static void kf(void *handle) ++{ ++ if (!is_open) ++ return; ++ if (!lirc_claim()) ++ return; ++ parport_enable_irq(pport); ++ lirc_off(); ++ /* this is a bit annoying when you actually print...*/ ++ /* ++ printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME); ++ */ ++} ++ ++/*** module initialization and cleanup ***/ ++ ++static int __init lirc_parallel_init(void) ++{ ++ pport = parport_find_base(io); ++ if (pport == NULL) { ++ printk(KERN_NOTICE "%s: no port at %x found\n", ++ LIRC_DRIVER_NAME, io); ++ return -ENXIO; ++ } ++ ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME, ++ pf, kf, irq_handler, 0, NULL); ++ parport_put_port(pport); ++ if (ppdevice == NULL) { ++ printk(KERN_NOTICE "%s: parport_register_device() failed\n", ++ LIRC_DRIVER_NAME); ++ return -ENXIO; ++ } ++ if (parport_claim(ppdevice) != 0) ++ goto skip_init; ++ is_claimed = 1; ++ out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); ++ ++#ifdef LIRC_TIMER ++ if (debug) ++ out(LIRC_PORT_DATA, tx_mask); ++ ++ timer = init_lirc_timer(); ++ ++#if 0 /* continue even if device is offline */ ++ if (timer == 0) { ++ is_claimed = 0; ++ parport_release(pport); ++ parport_unregister_device(ppdevice); ++ return -EIO; ++ } ++ ++#endif ++ if (debug) ++ out(LIRC_PORT_DATA, 0); ++#endif ++ ++ is_claimed = 0; ++ parport_release(ppdevice); ++ skip_init: ++ driver.minor = lirc_register_driver(&driver); ++ if (driver.minor < 0) { ++ printk(KERN_NOTICE "%s: register_chrdev() failed\n", ++ LIRC_DRIVER_NAME); ++ parport_unregister_device(ppdevice); ++ return -EIO; ++ } ++ printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n", ++ LIRC_DRIVER_NAME, io, irq); ++ return 0; ++} ++ ++static void __exit lirc_parallel_exit(void) ++{ ++ parport_unregister_device(ppdevice); ++ lirc_unregister_driver(driver.minor); ++} ++ ++module_init(lirc_parallel_init); ++module_exit(lirc_parallel_exit); ++ ++MODULE_DESCRIPTION("Infrared receiver driver for parallel ports."); ++MODULE_AUTHOR("Christoph Bartelmus"); ++MODULE_LICENSE("GPL"); ++ ++module_param(io, int, S_IRUGO); ++MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)"); ++ ++module_param(irq, int, S_IRUGO); ++MODULE_PARM_DESC(irq, "Interrupt (7 or 5)"); ++ ++module_param(tx_mask, int, S_IRUGO); ++MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); ++ ++module_param(check_pselecd, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Check for printer (default: 0)"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_parallel.h linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_parallel.h +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_parallel.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_parallel.h 2010-08-02 09:28:03.958926641 +0200 +@@ -0,0 +1,26 @@ ++/* lirc_parallel.h */ ++ ++#ifndef _LIRC_PARALLEL_H ++#define _LIRC_PARALLEL_H ++ ++#include ++ ++#define LIRC_PORT_LEN 3 ++ ++#define LIRC_LP_BASE 0 ++#define LIRC_LP_STATUS 1 ++#define LIRC_LP_CONTROL 2 ++ ++#define LIRC_PORT_DATA LIRC_LP_BASE /* base */ ++#define LIRC_PORT_TIMER LIRC_LP_STATUS /* status port */ ++#define LIRC_PORT_TIMER_BIT LP_PBUSY /* busy signal */ ++#define LIRC_PORT_SIGNAL LIRC_LP_STATUS /* status port */ ++#define LIRC_PORT_SIGNAL_BIT LP_PACK /* ack signal */ ++#define LIRC_PORT_IRQ LIRC_LP_CONTROL /* control port */ ++ ++#define LIRC_SFH506_DELAY 0 /* delay t_phl in usecs */ ++ ++#define LIRC_PARALLEL_MAX_TRANSMITTERS 8 ++#define LIRC_PARALLEL_TRANSMITTER_MASK ((1< ++ * Tim Davies ++ * ++ * This driver was derived from: ++ * Venky Raju ++ * "lirc_imon - "LIRC/VFD driver for Ahanix/Soundgraph IMON IR/VFD" ++ * Paul Miller 's 2003-2004 ++ * "lirc_atiusb - USB remote support for LIRC" ++ * Culver Consulting Services 's 2003 ++ * "Sasem OnAir VFD/IR USB driver" ++ * ++ * ++ * NOTE - The LCDproc iMon driver should work with this module. More info at ++ * http://www.frogstorm.info/sasem ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++ ++#define MOD_AUTHOR "Oliver Stabel , " \ ++ "Tim Davies " ++#define MOD_DESC "USB Driver for Sasem Remote Controller V1.1" ++#define MOD_NAME "lirc_sasem" ++#define MOD_VERSION "0.5" ++ ++#define VFD_MINOR_BASE 144 /* Same as LCD */ ++#define DEVICE_NAME "lcd%d" ++ ++#define BUF_CHUNK_SIZE 8 ++#define BUF_SIZE 128 ++ ++#define IOCTL_LCD_CONTRAST 1 ++ ++/*** P R O T O T Y P E S ***/ ++ ++/* USB Callback prototypes */ ++static int sasem_probe(struct usb_interface *interface, ++ const struct usb_device_id *id); ++static void sasem_disconnect(struct usb_interface *interface); ++static void usb_rx_callback(struct urb *urb); ++static void usb_tx_callback(struct urb *urb); ++ ++/* VFD file_operations function prototypes */ ++static int vfd_open(struct inode *inode, struct file *file); ++static int vfd_ioctl(struct inode *inode, struct file *file, ++ unsigned cmd, unsigned long arg); ++static int vfd_close(struct inode *inode, struct file *file); ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos); ++ ++/* LIRC driver function prototypes */ ++static int ir_open(void *data); ++static void ir_close(void *data); ++ ++/* Driver init/exit prototypes */ ++static int __init sasem_init(void); ++static void __exit sasem_exit(void); ++ ++/*** G L O B A L S ***/ ++ ++struct sasem_context { ++ ++ struct usb_device *dev; ++ int vfd_isopen; /* VFD port has been opened */ ++ unsigned int vfd_contrast; /* VFD contrast */ ++ int ir_isopen; /* IR port has been opened */ ++ int dev_present; /* USB device presence */ ++ struct mutex ctx_lock; /* to lock this object */ ++ wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ ++ ++ struct lirc_driver *driver; ++ struct usb_endpoint_descriptor *rx_endpoint; ++ struct usb_endpoint_descriptor *tx_endpoint; ++ struct urb *rx_urb; ++ struct urb *tx_urb; ++ unsigned char usb_rx_buf[8]; ++ unsigned char usb_tx_buf[8]; ++ ++ struct tx_t { ++ unsigned char data_buf[32]; /* user data buffer */ ++ struct completion finished; /* wait for write to finish */ ++ atomic_t busy; /* write in progress */ ++ int status; /* status of tx completion */ ++ } tx; ++ ++ /* for dealing with repeat codes (wish there was a toggle bit!) */ ++ struct timeval presstime; ++ char lastcode[8]; ++ int codesaved; ++}; ++ ++/* VFD file operations */ ++static struct file_operations vfd_fops = { ++ .owner = THIS_MODULE, ++ .open = &vfd_open, ++ .write = &vfd_write, ++ .ioctl = &vfd_ioctl, ++ .release = &vfd_close, ++}; ++ ++/* USB Device ID for Sasem USB Control Board */ ++static struct usb_device_id sasem_usb_id_table[] = { ++ /* Sasem USB Control Board */ ++ { USB_DEVICE(0x11ba, 0x0101) }, ++ /* Terminating entry */ ++ {} ++}; ++ ++/* USB Device data */ ++static struct usb_driver sasem_driver = { ++ .name = MOD_NAME, ++ .probe = sasem_probe, ++ .disconnect = sasem_disconnect, ++ .id_table = sasem_usb_id_table, ++}; ++ ++static struct usb_class_driver sasem_class = { ++ .name = DEVICE_NAME, ++ .fops = &vfd_fops, ++ .minor_base = VFD_MINOR_BASE, ++}; ++ ++/* to prevent races between open() and disconnect() */ ++static DEFINE_MUTEX(disconnect_lock); ++ ++static int debug; ++ ++ ++/*** M O D U L E C O D E ***/ ++ ++MODULE_AUTHOR(MOD_AUTHOR); ++MODULE_DESCRIPTION(MOD_DESC); ++MODULE_LICENSE("GPL"); ++module_param(debug, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); ++ ++static void delete_context(struct sasem_context *context) ++{ ++ usb_free_urb(context->tx_urb); /* VFD */ ++ usb_free_urb(context->rx_urb); /* IR */ ++ lirc_buffer_free(context->driver->rbuf); ++ kfree(context->driver->rbuf); ++ kfree(context->driver); ++ kfree(context); ++ ++ if (debug) ++ printk(KERN_INFO "%s: context deleted\n", __func__); ++} ++ ++static void deregister_from_lirc(struct sasem_context *context) ++{ ++ int retval; ++ int minor = context->driver->minor; ++ ++ retval = lirc_unregister_driver(minor); ++ if (retval) ++ err("%s: unable to deregister from lirc (%d)", ++ __func__, retval); ++ else ++ printk(KERN_INFO "Deregistered Sasem driver (minor:%d)\n", ++ minor); ++ ++} ++ ++/** ++ * Called when the VFD device (e.g. /dev/usb/lcd) ++ * is opened by the application. ++ */ ++static int vfd_open(struct inode *inode, struct file *file) ++{ ++ struct usb_interface *interface; ++ struct sasem_context *context = NULL; ++ int subminor; ++ int retval = 0; ++ ++ /* prevent races with disconnect */ ++ mutex_lock(&disconnect_lock); ++ ++ subminor = iminor(inode); ++ interface = usb_find_interface(&sasem_driver, subminor); ++ if (!interface) { ++ err("%s: could not find interface for minor %d", ++ __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ context = usb_get_intfdata(interface); ++ ++ if (!context) { ++ err("%s: no context found for minor %d", ++ __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (context->vfd_isopen) { ++ err("%s: VFD port is already open", __func__); ++ retval = -EBUSY; ++ } else { ++ context->vfd_isopen = 1; ++ file->private_data = context; ++ printk(KERN_INFO "VFD port opened\n"); ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ ++exit: ++ mutex_unlock(&disconnect_lock); ++ return retval; ++} ++ ++/** ++ * Called when the VFD device (e.g. /dev/usb/lcd) ++ * is closed by the application. ++ */ ++static int vfd_ioctl(struct inode *inode, struct file *file, ++ unsigned cmd, unsigned long arg) ++{ ++ struct sasem_context *context = NULL; ++ ++ context = (struct sasem_context *) file->private_data; ++ ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ switch (cmd) { ++ case IOCTL_LCD_CONTRAST: ++ if (arg > 1000) ++ arg = 1000; ++ context->vfd_contrast = (unsigned int)arg; ++ break; ++ default: ++ printk(KERN_INFO "Unknown IOCTL command\n"); ++ mutex_unlock(&context->ctx_lock); ++ return -ENOIOCTLCMD; /* not supported */ ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ return 0; ++} ++ ++/** ++ * Called when the VFD device (e.g. /dev/usb/lcd) ++ * is closed by the application. ++ */ ++static int vfd_close(struct inode *inode, struct file *file) ++{ ++ struct sasem_context *context = NULL; ++ int retval = 0; ++ ++ context = (struct sasem_context *) file->private_data; ++ ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (!context->vfd_isopen) { ++ err("%s: VFD is not open", __func__); ++ retval = -EIO; ++ } else { ++ context->vfd_isopen = 0; ++ printk(KERN_INFO "VFD port closed\n"); ++ if (!context->dev_present && !context->ir_isopen) { ++ ++ /* Device disconnected before close and IR port is ++ * not open. If IR port is open, context will be ++ * deleted by ir_close. */ ++ mutex_unlock(&context->ctx_lock); ++ delete_context(context); ++ return retval; ++ } ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ return retval; ++} ++ ++/** ++ * Sends a packet to the VFD. ++ */ ++static int send_packet(struct sasem_context *context) ++{ ++ unsigned int pipe; ++ int interval = 0; ++ int retval = 0; ++ ++ pipe = usb_sndintpipe(context->dev, ++ context->tx_endpoint->bEndpointAddress); ++ interval = context->tx_endpoint->bInterval; ++ ++ usb_fill_int_urb(context->tx_urb, context->dev, pipe, ++ context->usb_tx_buf, sizeof(context->usb_tx_buf), ++ usb_tx_callback, context, interval); ++ ++ context->tx_urb->actual_length = 0; ++ ++ init_completion(&context->tx.finished); ++ atomic_set(&(context->tx.busy), 1); ++ ++ retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); ++ if (retval) { ++ atomic_set(&(context->tx.busy), 0); ++ err("%s: error submitting urb (%d)", __func__, retval); ++ } else { ++ /* Wait for transmission to complete (or abort) */ ++ mutex_unlock(&context->ctx_lock); ++ wait_for_completion(&context->tx.finished); ++ mutex_lock(&context->ctx_lock); ++ ++ retval = context->tx.status; ++ if (retval) ++ err("%s: packet tx failed (%d)", __func__, retval); ++ } ++ ++ return retval; ++} ++ ++/** ++ * Writes data to the VFD. The Sasem VFD is 2x16 characters ++ * and requires data in 9 consecutive USB interrupt packets, ++ * each packet carrying 8 bytes. ++ */ ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos) ++{ ++ int i; ++ int retval = 0; ++ struct sasem_context *context; ++ ++ context = (struct sasem_context *) file->private_data; ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (!context->dev_present) { ++ err("%s: no Sasem device present", __func__); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ if (n_bytes <= 0 || n_bytes > 32) { ++ err("%s: invalid payload size", __func__); ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ retval = copy_from_user(context->tx.data_buf, buf, n_bytes); ++ if (retval < 0) ++ goto exit; ++ ++ /* Pad with spaces */ ++ for (i = n_bytes; i < 32; ++i) ++ context->tx.data_buf[i] = ' '; ++ ++ /* Nine 8 byte packets to be sent */ ++ /* NOTE: "\x07\x01\0\0\0\0\0\0" or "\x0c\0\0\0\0\0\0\0" ++ * will clear the VFD */ ++ for (i = 0; i < 9; i++) { ++ switch (i) { ++ case 0: ++ memcpy(context->usb_tx_buf, "\x07\0\0\0\0\0\0\0", 8); ++ context->usb_tx_buf[1] = (context->vfd_contrast) ? ++ (0x2B - (context->vfd_contrast - 1) / 250) ++ : 0x2B; ++ break; ++ case 1: ++ memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); ++ break; ++ case 2: ++ memcpy(context->usb_tx_buf, "\x0b\x01\0\0\0\0\0\0", 8); ++ break; ++ case 3: ++ memcpy(context->usb_tx_buf, context->tx.data_buf, 8); ++ break; ++ case 4: ++ memcpy(context->usb_tx_buf, ++ context->tx.data_buf + 8, 8); ++ break; ++ case 5: ++ memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); ++ break; ++ case 6: ++ memcpy(context->usb_tx_buf, "\x0b\x02\0\0\0\0\0\0", 8); ++ break; ++ case 7: ++ memcpy(context->usb_tx_buf, ++ context->tx.data_buf + 16, 8); ++ break; ++ case 8: ++ memcpy(context->usb_tx_buf, ++ context->tx.data_buf + 24, 8); ++ break; ++ } ++ retval = send_packet(context); ++ if (retval) { ++ ++ err("%s: send packet failed for packet #%d", ++ __func__, i); ++ goto exit; ++ } ++ } ++exit: ++ ++ mutex_unlock(&context->ctx_lock); ++ ++ return (!retval) ? n_bytes : retval; ++} ++ ++/** ++ * Callback function for USB core API: transmit data ++ */ ++static void usb_tx_callback(struct urb *urb) ++{ ++ struct sasem_context *context; ++ ++ if (!urb) ++ return; ++ context = (struct sasem_context *) urb->context; ++ if (!context) ++ return; ++ ++ context->tx.status = urb->status; ++ ++ /* notify waiters that write has finished */ ++ atomic_set(&context->tx.busy, 0); ++ complete(&context->tx.finished); ++ ++ return; ++} ++ ++/** ++ * Called by lirc_dev when the application opens /dev/lirc ++ */ ++static int ir_open(void *data) ++{ ++ int retval = 0; ++ struct sasem_context *context; ++ ++ /* prevent races with disconnect */ ++ mutex_lock(&disconnect_lock); ++ ++ context = (struct sasem_context *) data; ++ ++ mutex_lock(&context->ctx_lock); ++ ++ if (context->ir_isopen) { ++ err("%s: IR port is already open", __func__); ++ retval = -EBUSY; ++ goto exit; ++ } ++ ++ usb_fill_int_urb(context->rx_urb, context->dev, ++ usb_rcvintpipe(context->dev, ++ context->rx_endpoint->bEndpointAddress), ++ context->usb_rx_buf, sizeof(context->usb_rx_buf), ++ usb_rx_callback, context, context->rx_endpoint->bInterval); ++ ++ retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); ++ ++ if (retval) ++ err("%s: usb_submit_urb failed for ir_open (%d)", ++ __func__, retval); ++ else { ++ context->ir_isopen = 1; ++ printk(KERN_INFO "IR port opened\n"); ++ } ++ ++exit: ++ mutex_unlock(&context->ctx_lock); ++ ++ mutex_unlock(&disconnect_lock); ++ return 0; ++} ++ ++/** ++ * Called by lirc_dev when the application closes /dev/lirc ++ */ ++static void ir_close(void *data) ++{ ++ struct sasem_context *context; ++ ++ context = (struct sasem_context *)data; ++ if (!context) { ++ err("%s: no context for device", __func__); ++ return; ++ } ++ ++ mutex_lock(&context->ctx_lock); ++ ++ usb_kill_urb(context->rx_urb); ++ context->ir_isopen = 0; ++ printk(KERN_INFO "IR port closed\n"); ++ ++ if (!context->dev_present) { ++ ++ /* ++ * Device disconnected while IR port was ++ * still open. Driver was not deregistered ++ * at disconnect time, so do it now. ++ */ ++ deregister_from_lirc(context); ++ ++ if (!context->vfd_isopen) { ++ ++ mutex_unlock(&context->ctx_lock); ++ delete_context(context); ++ return; ++ } ++ /* If VFD port is open, context will be deleted by vfd_close */ ++ } ++ ++ mutex_unlock(&context->ctx_lock); ++ return; ++} ++ ++/** ++ * Process the incoming packet ++ */ ++static void incoming_packet(struct sasem_context *context, ++ struct urb *urb) ++{ ++ int len = urb->actual_length; ++ unsigned char *buf = urb->transfer_buffer; ++ long ms; ++ struct timeval tv; ++ ++ if (len != 8) { ++ printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n", ++ __func__, len); ++ return; ++ } ++ ++#ifdef DEBUG ++ int i; ++ for (i = 0; i < 8; ++i) ++ printk(KERN_INFO "%02x ", buf[i]); ++ printk(KERN_INFO "\n"); ++#endif ++ ++ /* ++ * Lirc could deal with the repeat code, but we really need to block it ++ * if it arrives too late. Otherwise we could repeat the wrong code. ++ */ ++ ++ /* get the time since the last button press */ ++ do_gettimeofday(&tv); ++ ms = (tv.tv_sec - context->presstime.tv_sec) * 1000 + ++ (tv.tv_usec - context->presstime.tv_usec) / 1000; ++ ++ if (memcmp(buf, "\x08\0\0\0\0\0\0\0", 8) == 0) { ++ /* ++ * the repeat code is being sent, so we copy ++ * the old code to LIRC ++ */ ++ ++ /* ++ * NOTE: Only if the last code was less than 250ms ago ++ * - no one should be able to push another (undetected) button ++ * in that time and then get a false repeat of the previous ++ * press but it is long enough for a genuine repeat ++ */ ++ if ((ms < 250) && (context->codesaved != 0)) { ++ memcpy(buf, &context->lastcode, 8); ++ context->presstime.tv_sec = tv.tv_sec; ++ context->presstime.tv_usec = tv.tv_usec; ++ } ++ } else { ++ /* save the current valid code for repeats */ ++ memcpy(&context->lastcode, buf, 8); ++ /* ++ * set flag to signal a valid code was save; ++ * just for safety reasons ++ */ ++ context->codesaved = 1; ++ context->presstime.tv_sec = tv.tv_sec; ++ context->presstime.tv_usec = tv.tv_usec; ++ } ++ ++ lirc_buffer_write(context->driver->rbuf, buf); ++ wake_up(&context->driver->rbuf->wait_poll); ++} ++ ++/** ++ * Callback function for USB core API: receive data ++ */ ++static void usb_rx_callback(struct urb *urb) ++{ ++ struct sasem_context *context; ++ ++ if (!urb) ++ return; ++ context = (struct sasem_context *) urb->context; ++ if (!context) ++ return; ++ ++ switch (urb->status) { ++ ++ case -ENOENT: /* usbcore unlink successful! */ ++ return; ++ ++ case 0: ++ if (context->ir_isopen) ++ incoming_packet(context, urb); ++ break; ++ ++ default: ++ printk(KERN_WARNING "%s: status (%d): ignored", ++ __func__, urb->status); ++ break; ++ } ++ ++ usb_submit_urb(context->rx_urb, GFP_ATOMIC); ++ return; ++} ++ ++ ++ ++/** ++ * Callback function for USB core API: Probe ++ */ ++static int sasem_probe(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *dev = NULL; ++ struct usb_host_interface *iface_desc = NULL; ++ struct usb_endpoint_descriptor *rx_endpoint = NULL; ++ struct usb_endpoint_descriptor *tx_endpoint = NULL; ++ struct urb *rx_urb = NULL; ++ struct urb *tx_urb = NULL; ++ struct lirc_driver *driver = NULL; ++ struct lirc_buffer *rbuf = NULL; ++ int lirc_minor = 0; ++ int num_endpoints; ++ int retval = 0; ++ int vfd_ep_found; ++ int ir_ep_found; ++ int alloc_status; ++ struct sasem_context *context = NULL; ++ int i; ++ ++ printk(KERN_INFO "%s: found Sasem device\n", __func__); ++ ++ ++ dev = usb_get_dev(interface_to_usbdev(interface)); ++ iface_desc = interface->cur_altsetting; ++ num_endpoints = iface_desc->desc.bNumEndpoints; ++ ++ /* ++ * Scan the endpoint list and set: ++ * first input endpoint = IR endpoint ++ * first output endpoint = VFD endpoint ++ */ ++ ++ ir_ep_found = 0; ++ vfd_ep_found = 0; ++ ++ for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { ++ ++ struct usb_endpoint_descriptor *ep; ++ int ep_dir; ++ int ep_type; ++ ep = &iface_desc->endpoint [i].desc; ++ ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ++ ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ ++ if (!ir_ep_found && ++ ep_dir == USB_DIR_IN && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ ++ rx_endpoint = ep; ++ ir_ep_found = 1; ++ if (debug) ++ printk(KERN_INFO "%s: found IR endpoint\n", ++ __func__); ++ ++ } else if (!vfd_ep_found && ++ ep_dir == USB_DIR_OUT && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ ++ tx_endpoint = ep; ++ vfd_ep_found = 1; ++ if (debug) ++ printk(KERN_INFO "%s: found VFD endpoint\n", ++ __func__); ++ } ++ } ++ ++ /* Input endpoint is mandatory */ ++ if (!ir_ep_found) { ++ ++ err("%s: no valid input (IR) endpoint found.", __func__); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ if (!vfd_ep_found) ++ printk(KERN_INFO "%s: no valid output (VFD) endpoint found.\n", ++ __func__); ++ ++ ++ /* Allocate memory */ ++ alloc_status = 0; ++ ++ context = kzalloc(sizeof(struct sasem_context), GFP_KERNEL); ++ if (!context) { ++ err("%s: kzalloc failed for context", __func__); ++ alloc_status = 1; ++ goto alloc_status_switch; ++ } ++ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ if (!driver) { ++ err("%s: kzalloc failed for lirc_driver", __func__); ++ alloc_status = 2; ++ goto alloc_status_switch; ++ } ++ rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!rbuf) { ++ err("%s: kmalloc failed for lirc_buffer", __func__); ++ alloc_status = 3; ++ goto alloc_status_switch; ++ } ++ if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { ++ err("%s: lirc_buffer_init failed", __func__); ++ alloc_status = 4; ++ goto alloc_status_switch; ++ } ++ rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!rx_urb) { ++ err("%s: usb_alloc_urb failed for IR urb", __func__); ++ alloc_status = 5; ++ goto alloc_status_switch; ++ } ++ if (vfd_ep_found) { ++ tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!tx_urb) { ++ err("%s: usb_alloc_urb failed for VFD urb", ++ __func__); ++ alloc_status = 6; ++ goto alloc_status_switch; ++ } ++ } ++ ++ mutex_init(&context->ctx_lock); ++ ++ strcpy(driver->name, MOD_NAME); ++ driver->minor = -1; ++ driver->code_length = 64; ++ driver->sample_rate = 0; ++ driver->features = LIRC_CAN_REC_LIRCCODE; ++ driver->data = context; ++ driver->rbuf = rbuf; ++ driver->set_use_inc = ir_open; ++ driver->set_use_dec = ir_close; ++ driver->dev = &interface->dev; ++ driver->owner = THIS_MODULE; ++ ++ mutex_lock(&context->ctx_lock); ++ ++ lirc_minor = lirc_register_driver(driver); ++ if (lirc_minor < 0) { ++ err("%s: lirc_register_driver failed", __func__); ++ alloc_status = 7; ++ mutex_unlock(&context->ctx_lock); ++ } else ++ printk(KERN_INFO "%s: Registered Sasem driver (minor:%d)\n", ++ __func__, lirc_minor); ++ ++alloc_status_switch: ++ ++ switch (alloc_status) { ++ ++ case 7: ++ if (vfd_ep_found) ++ usb_free_urb(tx_urb); ++ case 6: ++ usb_free_urb(rx_urb); ++ case 5: ++ lirc_buffer_free(rbuf); ++ case 4: ++ kfree(rbuf); ++ case 3: ++ kfree(driver); ++ case 2: ++ kfree(context); ++ context = NULL; ++ case 1: ++ retval = -ENOMEM; ++ goto exit; ++ } ++ ++ /* Needed while unregistering! */ ++ driver->minor = lirc_minor; ++ ++ context->dev = dev; ++ context->dev_present = 1; ++ context->rx_endpoint = rx_endpoint; ++ context->rx_urb = rx_urb; ++ if (vfd_ep_found) { ++ context->tx_endpoint = tx_endpoint; ++ context->tx_urb = tx_urb; ++ context->vfd_contrast = 1000; /* range 0 - 1000 */ ++ } ++ context->driver = driver; ++ ++ usb_set_intfdata(interface, context); ++ ++ if (vfd_ep_found) { ++ ++ if (debug) ++ printk(KERN_INFO "Registering VFD with sysfs\n"); ++ if (usb_register_dev(interface, &sasem_class)) ++ /* Not a fatal error, so ignore */ ++ printk(KERN_INFO "%s: could not get a minor number " ++ "for VFD\n", __func__); ++ } ++ ++ printk(KERN_INFO "%s: Sasem device on usb<%d:%d> initialized\n", ++ __func__, dev->bus->busnum, dev->devnum); ++ ++ mutex_unlock(&context->ctx_lock); ++exit: ++ return retval; ++} ++ ++/** ++ * Callback function for USB core API: disonnect ++ */ ++static void sasem_disconnect(struct usb_interface *interface) ++{ ++ struct sasem_context *context; ++ ++ /* prevent races with ir_open()/vfd_open() */ ++ mutex_lock(&disconnect_lock); ++ ++ context = usb_get_intfdata(interface); ++ mutex_lock(&context->ctx_lock); ++ ++ printk(KERN_INFO "%s: Sasem device disconnected\n", __func__); ++ ++ usb_set_intfdata(interface, NULL); ++ context->dev_present = 0; ++ ++ /* Stop reception */ ++ usb_kill_urb(context->rx_urb); ++ ++ /* Abort ongoing write */ ++ if (atomic_read(&context->tx.busy)) { ++ ++ usb_kill_urb(context->tx_urb); ++ wait_for_completion(&context->tx.finished); ++ } ++ ++ /* De-register from lirc_dev if IR port is not open */ ++ if (!context->ir_isopen) ++ deregister_from_lirc(context); ++ ++ usb_deregister_dev(interface, &sasem_class); ++ ++ mutex_unlock(&context->ctx_lock); ++ ++ if (!context->ir_isopen && !context->vfd_isopen) ++ delete_context(context); ++ ++ mutex_unlock(&disconnect_lock); ++} ++ ++static int __init sasem_init(void) ++{ ++ int rc; ++ ++ printk(KERN_INFO MOD_DESC ", v" MOD_VERSION "\n"); ++ printk(KERN_INFO MOD_AUTHOR "\n"); ++ ++ rc = usb_register(&sasem_driver); ++ if (rc < 0) { ++ err("%s: usb register failed (%d)", __func__, rc); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++static void __exit sasem_exit(void) ++{ ++ usb_deregister(&sasem_driver); ++ printk(KERN_INFO "module removed. Goodbye!\n"); ++} ++ ++ ++module_init(sasem_init); ++module_exit(sasem_exit); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_serial.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_serial.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_serial.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_serial.c 2010-08-02 09:28:03.961924699 +0200 +@@ -0,0 +1,1317 @@ ++/* ++ * lirc_serial.c ++ * ++ * lirc_serial - Device driver that records pulse- and pause-lengths ++ * (space-lengths) between DDCD event on a serial port. ++ * ++ * Copyright (C) 1996,97 Ralph Metzler ++ * Copyright (C) 1998 Trent Piepho ++ * Copyright (C) 1998 Ben Pfaff ++ * Copyright (C) 1999 Christoph Bartelmus ++ * Copyright (C) 2007 Andrei Tanas (suspend/resume support) ++ * 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 ++ * ++ */ ++ ++/* ++ * Steve's changes to improve transmission fidelity: ++ * - for systems with the rdtsc instruction and the clock counter, a ++ * send_pule that times the pulses directly using the counter. ++ * This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is ++ * not needed. Measurement shows very stable waveform, even where ++ * PCI activity slows the access to the UART, which trips up other ++ * versions. ++ * - For other system, non-integer-microsecond pulse/space lengths, ++ * done using fixed point binary. So, much more accurate carrier ++ * frequency. ++ * - fine tuned transmitter latency, taking advantage of fractional ++ * microseconds in previous change ++ * - Fixed bug in the way transmitter latency was accounted for by ++ * tuning the pulse lengths down - the send_pulse routine ignored ++ * this overhead as it timed the overall pulse length - so the ++ * pulse frequency was right but overall pulse length was too ++ * long. Fixed by accounting for latency on each pulse/space ++ * iteration. ++ * ++ * Steve Davies July 2001 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++#include ++#endif ++/* From Intel IXP42X Developer's Manual (#252480-005): */ ++/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ ++#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ ++#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ ++ ++#include ++#include "lirc_dev.h" ++ ++#define LIRC_DRIVER_NAME "lirc_serial" ++ ++struct lirc_serial { ++ int signal_pin; ++ int signal_pin_change; ++ u8 on; ++ u8 off; ++ long (*send_pulse)(unsigned long length); ++ void (*send_space)(long length); ++ int features; ++ spinlock_t lock; ++}; ++ ++#define LIRC_HOMEBREW 0 ++#define LIRC_IRDEO 1 ++#define LIRC_IRDEO_REMOTE 2 ++#define LIRC_ANIMAX 3 ++#define LIRC_IGOR 4 ++#define LIRC_NSLU2 5 ++ ++/*** module parameters ***/ ++static int type; ++static int io; ++static int irq; ++static int iommap; ++static int ioshift; ++static int softcarrier = 1; ++static int share_irq; ++static int debug; ++static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ ++static int txsense; /* 0 = active high, 1 = active low */ ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ ++ fmt, ## args); \ ++ } while (0) ++ ++/* forward declarations */ ++static long send_pulse_irdeo(unsigned long length); ++static long send_pulse_homebrew(unsigned long length); ++static void send_space_irdeo(long length); ++static void send_space_homebrew(long length); ++ ++static struct lirc_serial hardware[] = { ++ [LIRC_HOMEBREW] = { ++ .signal_pin = UART_MSR_DCD, ++ .signal_pin_change = UART_MSR_DDCD, ++ .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), ++ .off = (UART_MCR_RTS | UART_MCR_OUT2), ++ .send_pulse = send_pulse_homebrew, ++ .send_space = send_space_homebrew, ++#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER ++ .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SET_SEND_CARRIER | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) ++#else ++ .features = LIRC_CAN_REC_MODE2 ++#endif ++ }, ++ ++ [LIRC_IRDEO] = { ++ .signal_pin = UART_MSR_DSR, ++ .signal_pin_change = UART_MSR_DDSR, ++ .on = UART_MCR_OUT2, ++ .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), ++ .send_pulse = send_pulse_irdeo, ++ .send_space = send_space_irdeo, ++ .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) ++ }, ++ ++ [LIRC_IRDEO_REMOTE] = { ++ .signal_pin = UART_MSR_DSR, ++ .signal_pin_change = UART_MSR_DDSR, ++ .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), ++ .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), ++ .send_pulse = send_pulse_irdeo, ++ .send_space = send_space_irdeo, ++ .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) ++ }, ++ ++ [LIRC_ANIMAX] = { ++ .signal_pin = UART_MSR_DCD, ++ .signal_pin_change = UART_MSR_DDCD, ++ .on = 0, ++ .off = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), ++ .send_pulse = NULL, ++ .send_space = NULL, ++ .features = LIRC_CAN_REC_MODE2 ++ }, ++ ++ [LIRC_IGOR] = { ++ .signal_pin = UART_MSR_DSR, ++ .signal_pin_change = UART_MSR_DDSR, ++ .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), ++ .off = (UART_MCR_RTS | UART_MCR_OUT2), ++ .send_pulse = send_pulse_homebrew, ++ .send_space = send_space_homebrew, ++#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER ++ .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SET_SEND_CARRIER | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) ++#else ++ .features = LIRC_CAN_REC_MODE2 ++#endif ++ }, ++ ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ /* ++ * Modified Linksys Network Storage Link USB 2.0 (NSLU2): ++ * We receive on CTS of the 2nd serial port (R142,LHS), we ++ * transmit with a IR diode between GPIO[1] (green status LED), ++ * and ground (Matthias Goebl ). ++ * See also http://www.nslu2-linux.org for this device ++ */ ++ [LIRC_NSLU2] = { ++ .signal_pin = UART_MSR_CTS, ++ .signal_pin_change = UART_MSR_DCTS, ++ .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), ++ .off = (UART_MCR_RTS | UART_MCR_OUT2), ++ .send_pulse = send_pulse_homebrew, ++ .send_space = send_space_homebrew, ++#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER ++ .features = (LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SET_SEND_CARRIER | ++ LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2) ++#else ++ .features = LIRC_CAN_REC_MODE2 ++#endif ++ }, ++#endif ++ ++}; ++ ++#define RS_ISR_PASS_LIMIT 256 ++ ++/* ++ * A long pulse code from a remote might take up to 300 bytes. The ++ * daemon should read the bytes as soon as they are generated, so take ++ * the number of keys you think you can push before the daemon runs ++ * and multiply by 300. The driver will warn you if you overrun this ++ * buffer. If you have a slow computer or non-busmastering IDE disks, ++ * maybe you will need to increase this. ++ */ ++ ++/* This MUST be a power of two! It has to be larger than 1 as well. */ ++ ++#define RBUF_LEN 256 ++#define WBUF_LEN 256 ++ ++static struct timeval lasttv = {0, 0}; ++ ++static struct lirc_buffer rbuf; ++ ++static int wbuf[WBUF_LEN]; ++ ++static unsigned int freq = 38000; ++static unsigned int duty_cycle = 50; ++ ++/* Initialized in init_timing_params() */ ++static unsigned long period; ++static unsigned long pulse_width; ++static unsigned long space_width; ++ ++#if defined(__i386__) ++/* ++ * From: ++ * Linux I/O port programming mini-HOWTO ++ * Author: Riku Saikkonen ++ * v, 28 December 1997 ++ * ++ * [...] ++ * Actually, a port I/O instruction on most ports in the 0-0x3ff range ++ * takes almost exactly 1 microsecond, so if you're, for example, using ++ * the parallel port directly, just do additional inb()s from that port ++ * to delay. ++ * [...] ++ */ ++/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from ++ * comment above plus trimming to match actual measured frequency. ++ * This will be sensitive to cpu speed, though hopefully most of the 1.5us ++ * is spent in the uart access. Still - for reference test machine was a ++ * 1.13GHz Athlon system - Steve ++ */ ++ ++/* ++ * changed from 400 to 450 as this works better on slower machines; ++ * faster machines will use the rdtsc code anyway ++ */ ++#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 ++ ++#else ++ ++/* does anybody have information on other platforms ? */ ++/* 256 = 1<<8 */ ++#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 ++ ++#endif /* __i386__ */ ++/* ++ * FIXME: should we be using hrtimers instead of this ++ * LIRC_SERIAL_TRANSMITTER_LATENCY nonsense? ++ */ ++ ++/* fetch serial input packet (1 byte) from register offset */ ++static u8 sinp(int offset) ++{ ++ if (iommap != 0) ++ /* the register is memory-mapped */ ++ offset <<= ioshift; ++ ++ return inb(io + offset); ++} ++ ++/* write serial output packet (1 byte) of value to register offset */ ++static void soutp(int offset, u8 value) ++{ ++ if (iommap != 0) ++ /* the register is memory-mapped */ ++ offset <<= ioshift; ++ ++ outb(value, io + offset); ++} ++ ++static void on(void) ++{ ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ /* ++ * On NSLU2, we put the transmit diode between the output of the green ++ * status LED and ground ++ */ ++ if (type == LIRC_NSLU2) { ++ gpio_line_set(NSLU2_LED_GRN, IXP4XX_GPIO_LOW); ++ return; ++ } ++#endif ++ if (txsense) ++ soutp(UART_MCR, hardware[type].off); ++ else ++ soutp(UART_MCR, hardware[type].on); ++} ++ ++static void off(void) ++{ ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ if (type == LIRC_NSLU2) { ++ gpio_line_set(NSLU2_LED_GRN, IXP4XX_GPIO_HIGH); ++ return; ++ } ++#endif ++ if (txsense) ++ soutp(UART_MCR, hardware[type].on); ++ else ++ soutp(UART_MCR, hardware[type].off); ++} ++ ++#ifndef MAX_UDELAY_MS ++#define MAX_UDELAY_US 5000 ++#else ++#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) ++#endif ++ ++static void safe_udelay(unsigned long usecs) ++{ ++ while (usecs > MAX_UDELAY_US) { ++ udelay(MAX_UDELAY_US); ++ usecs -= MAX_UDELAY_US; ++ } ++ udelay(usecs); ++} ++ ++#ifdef USE_RDTSC ++/* ++ * This is an overflow/precision juggle, complicated in that we can't ++ * do long long divide in the kernel ++ */ ++ ++/* ++ * When we use the rdtsc instruction to measure clocks, we keep the ++ * pulse and space widths as clock cycles. As this is CPU speed ++ * dependent, the widths must be calculated in init_port and ioctl ++ * time ++ */ ++ ++/* So send_pulse can quickly convert microseconds to clocks */ ++static unsigned long conv_us_to_clocks; ++ ++static int init_timing_params(unsigned int new_duty_cycle, ++ unsigned int new_freq) ++{ ++ unsigned long long loops_per_sec, work; ++ ++ duty_cycle = new_duty_cycle; ++ freq = new_freq; ++ ++ loops_per_sec = current_cpu_data.loops_per_jiffy; ++ loops_per_sec *= HZ; ++ ++ /* How many clocks in a microsecond?, avoiding long long divide */ ++ work = loops_per_sec; ++ work *= 4295; /* 4295 = 2^32 / 1e6 */ ++ conv_us_to_clocks = (work >> 32); ++ ++ /* ++ * Carrier period in clocks, approach good up to 32GHz clock, ++ * gets carrier frequency within 8Hz ++ */ ++ period = loops_per_sec >> 3; ++ period /= (freq >> 3); ++ ++ /* Derive pulse and space from the period */ ++ pulse_width = period * duty_cycle / 100; ++ space_width = period - pulse_width; ++ dprintk("in init_timing_params, freq=%d, duty_cycle=%d, " ++ "clk/jiffy=%ld, pulse=%ld, space=%ld, " ++ "conv_us_to_clocks=%ld\n", ++ freq, duty_cycle, current_cpu_data.loops_per_jiffy, ++ pulse_width, space_width, conv_us_to_clocks); ++ return 0; ++} ++#else /* ! USE_RDTSC */ ++static int init_timing_params(unsigned int new_duty_cycle, ++ unsigned int new_freq) ++{ ++/* ++ * period, pulse/space width are kept with 8 binary places - ++ * IE multiplied by 256. ++ */ ++ if (256 * 1000000L / new_freq * new_duty_cycle / 100 <= ++ LIRC_SERIAL_TRANSMITTER_LATENCY) ++ return -EINVAL; ++ if (256 * 1000000L / new_freq * (100 - new_duty_cycle) / 100 <= ++ LIRC_SERIAL_TRANSMITTER_LATENCY) ++ return -EINVAL; ++ duty_cycle = new_duty_cycle; ++ freq = new_freq; ++ period = 256 * 1000000L / freq; ++ pulse_width = period * duty_cycle / 100; ++ space_width = period - pulse_width; ++ dprintk("in init_timing_params, freq=%d pulse=%ld, " ++ "space=%ld\n", freq, pulse_width, space_width); ++ return 0; ++} ++#endif /* USE_RDTSC */ ++ ++ ++/* return value: space length delta */ ++ ++static long send_pulse_irdeo(unsigned long length) ++{ ++ long rawbits, ret; ++ int i; ++ unsigned char output; ++ unsigned char chunk, shifted; ++ ++ /* how many bits have to be sent ? */ ++ rawbits = length * 1152 / 10000; ++ if (duty_cycle > 50) ++ chunk = 3; ++ else ++ chunk = 1; ++ for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { ++ shifted = chunk << (i * 3); ++ shifted >>= 1; ++ output &= (~shifted); ++ i++; ++ if (i == 3) { ++ soutp(UART_TX, output); ++ while (!(sinp(UART_LSR) & UART_LSR_THRE)) ++ ; ++ output = 0x7f; ++ i = 0; ++ } ++ } ++ if (i != 0) { ++ soutp(UART_TX, output); ++ while (!(sinp(UART_LSR) & UART_LSR_TEMT)) ++ ; ++ } ++ ++ if (i == 0) ++ ret = (-rawbits) * 10000 / 1152; ++ else ++ ret = (3 - i) * 3 * 10000 / 1152 + (-rawbits) * 10000 / 1152; ++ ++ return ret; ++} ++ ++#ifdef USE_RDTSC ++/* Version that uses Pentium rdtsc instruction to measure clocks */ ++ ++/* ++ * This version does sub-microsecond timing using rdtsc instruction, ++ * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY ++ * Implicitly i586 architecture... - Steve ++ */ ++ ++static long send_pulse_homebrew_softcarrier(unsigned long length) ++{ ++ int flag; ++ unsigned long target, start, now; ++ ++ /* Get going quick as we can */ ++ rdtscl(start); ++ on(); ++ /* Convert length from microseconds to clocks */ ++ length *= conv_us_to_clocks; ++ /* And loop till time is up - flipping at right intervals */ ++ now = start; ++ target = pulse_width; ++ flag = 1; ++ /* ++ * FIXME: This looks like a hard busy wait, without even an occasional, ++ * polite, cpu_relax() call. There's got to be a better way? ++ * ++ * The i2c code has the result of a lot of bit-banging work, I wonder if ++ * there's something there which could be helpful here. ++ */ ++ while ((now - start) < length) { ++ /* Delay till flip time */ ++ do { ++ rdtscl(now); ++ } while ((now - start) < target); ++ ++ /* flip */ ++ if (flag) { ++ rdtscl(now); ++ off(); ++ target += space_width; ++ } else { ++ rdtscl(now); on(); ++ target += pulse_width; ++ } ++ flag = !flag; ++ } ++ rdtscl(now); ++ return ((now - start) - length) / conv_us_to_clocks; ++} ++#else /* ! USE_RDTSC */ ++/* Version using udelay() */ ++ ++/* ++ * here we use fixed point arithmetic, with 8 ++ * fractional bits. that gets us within 0.1% or so of the right average ++ * frequency, albeit with some jitter in pulse length - Steve ++ */ ++ ++/* To match 8 fractional bits used for pulse/space length */ ++ ++static long send_pulse_homebrew_softcarrier(unsigned long length) ++{ ++ int flag; ++ unsigned long actual, target, d; ++ length <<= 8; ++ ++ actual = 0; target = 0; flag = 0; ++ while (actual < length) { ++ if (flag) { ++ off(); ++ target += space_width; ++ } else { ++ on(); ++ target += pulse_width; ++ } ++ d = (target - actual - ++ LIRC_SERIAL_TRANSMITTER_LATENCY + 128) >> 8; ++ /* ++ * Note - we've checked in ioctl that the pulse/space ++ * widths are big enough so that d is > 0 ++ */ ++ udelay(d); ++ actual += (d << 8) + LIRC_SERIAL_TRANSMITTER_LATENCY; ++ flag = !flag; ++ } ++ return (actual-length) >> 8; ++} ++#endif /* USE_RDTSC */ ++ ++static long send_pulse_homebrew(unsigned long length) ++{ ++ if (length <= 0) ++ return 0; ++ ++ if (softcarrier) ++ return send_pulse_homebrew_softcarrier(length); ++ else { ++ on(); ++ safe_udelay(length); ++ return 0; ++ } ++} ++ ++static void send_space_irdeo(long length) ++{ ++ if (length <= 0) ++ return; ++ ++ safe_udelay(length); ++} ++ ++static void send_space_homebrew(long length) ++{ ++ off(); ++ if (length <= 0) ++ return; ++ safe_udelay(length); ++} ++ ++static void rbwrite(int l) ++{ ++ if (lirc_buffer_full(&rbuf)) { ++ /* no new signals will be accepted */ ++ dprintk("Buffer overrun\n"); ++ return; ++ } ++ lirc_buffer_write(&rbuf, (void *)&l); ++} ++ ++static void frbwrite(int l) ++{ ++ /* simple noise filter */ ++ static int pulse, space; ++ static unsigned int ptr; ++ ++ if (ptr > 0 && (l & PULSE_BIT)) { ++ pulse += l & PULSE_MASK; ++ if (pulse > 250) { ++ rbwrite(space); ++ rbwrite(pulse | PULSE_BIT); ++ ptr = 0; ++ pulse = 0; ++ } ++ return; ++ } ++ if (!(l & PULSE_BIT)) { ++ if (ptr == 0) { ++ if (l > 20000) { ++ space = l; ++ ptr++; ++ return; ++ } ++ } else { ++ if (l > 20000) { ++ space += pulse; ++ if (space > PULSE_MASK) ++ space = PULSE_MASK; ++ space += l; ++ if (space > PULSE_MASK) ++ space = PULSE_MASK; ++ pulse = 0; ++ return; ++ } ++ rbwrite(space); ++ rbwrite(pulse | PULSE_BIT); ++ ptr = 0; ++ pulse = 0; ++ } ++ } ++ rbwrite(l); ++} ++ ++static irqreturn_t irq_handler(int i, void *blah) ++{ ++ struct timeval tv; ++ int counter, dcd; ++ u8 status; ++ long deltv; ++ int data; ++ static int last_dcd = -1; ++ ++ if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { ++ /* not our interrupt */ ++ return IRQ_NONE; ++ } ++ ++ counter = 0; ++ do { ++ counter++; ++ status = sinp(UART_MSR); ++ if (counter > RS_ISR_PASS_LIMIT) { ++ printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: " ++ "We're caught!\n"); ++ break; ++ } ++ if ((status & hardware[type].signal_pin_change) ++ && sense != -1) { ++ /* get current time */ ++ do_gettimeofday(&tv); ++ ++ /* New mode, written by Trent Piepho ++ . */ ++ ++ /* ++ * The old format was not very portable. ++ * We now use an int to pass pulses ++ * and spaces to user space. ++ * ++ * If PULSE_BIT is set a pulse has been ++ * received, otherwise a space has been ++ * received. The driver needs to know if your ++ * receiver is active high or active low, or ++ * the space/pulse sense could be ++ * inverted. The bits denoted by PULSE_MASK are ++ * the length in microseconds. Lengths greater ++ * than or equal to 16 seconds are clamped to ++ * PULSE_MASK. All other bits are unused. ++ * This is a much simpler interface for user ++ * programs, as well as eliminating "out of ++ * phase" errors with space/pulse ++ * autodetection. ++ */ ++ ++ /* calc time since last interrupt in microseconds */ ++ dcd = (status & hardware[type].signal_pin) ? 1 : 0; ++ ++ if (dcd == last_dcd) { ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": ignoring spike: %d %d %lx %lx %lx %lx\n", ++ dcd, sense, ++ tv.tv_sec, lasttv.tv_sec, ++ tv.tv_usec, lasttv.tv_usec); ++ continue; ++ } ++ ++ deltv = tv.tv_sec-lasttv.tv_sec; ++ if (tv.tv_sec < lasttv.tv_sec || ++ (tv.tv_sec == lasttv.tv_sec && ++ tv.tv_usec < lasttv.tv_usec)) { ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": AIEEEE: your clock just jumped " ++ "backwards\n"); ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": %d %d %lx %lx %lx %lx\n", ++ dcd, sense, ++ tv.tv_sec, lasttv.tv_sec, ++ tv.tv_usec, lasttv.tv_usec); ++ data = PULSE_MASK; ++ } else if (deltv > 15) { ++ data = PULSE_MASK; /* really long time */ ++ if (!(dcd^sense)) { ++ /* sanity check */ ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": AIEEEE: " ++ "%d %d %lx %lx %lx %lx\n", ++ dcd, sense, ++ tv.tv_sec, lasttv.tv_sec, ++ tv.tv_usec, lasttv.tv_usec); ++ /* ++ * detecting pulse while this ++ * MUST be a space! ++ */ ++ sense = sense ? 0 : 1; ++ } ++ } else ++ data = (int) (deltv*1000000 + ++ tv.tv_usec - ++ lasttv.tv_usec); ++ frbwrite(dcd^sense ? data : (data|PULSE_BIT)); ++ lasttv = tv; ++ last_dcd = dcd; ++ wake_up_interruptible(&rbuf.wait_poll); ++ } ++ } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ ++ return IRQ_HANDLED; ++} ++ ++ ++static int hardware_init_port(void) ++{ ++ u8 scratch, scratch2, scratch3; ++ ++ /* ++ * This is a simple port existence test, borrowed from the autoconfig ++ * function in drivers/serial/8250.c ++ */ ++ scratch = sinp(UART_IER); ++ soutp(UART_IER, 0); ++#ifdef __i386__ ++ outb(0xff, 0x080); ++#endif ++ scratch2 = sinp(UART_IER) & 0x0f; ++ soutp(UART_IER, 0x0f); ++#ifdef __i386__ ++ outb(0x00, 0x080); ++#endif ++ scratch3 = sinp(UART_IER) & 0x0f; ++ soutp(UART_IER, scratch); ++ if (scratch2 != 0 || scratch3 != 0x0f) { ++ /* we fail, there's nothing here */ ++ printk(KERN_ERR LIRC_DRIVER_NAME ": port existence test " ++ "failed, cannot continue\n"); ++ return -EINVAL; ++ } ++ ++ ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* First of all, disable all interrupts */ ++ soutp(UART_IER, sinp(UART_IER) & ++ (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); ++ ++ /* Clear registers. */ ++ sinp(UART_LSR); ++ sinp(UART_RX); ++ sinp(UART_IIR); ++ sinp(UART_MSR); ++ ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ if (type == LIRC_NSLU2) { ++ /* Setup NSLU2 UART */ ++ ++ /* Enable UART */ ++ soutp(UART_IER, sinp(UART_IER) | UART_IE_IXP42X_UUE); ++ /* Disable Receiver data Time out interrupt */ ++ soutp(UART_IER, sinp(UART_IER) & ~UART_IE_IXP42X_RTOIE); ++ /* set out2 = interrupt unmask; off() doesn't set MCR ++ on NSLU2 */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); ++ } ++#endif ++ ++ /* Set line for power source */ ++ off(); ++ ++ /* Clear registers again to be sure. */ ++ sinp(UART_LSR); ++ sinp(UART_RX); ++ sinp(UART_IIR); ++ sinp(UART_MSR); ++ ++ switch (type) { ++ case LIRC_IRDEO: ++ case LIRC_IRDEO_REMOTE: ++ /* setup port to 7N1 @ 115200 Baud */ ++ /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); ++ /* Set divisor to 1 => 115200 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 1); ++ /* Set DLAB 0 + 7N1 */ ++ soutp(UART_LCR, UART_LCR_WLEN7); ++ /* THR interrupt already disabled at this point */ ++ break; ++ default: ++ break; ++ } ++ ++ return 0; ++} ++ ++static int init_port(void) ++{ ++ int i, nlow, nhigh; ++ ++ /* Reserve io region. */ ++ /* ++ * Future MMAP-Developers: Attention! ++ * For memory mapped I/O you *might* need to use ioremap() first, ++ * for the NSLU2 it's done in boot code. ++ */ ++ if (((iommap != 0) ++ && (request_mem_region(iommap, 8 << ioshift, ++ LIRC_DRIVER_NAME) == NULL)) ++ || ((iommap == 0) ++ && (request_region(io, 8, LIRC_DRIVER_NAME) == NULL))) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": port %04x already in use\n", io); ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": use 'setserial /dev/ttySX uart none'\n"); ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": or compile the serial port driver as module and\n"); ++ printk(KERN_WARNING LIRC_DRIVER_NAME ++ ": make sure this module is loaded first\n"); ++ return -EBUSY; ++ } ++ ++ if (hardware_init_port() < 0) ++ return -EINVAL; ++ ++ /* Initialize pulse/space widths */ ++ init_timing_params(duty_cycle, freq); ++ ++ /* If pin is high, then this must be an active low receiver. */ ++ if (sense == -1) { ++ /* wait 1/2 sec for the power supply */ ++ msleep(500); ++ ++ /* ++ * probe 9 times every 0.04s, collect "votes" for ++ * active high/low ++ */ ++ nlow = 0; ++ nhigh = 0; ++ for (i = 0; i < 9; i++) { ++ if (sinp(UART_MSR) & hardware[type].signal_pin) ++ nlow++; ++ else ++ nhigh++; ++ msleep(40); ++ } ++ sense = (nlow >= nhigh ? 1 : 0); ++ printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " ++ "%s receiver\n", sense ? "low" : "high"); ++ } else ++ printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " ++ "%s receiver\n", sense ? "low" : "high"); ++ ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ int result; ++ unsigned long flags; ++ ++ /* initialize timestamp */ ++ do_gettimeofday(&lasttv); ++ ++ result = request_irq(irq, irq_handler, ++ IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), ++ LIRC_DRIVER_NAME, (void *)&hardware); ++ ++ switch (result) { ++ case -EBUSY: ++ printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); ++ return -EBUSY; ++ case -EINVAL: ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": Bad irq number or handler\n"); ++ return -EINVAL; ++ default: ++ dprintk("Interrupt %d, port %04x obtained\n", irq, io); ++ break; ++ }; ++ ++ spin_lock_irqsave(&hardware[type].lock, flags); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); ++ ++ spin_unlock_irqrestore(&hardware[type].lock, flags); ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ unsigned long flags; ++ ++ spin_lock_irqsave(&hardware[type].lock, flags); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* First of all, disable all interrupts */ ++ soutp(UART_IER, sinp(UART_IER) & ++ (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); ++ spin_unlock_irqrestore(&hardware[type].lock, flags); ++ ++ free_irq(irq, (void *)&hardware); ++ ++ dprintk("freed IRQ %d\n", irq); ++} ++ ++static ssize_t lirc_write(struct file *file, const char *buf, ++ size_t n, loff_t *ppos) ++{ ++ int i, count; ++ unsigned long flags; ++ long delta = 0; ++ ++ if (!(hardware[type].features&LIRC_CAN_SEND_PULSE)) ++ return -EBADF; ++ ++ if (n % sizeof(int)) ++ return -EINVAL; ++ count = n / sizeof(int); ++ if (count > WBUF_LEN || count % 2 == 0) ++ return -EINVAL; ++ if (copy_from_user(wbuf, buf, n)) ++ return -EFAULT; ++ spin_lock_irqsave(&hardware[type].lock, flags); ++ if (type == LIRC_IRDEO) { ++ /* DTR, RTS down */ ++ on(); ++ } ++ for (i = 0; i < count; i++) { ++ if (i%2) ++ hardware[type].send_space(wbuf[i]-delta); ++ else ++ delta = hardware[type].send_pulse(wbuf[i]); ++ } ++ off(); ++ spin_unlock_irqrestore(&hardware[type].lock, flags); ++ return n; ++} ++ ++static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, ++ unsigned long arg) ++{ ++ int result; ++ unsigned long value; ++ unsigned int ivalue; ++ ++ switch (cmd) { ++ case LIRC_GET_SEND_MODE: ++ if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) ++ return -ENOIOCTLCMD; ++ ++ result = put_user(LIRC_SEND2MODE ++ (hardware[type].features&LIRC_CAN_SEND_MASK), ++ (unsigned long *) arg); ++ if (result) ++ return result; ++ break; ++ ++ case LIRC_SET_SEND_MODE: ++ if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) ++ return -ENOIOCTLCMD; ++ ++ result = get_user(value, (unsigned long *) arg); ++ if (result) ++ return result; ++ /* only LIRC_MODE_PULSE supported */ ++ if (value != LIRC_MODE_PULSE) ++ return -ENOSYS; ++ break; ++ ++ case LIRC_GET_LENGTH: ++ return -ENOSYS; ++ break; ++ ++ case LIRC_SET_SEND_DUTY_CYCLE: ++ dprintk("SET_SEND_DUTY_CYCLE\n"); ++ if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) ++ return -ENOIOCTLCMD; ++ ++ result = get_user(ivalue, (unsigned int *) arg); ++ if (result) ++ return result; ++ if (ivalue <= 0 || ivalue > 100) ++ return -EINVAL; ++ return init_timing_params(ivalue, freq); ++ break; ++ ++ case LIRC_SET_SEND_CARRIER: ++ dprintk("SET_SEND_CARRIER\n"); ++ if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) ++ return -ENOIOCTLCMD; ++ ++ result = get_user(ivalue, (unsigned int *) arg); ++ if (result) ++ return result; ++ if (ivalue > 500000 || ivalue < 20000) ++ return -EINVAL; ++ return init_timing_params(duty_cycle, ivalue); ++ break; ++ ++ default: ++ return lirc_dev_fop_ioctl(node, filep, cmd, arg); ++ } ++ return 0; ++} ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .write = lirc_write, ++ .ioctl = lirc_ioctl, ++ .read = lirc_dev_fop_read, ++ .poll = lirc_dev_fop_poll, ++ .open = lirc_dev_fop_open, ++ .release = lirc_dev_fop_close, ++}; ++ ++static struct lirc_driver driver = { ++ .name = LIRC_DRIVER_NAME, ++ .minor = -1, ++ .code_length = 1, ++ .sample_rate = 0, ++ .data = NULL, ++ .add_to_buf = NULL, ++ .rbuf = &rbuf, ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .fops = &lirc_fops, ++ .dev = NULL, ++ .owner = THIS_MODULE, ++}; ++ ++static struct platform_device *lirc_serial_dev; ++ ++static int __devinit lirc_serial_probe(struct platform_device *dev) ++{ ++ return 0; ++} ++ ++static int __devexit lirc_serial_remove(struct platform_device *dev) ++{ ++ return 0; ++} ++ ++static int lirc_serial_suspend(struct platform_device *dev, ++ pm_message_t state) ++{ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* Disable all interrupts */ ++ soutp(UART_IER, sinp(UART_IER) & ++ (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); ++ ++ /* Clear registers. */ ++ sinp(UART_LSR); ++ sinp(UART_RX); ++ sinp(UART_IIR); ++ sinp(UART_MSR); ++ ++ return 0; ++} ++ ++/* twisty maze... need a forward-declaration here... */ ++static void lirc_serial_exit(void); ++ ++static int lirc_serial_resume(struct platform_device *dev) ++{ ++ unsigned long flags; ++ ++ if (hardware_init_port() < 0) { ++ lirc_serial_exit(); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&hardware[type].lock, flags); ++ /* Enable Interrupt */ ++ do_gettimeofday(&lasttv); ++ soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); ++ off(); ++ ++ lirc_buffer_clear(&rbuf); ++ ++ spin_unlock_irqrestore(&hardware[type].lock, flags); ++ ++ return 0; ++} ++ ++static struct platform_driver lirc_serial_driver = { ++ .probe = lirc_serial_probe, ++ .remove = __devexit_p(lirc_serial_remove), ++ .suspend = lirc_serial_suspend, ++ .resume = lirc_serial_resume, ++ .driver = { ++ .name = "lirc_serial", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++static int __init lirc_serial_init(void) ++{ ++ int result; ++ ++ /* Init read buffer. */ ++ result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN); ++ if (result < 0) ++ return -ENOMEM; ++ ++ result = platform_driver_register(&lirc_serial_driver); ++ if (result) { ++ printk("lirc register returned %d\n", result); ++ goto exit_buffer_free; ++ } ++ ++ lirc_serial_dev = platform_device_alloc("lirc_serial", 0); ++ if (!lirc_serial_dev) { ++ result = -ENOMEM; ++ goto exit_driver_unregister; ++ } ++ ++ result = platform_device_add(lirc_serial_dev); ++ if (result) ++ goto exit_device_put; ++ ++ return 0; ++ ++exit_device_put: ++ platform_device_put(lirc_serial_dev); ++exit_driver_unregister: ++ platform_driver_unregister(&lirc_serial_driver); ++exit_buffer_free: ++ lirc_buffer_free(&rbuf); ++ return result; ++} ++ ++static void lirc_serial_exit(void) ++{ ++ platform_device_unregister(lirc_serial_dev); ++ platform_driver_unregister(&lirc_serial_driver); ++ lirc_buffer_free(&rbuf); ++} ++ ++static int __init lirc_serial_init_module(void) ++{ ++ int result; ++ ++ result = lirc_serial_init(); ++ if (result) ++ return result; ++ ++ switch (type) { ++ case LIRC_HOMEBREW: ++ case LIRC_IRDEO: ++ case LIRC_IRDEO_REMOTE: ++ case LIRC_ANIMAX: ++ case LIRC_IGOR: ++ /* if nothing specified, use ttyS0/com1 and irq 4 */ ++ io = io ? io : 0x3f8; ++ irq = irq ? irq : 4; ++ break; ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ case LIRC_NSLU2: ++ io = io ? io : IRQ_IXP4XX_UART2; ++ irq = irq ? irq : (IXP4XX_UART2_BASE_VIRT + REG_OFFSET); ++ iommap = iommap ? iommap : IXP4XX_UART2_BASE_PHYS; ++ ioshift = ioshift ? ioshift : 2; ++ break; ++#endif ++ default: ++ result = -EINVAL; ++ goto exit_serial_exit; ++ } ++ if (!softcarrier) { ++ switch (type) { ++ case LIRC_HOMEBREW: ++ case LIRC_IGOR: ++#ifdef CONFIG_LIRC_SERIAL_NSLU2 ++ case LIRC_NSLU2: ++#endif ++ hardware[type].features &= ++ ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| ++ LIRC_CAN_SET_SEND_CARRIER); ++ break; ++ } ++ } ++ ++ result = init_port(); ++ if (result < 0) ++ goto exit_serial_exit; ++ driver.features = hardware[type].features; ++ driver.dev = &lirc_serial_dev->dev; ++ driver.minor = lirc_register_driver(&driver); ++ if (driver.minor < 0) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": register_chrdev failed!\n"); ++ result = -EIO; ++ goto exit_release; ++ } ++ return 0; ++exit_release: ++ release_region(io, 8); ++exit_serial_exit: ++ lirc_serial_exit(); ++ return result; ++} ++ ++static void __exit lirc_serial_exit_module(void) ++{ ++ lirc_serial_exit(); ++ if (iommap != 0) ++ release_mem_region(iommap, 8 << ioshift); ++ else ++ release_region(io, 8); ++ lirc_unregister_driver(driver.minor); ++ dprintk("cleaned up module\n"); ++} ++ ++ ++module_init(lirc_serial_init_module); ++module_exit(lirc_serial_exit_module); ++ ++MODULE_DESCRIPTION("Infra-red receiver driver for serial ports."); ++MODULE_AUTHOR("Ralph Metzler, Trent Piepho, Ben Pfaff, " ++ "Christoph Bartelmus, Andrei Tanas"); ++MODULE_LICENSE("GPL"); ++ ++module_param(type, int, S_IRUGO); ++MODULE_PARM_DESC(type, "Hardware type (0 = home-brew, 1 = IRdeo," ++ " 2 = IRdeo Remote, 3 = AnimaX, 4 = IgorPlug," ++ " 5 = NSLU2 RX:CTS2/TX:GreenLED)"); ++ ++module_param(io, int, S_IRUGO); ++MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); ++ ++/* some architectures (e.g. intel xscale) have memory mapped registers */ ++module_param(iommap, bool, S_IRUGO); ++MODULE_PARM_DESC(iommap, "physical base for memory mapped I/O" ++ " (0 = no memory mapped io)"); ++ ++/* ++ * some architectures (e.g. intel xscale) align the 8bit serial registers ++ * on 32bit word boundaries. ++ * See linux-kernel/serial/8250.c serial_in()/out() ++ */ ++module_param(ioshift, int, S_IRUGO); ++MODULE_PARM_DESC(ioshift, "shift I/O register offset (0 = no shift)"); ++ ++module_param(irq, int, S_IRUGO); ++MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); ++ ++module_param(share_irq, bool, S_IRUGO); ++MODULE_PARM_DESC(share_irq, "Share interrupts (0 = off, 1 = on)"); ++ ++module_param(sense, bool, S_IRUGO); ++MODULE_PARM_DESC(sense, "Override autodetection of IR receiver circuit" ++ " (0 = active high, 1 = active low )"); ++ ++#ifdef CONFIG_LIRC_SERIAL_TRANSMITTER ++module_param(txsense, bool, S_IRUGO); ++MODULE_PARM_DESC(txsense, "Sense of transmitter circuit" ++ " (0 = active high, 1 = active low )"); ++#endif ++ ++module_param(softcarrier, bool, S_IRUGO); ++MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_sir.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_sir.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_sir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_sir.c 2010-08-02 09:28:03.981051171 +0200 +@@ -0,0 +1,1283 @@ ++/* ++ * LIRC SIR driver, (C) 2000 Milan Pikula ++ * ++ * lirc_sir - Device driver for use with SIR (serial infra red) ++ * mode of IrDA on many notebooks. ++ * ++ * 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 ++ * ++ * ++ * 2000/09/16 Frank Przybylski : ++ * added timeout and relaxed pulse detection, removed gap bug ++ * ++ * 2000/12/15 Christoph Bartelmus : ++ * added support for Tekram Irmate 210 (sending does not work yet, ++ * kind of disappointing that nobody was able to implement that ++ * before), ++ * major clean-up ++ * ++ * 2001/02/27 Christoph Bartelmus : ++ * added support for StrongARM SA1100 embedded microprocessor ++ * parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef LIRC_ON_SA1100 ++#include ++#ifdef CONFIG_SA1100_COLLIE ++#include ++#include ++#endif ++#endif ++ ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++/* SECTION: Definitions */ ++ ++/*** Tekram dongle ***/ ++#ifdef LIRC_SIR_TEKRAM ++/* stolen from kernel source */ ++/* definitions for Tekram dongle */ ++#define TEKRAM_115200 0x00 ++#define TEKRAM_57600 0x01 ++#define TEKRAM_38400 0x02 ++#define TEKRAM_19200 0x03 ++#define TEKRAM_9600 0x04 ++#define TEKRAM_2400 0x08 ++ ++#define TEKRAM_PW 0x10 /* Pulse select bit */ ++ ++/* 10bit * 1s/115200bit in milliseconds = 87ms*/ ++#define TIME_CONST (10000000ul/115200ul) ++ ++#endif ++ ++#ifdef LIRC_SIR_ACTISYS_ACT200L ++static void init_act200(void); ++#elif defined(LIRC_SIR_ACTISYS_ACT220L) ++static void init_act220(void); ++#endif ++ ++/*** SA1100 ***/ ++#ifdef LIRC_ON_SA1100 ++struct sa1100_ser2_registers { ++ /* HSSP control register */ ++ unsigned char hscr0; ++ /* UART registers */ ++ unsigned char utcr0; ++ unsigned char utcr1; ++ unsigned char utcr2; ++ unsigned char utcr3; ++ unsigned char utcr4; ++ unsigned char utdr; ++ unsigned char utsr0; ++ unsigned char utsr1; ++} sr; ++ ++static int irq = IRQ_Ser2ICP; ++ ++#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0 ++ ++/* pulse/space ratio of 50/50 */ ++static unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); ++/* 1000000/freq-pulse_width */ ++static unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); ++static unsigned int freq = 38000; /* modulation frequency */ ++static unsigned int duty_cycle = 50; /* duty cycle of 50% */ ++ ++#endif ++ ++#define RBUF_LEN 1024 ++#define WBUF_LEN 1024 ++ ++#define LIRC_DRIVER_NAME "lirc_sir" ++ ++#define PULSE '[' ++ ++#ifndef LIRC_SIR_TEKRAM ++/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ ++#define TIME_CONST (9000000ul/115200ul) ++#endif ++ ++ ++/* timeout for sequences in jiffies (=5/100s), must be longer than TIME_CONST */ ++#define SIR_TIMEOUT (HZ*5/100) ++ ++#ifndef LIRC_ON_SA1100 ++#ifndef LIRC_IRQ ++#define LIRC_IRQ 4 ++#endif ++#ifndef LIRC_PORT ++/* for external dongles, default to com1 */ ++#if defined(LIRC_SIR_ACTISYS_ACT200L) || \ ++ defined(LIRC_SIR_ACTISYS_ACT220L) || \ ++ defined(LIRC_SIR_TEKRAM) ++#define LIRC_PORT 0x3f8 ++#else ++/* onboard sir ports are typically com3 */ ++#define LIRC_PORT 0x3e8 ++#endif ++#endif ++ ++static int io = LIRC_PORT; ++static int irq = LIRC_IRQ; ++static int threshold = 3; ++#endif ++ ++static DEFINE_SPINLOCK(timer_lock); ++static struct timer_list timerlist; ++/* time of last signal change detected */ ++static struct timeval last_tv = {0, 0}; ++/* time of last UART data ready interrupt */ ++static struct timeval last_intr_tv = {0, 0}; ++static int last_value; ++ ++static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); ++ ++static DEFINE_SPINLOCK(hardware_lock); ++ ++static int rx_buf[RBUF_LEN]; ++static unsigned int rx_tail, rx_head; ++static int tx_buf[WBUF_LEN]; ++ ++static int debug; ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ ++ fmt, ## args); \ ++ } while (0) ++ ++/* SECTION: Prototypes */ ++ ++/* Communication with user-space */ ++static unsigned int lirc_poll(struct file *file, poll_table *wait); ++static ssize_t lirc_read(struct file *file, char *buf, size_t count, ++ loff_t *ppos); ++static ssize_t lirc_write(struct file *file, const char *buf, size_t n, ++ loff_t *pos); ++static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, ++ unsigned long arg); ++static void add_read_queue(int flag, unsigned long val); ++static int init_chrdev(void); ++static void drop_chrdev(void); ++/* Hardware */ ++static irqreturn_t sir_interrupt(int irq, void *dev_id); ++static void send_space(unsigned long len); ++static void send_pulse(unsigned long len); ++static int init_hardware(void); ++static void drop_hardware(void); ++/* Initialisation */ ++static int init_port(void); ++static void drop_port(void); ++ ++#ifdef LIRC_ON_SA1100 ++static void on(void) ++{ ++ PPSR |= PPC_TXD2; ++} ++ ++static void off(void) ++{ ++ PPSR &= ~PPC_TXD2; ++} ++#else ++static inline unsigned int sinp(int offset) ++{ ++ return inb(io + offset); ++} ++ ++static inline void soutp(int offset, int value) ++{ ++ outb(value, io + offset); ++} ++#endif ++ ++#ifndef MAX_UDELAY_MS ++#define MAX_UDELAY_US 5000 ++#else ++#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) ++#endif ++ ++static void safe_udelay(unsigned long usecs) ++{ ++ while (usecs > MAX_UDELAY_US) { ++ udelay(MAX_UDELAY_US); ++ usecs -= MAX_UDELAY_US; ++ } ++ udelay(usecs); ++} ++ ++/* SECTION: Communication with user-space */ ++ ++static unsigned int lirc_poll(struct file *file, poll_table *wait) ++{ ++ poll_wait(file, &lirc_read_queue, wait); ++ if (rx_head != rx_tail) ++ return POLLIN | POLLRDNORM; ++ return 0; ++} ++ ++static ssize_t lirc_read(struct file *file, char *buf, size_t count, ++ loff_t *ppos) ++{ ++ int n = 0; ++ int retval = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ if (count % sizeof(int)) ++ return -EINVAL; ++ ++ add_wait_queue(&lirc_read_queue, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ while (n < count) { ++ if (rx_head != rx_tail) { ++ if (copy_to_user((void *) buf + n, ++ (void *) (rx_buf + rx_head), ++ sizeof(int))) { ++ retval = -EFAULT; ++ break; ++ } ++ rx_head = (rx_head + 1) & (RBUF_LEN - 1); ++ n += sizeof(int); ++ } else { ++ if (file->f_flags & O_NONBLOCK) { ++ retval = -EAGAIN; ++ break; ++ } ++ if (signal_pending(current)) { ++ retval = -ERESTARTSYS; ++ break; ++ } ++ schedule(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ } ++ } ++ remove_wait_queue(&lirc_read_queue, &wait); ++ set_current_state(TASK_RUNNING); ++ return n ? n : retval; ++} ++static ssize_t lirc_write(struct file *file, const char *buf, size_t n, ++ loff_t *pos) ++{ ++ unsigned long flags; ++ int i; ++ ++ if (n % sizeof(int) || (n / sizeof(int)) > WBUF_LEN) ++ return -EINVAL; ++ if (copy_from_user(tx_buf, buf, n)) ++ return -EFAULT; ++ i = 0; ++ n /= sizeof(int); ++#ifdef LIRC_ON_SA1100 ++ /* disable receiver */ ++ Ser2UTCR3 = 0; ++#endif ++ local_irq_save(flags); ++ while (1) { ++ if (i >= n) ++ break; ++ if (tx_buf[i]) ++ send_pulse(tx_buf[i]); ++ i++; ++ if (i >= n) ++ break; ++ if (tx_buf[i]) ++ send_space(tx_buf[i]); ++ i++; ++ } ++ local_irq_restore(flags); ++#ifdef LIRC_ON_SA1100 ++ off(); ++ udelay(1000); /* wait 1ms for IR diode to recover */ ++ Ser2UTCR3 = 0; ++ /* clear status register to prevent unwanted interrupts */ ++ Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); ++ /* enable receiver */ ++ Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; ++#endif ++ return n; ++} ++ ++static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, ++ unsigned long arg) ++{ ++ int retval = 0; ++ unsigned long value = 0; ++#ifdef LIRC_ON_SA1100 ++ unsigned int ivalue; ++ ++ if (cmd == LIRC_GET_FEATURES) ++ value = LIRC_CAN_SEND_PULSE | ++ LIRC_CAN_SET_SEND_DUTY_CYCLE | ++ LIRC_CAN_SET_SEND_CARRIER | ++ LIRC_CAN_REC_MODE2; ++ else if (cmd == LIRC_GET_SEND_MODE) ++ value = LIRC_MODE_PULSE; ++ else if (cmd == LIRC_GET_REC_MODE) ++ value = LIRC_MODE_MODE2; ++#else ++ if (cmd == LIRC_GET_FEATURES) ++ value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; ++ else if (cmd == LIRC_GET_SEND_MODE) ++ value = LIRC_MODE_PULSE; ++ else if (cmd == LIRC_GET_REC_MODE) ++ value = LIRC_MODE_MODE2; ++#endif ++ ++ switch (cmd) { ++ case LIRC_GET_FEATURES: ++ case LIRC_GET_SEND_MODE: ++ case LIRC_GET_REC_MODE: ++ retval = put_user(value, (unsigned long *) arg); ++ break; ++ ++ case LIRC_SET_SEND_MODE: ++ case LIRC_SET_REC_MODE: ++ retval = get_user(value, (unsigned long *) arg); ++ break; ++#ifdef LIRC_ON_SA1100 ++ case LIRC_SET_SEND_DUTY_CYCLE: ++ retval = get_user(ivalue, (unsigned int *) arg); ++ if (retval) ++ return retval; ++ if (ivalue <= 0 || ivalue > 100) ++ return -EINVAL; ++ /* (ivalue/100)*(1000000/freq) */ ++ duty_cycle = ivalue; ++ pulse_width = (unsigned long) duty_cycle*10000/freq; ++ space_width = (unsigned long) 1000000L/freq-pulse_width; ++ if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) ++ pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; ++ if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) ++ space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; ++ break; ++ case LIRC_SET_SEND_CARRIER: ++ retval = get_user(ivalue, (unsigned int *) arg); ++ if (retval) ++ return retval; ++ if (ivalue > 500000 || ivalue < 20000) ++ return -EINVAL; ++ freq = ivalue; ++ pulse_width = (unsigned long) duty_cycle*10000/freq; ++ space_width = (unsigned long) 1000000L/freq-pulse_width; ++ if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) ++ pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; ++ if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) ++ space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; ++ break; ++#endif ++ default: ++ retval = -ENOIOCTLCMD; ++ ++ } ++ ++ if (retval) ++ return retval; ++ if (cmd == LIRC_SET_REC_MODE) { ++ if (value != LIRC_MODE_MODE2) ++ retval = -ENOSYS; ++ } else if (cmd == LIRC_SET_SEND_MODE) { ++ if (value != LIRC_MODE_PULSE) ++ retval = -ENOSYS; ++ } ++ ++ return retval; ++} ++ ++static void add_read_queue(int flag, unsigned long val) ++{ ++ unsigned int new_rx_tail; ++ int newval; ++ ++ dprintk("add flag %d with val %lu\n", flag, val); ++ ++ newval = val & PULSE_MASK; ++ ++ /* ++ * statistically, pulses are ~TIME_CONST/2 too long. we could ++ * maybe make this more exact, but this is good enough ++ */ ++ if (flag) { ++ /* pulse */ ++ if (newval > TIME_CONST/2) ++ newval -= TIME_CONST/2; ++ else /* should not ever happen */ ++ newval = 1; ++ newval |= PULSE_BIT; ++ } else { ++ newval += TIME_CONST/2; ++ } ++ new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); ++ if (new_rx_tail == rx_head) { ++ dprintk("Buffer overrun.\n"); ++ return; ++ } ++ rx_buf[rx_tail] = newval; ++ rx_tail = new_rx_tail; ++ wake_up_interruptible(&lirc_read_queue); ++} ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .read = lirc_read, ++ .write = lirc_write, ++ .poll = lirc_poll, ++ .ioctl = lirc_ioctl, ++ .open = lirc_dev_fop_open, ++ .release = lirc_dev_fop_close, ++}; ++ ++static int set_use_inc(void *data) ++{ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++} ++ ++static struct lirc_driver driver = { ++ .name = LIRC_DRIVER_NAME, ++ .minor = -1, ++ .code_length = 1, ++ .sample_rate = 0, ++ .data = NULL, ++ .add_to_buf = NULL, ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .fops = &lirc_fops, ++ .dev = NULL, ++ .owner = THIS_MODULE, ++}; ++ ++ ++static int init_chrdev(void) ++{ ++ driver.minor = lirc_register_driver(&driver); ++ if (driver.minor < 0) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static void drop_chrdev(void) ++{ ++ lirc_unregister_driver(driver.minor); ++} ++ ++/* SECTION: Hardware */ ++static long delta(struct timeval *tv1, struct timeval *tv2) ++{ ++ unsigned long deltv; ++ ++ deltv = tv2->tv_sec - tv1->tv_sec; ++ if (deltv > 15) ++ deltv = 0xFFFFFF; ++ else ++ deltv = deltv*1000000 + ++ tv2->tv_usec - ++ tv1->tv_usec; ++ return deltv; ++} ++ ++static void sir_timeout(unsigned long data) ++{ ++ /* ++ * if last received signal was a pulse, but receiving stopped ++ * within the 9 bit frame, we need to finish this pulse and ++ * simulate a signal change to from pulse to space. Otherwise ++ * upper layers will receive two sequences next time. ++ */ ++ ++ unsigned long flags; ++ unsigned long pulse_end; ++ ++ /* avoid interference with interrupt */ ++ spin_lock_irqsave(&timer_lock, flags); ++ if (last_value) { ++#ifndef LIRC_ON_SA1100 ++ /* clear unread bits in UART and restart */ ++ outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); ++#endif ++ /* determine 'virtual' pulse end: */ ++ pulse_end = delta(&last_tv, &last_intr_tv); ++ dprintk("timeout add %d for %lu usec\n", last_value, pulse_end); ++ add_read_queue(last_value, pulse_end); ++ last_value = 0; ++ last_tv = last_intr_tv; ++ } ++ spin_unlock_irqrestore(&timer_lock, flags); ++} ++ ++static irqreturn_t sir_interrupt(int irq, void *dev_id) ++{ ++ unsigned char data; ++ struct timeval curr_tv; ++ static unsigned long deltv; ++#ifdef LIRC_ON_SA1100 ++ int status; ++ static int n; ++ ++ status = Ser2UTSR0; ++ /* ++ * Deal with any receive errors first. The bytes in error may be ++ * the only bytes in the receive FIFO, so we do this first. ++ */ ++ while (status & UTSR0_EIF) { ++ int bstat; ++ ++ if (debug) { ++ dprintk("EIF\n"); ++ bstat = Ser2UTSR1; ++ ++ if (bstat & UTSR1_FRE) ++ dprintk("frame error\n"); ++ if (bstat & UTSR1_ROR) ++ dprintk("receive fifo overrun\n"); ++ if (bstat & UTSR1_PRE) ++ dprintk("parity error\n"); ++ } ++ ++ bstat = Ser2UTDR; ++ n++; ++ status = Ser2UTSR0; ++ } ++ ++ if (status & (UTSR0_RFS | UTSR0_RID)) { ++ do_gettimeofday(&curr_tv); ++ deltv = delta(&last_tv, &curr_tv); ++ do { ++ data = Ser2UTDR; ++ dprintk("%d data: %u\n", n, (unsigned int) data); ++ n++; ++ } while (status & UTSR0_RID && /* do not empty fifo in order to ++ * get UTSR0_RID in any case */ ++ Ser2UTSR1 & UTSR1_RNE); /* data ready */ ++ ++ if (status&UTSR0_RID) { ++ add_read_queue(0 , deltv - n * TIME_CONST); /*space*/ ++ add_read_queue(1, n * TIME_CONST); /*pulse*/ ++ n = 0; ++ last_tv = curr_tv; ++ } ++ } ++ ++ if (status & UTSR0_TFS) ++ printk(KERN_ERR "transmit fifo not full, shouldn't happen\n"); ++ ++ /* We must clear certain bits. */ ++ status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); ++ if (status) ++ Ser2UTSR0 = status; ++#else ++ unsigned long deltintrtv; ++ unsigned long flags; ++ int iir, lsr; ++ ++ while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { ++ switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */ ++ case UART_IIR_MSI: ++ (void) inb(io + UART_MSR); ++ break; ++ case UART_IIR_RLSI: ++ (void) inb(io + UART_LSR); ++ break; ++ case UART_IIR_THRI: ++#if 0 ++ if (lsr & UART_LSR_THRE) /* FIFO is empty */ ++ outb(data, io + UART_TX) ++#endif ++ break; ++ case UART_IIR_RDI: ++ /* avoid interference with timer */ ++ spin_lock_irqsave(&timer_lock, flags); ++ do { ++ del_timer(&timerlist); ++ data = inb(io + UART_RX); ++ do_gettimeofday(&curr_tv); ++ deltv = delta(&last_tv, &curr_tv); ++ deltintrtv = delta(&last_intr_tv, &curr_tv); ++ dprintk("t %lu, d %d\n", deltintrtv, (int)data); ++ /* ++ * if nothing came in last X cycles, ++ * it was gap ++ */ ++ if (deltintrtv > TIME_CONST * threshold) { ++ if (last_value) { ++ dprintk("GAP\n"); ++ /* simulate signal change */ ++ add_read_queue(last_value, ++ deltv - ++ deltintrtv); ++ last_value = 0; ++ last_tv.tv_sec = ++ last_intr_tv.tv_sec; ++ last_tv.tv_usec = ++ last_intr_tv.tv_usec; ++ deltv = deltintrtv; ++ } ++ } ++ data = 1; ++ if (data ^ last_value) { ++ /* ++ * deltintrtv > 2*TIME_CONST, remember? ++ * the other case is timeout ++ */ ++ add_read_queue(last_value, ++ deltv-TIME_CONST); ++ last_value = data; ++ last_tv = curr_tv; ++ if (last_tv.tv_usec >= TIME_CONST) { ++ last_tv.tv_usec -= TIME_CONST; ++ } else { ++ last_tv.tv_sec--; ++ last_tv.tv_usec += 1000000 - ++ TIME_CONST; ++ } ++ } ++ last_intr_tv = curr_tv; ++ if (data) { ++ /* ++ * start timer for end of ++ * sequence detection ++ */ ++ timerlist.expires = jiffies + ++ SIR_TIMEOUT; ++ add_timer(&timerlist); ++ } ++ ++ lsr = inb(io + UART_LSR); ++ } while (lsr & UART_LSR_DR); /* data ready */ ++ spin_unlock_irqrestore(&timer_lock, flags); ++ break; ++ default: ++ break; ++ } ++ } ++#endif ++ return IRQ_RETVAL(IRQ_HANDLED); ++} ++ ++#ifdef LIRC_ON_SA1100 ++static void send_pulse(unsigned long length) ++{ ++ unsigned long k, delay; ++ int flag; ++ ++ if (length == 0) ++ return; ++ /* ++ * this won't give us the carrier frequency we really want ++ * due to integer arithmetic, but we can accept this inaccuracy ++ */ ++ ++ for (k = flag = 0; k < length; k += delay, flag = !flag) { ++ if (flag) { ++ off(); ++ delay = space_width; ++ } else { ++ on(); ++ delay = pulse_width; ++ } ++ safe_udelay(delay); ++ } ++ off(); ++} ++ ++static void send_space(unsigned long length) ++{ ++ if (length == 0) ++ return; ++ off(); ++ safe_udelay(length); ++} ++#else ++static void send_space(unsigned long len) ++{ ++ safe_udelay(len); ++} ++ ++static void send_pulse(unsigned long len) ++{ ++ long bytes_out = len / TIME_CONST; ++ long time_left; ++ ++ time_left = (long)len - (long)bytes_out * (long)TIME_CONST; ++ if (bytes_out == 0) { ++ bytes_out++; ++ time_left = 0; ++ } ++ while (bytes_out--) { ++ outb(PULSE, io + UART_TX); ++ /* FIXME treba seriozne cakanie z char/serial.c */ ++ while (!(inb(io + UART_LSR) & UART_LSR_THRE)) ++ ; ++ } ++#if 0 ++ if (time_left > 0) ++ safe_udelay(time_left); ++#endif ++} ++#endif ++ ++#ifdef CONFIG_SA1100_COLLIE ++static int sa1100_irda_set_power_collie(int state) ++{ ++ if (state) { ++ /* ++ * 0 - off ++ * 1 - short range, lowest power ++ * 2 - medium range, medium power ++ * 3 - maximum range, high power ++ */ ++ ucb1200_set_io_direction(TC35143_GPIO_IR_ON, ++ TC35143_IODIR_OUTPUT); ++ ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW); ++ udelay(100); ++ } else { ++ /* OFF */ ++ ucb1200_set_io_direction(TC35143_GPIO_IR_ON, ++ TC35143_IODIR_OUTPUT); ++ ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH); ++ } ++ return 0; ++} ++#endif ++ ++static int init_hardware(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hardware_lock, flags); ++ /* reset UART */ ++#ifdef LIRC_ON_SA1100 ++#ifdef CONFIG_SA1100_BITSY ++ if (machine_is_bitsy()) { ++ printk(KERN_INFO "Power on IR module\n"); ++ set_bitsy_egpio(EGPIO_BITSY_IR_ON); ++ } ++#endif ++#ifdef CONFIG_SA1100_COLLIE ++ sa1100_irda_set_power_collie(3); /* power on */ ++#endif ++ sr.hscr0 = Ser2HSCR0; ++ ++ sr.utcr0 = Ser2UTCR0; ++ sr.utcr1 = Ser2UTCR1; ++ sr.utcr2 = Ser2UTCR2; ++ sr.utcr3 = Ser2UTCR3; ++ sr.utcr4 = Ser2UTCR4; ++ ++ sr.utdr = Ser2UTDR; ++ sr.utsr0 = Ser2UTSR0; ++ sr.utsr1 = Ser2UTSR1; ++ ++ /* configure GPIO */ ++ /* output */ ++ PPDR |= PPC_TXD2; ++ PSDR |= PPC_TXD2; ++ /* set output to 0 */ ++ off(); ++ ++ /* Enable HP-SIR modulation, and ensure that the port is disabled. */ ++ Ser2UTCR3 = 0; ++ Ser2HSCR0 = sr.hscr0 & (~HSCR0_HSSP); ++ ++ /* clear status register to prevent unwanted interrupts */ ++ Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); ++ ++ /* 7N1 */ ++ Ser2UTCR0 = UTCR0_1StpBit|UTCR0_7BitData; ++ /* 115200 */ ++ Ser2UTCR1 = 0; ++ Ser2UTCR2 = 1; ++ /* use HPSIR, 1.6 usec pulses */ ++ Ser2UTCR4 = UTCR4_HPSIR|UTCR4_Z1_6us; ++ ++ /* enable receiver, receive fifo interrupt */ ++ Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; ++ ++ /* clear status register to prevent unwanted interrupts */ ++ Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); ++ ++#elif defined(LIRC_SIR_TEKRAM) ++ /* disable FIFO */ ++ soutp(UART_FCR, ++ UART_FCR_CLEAR_RCVR| ++ UART_FCR_CLEAR_XMIT| ++ UART_FCR_TRIGGER_1); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* First of all, disable all interrupts */ ++ soutp(UART_IER, sinp(UART_IER) & ++ (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); ++ ++ /* Set divisor to 12 => 9600 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 12); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* power supply */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ safe_udelay(50*1000); ++ ++ /* -DTR low -> reset PIC */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); ++ udelay(1*1000); ++ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(100); ++ ++ ++ /* -RTS low -> send control byte */ ++ soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(7); ++ soutp(UART_TX, TEKRAM_115200|TEKRAM_PW); ++ ++ /* one byte takes ~1042 usec to transmit at 9600,8N1 */ ++ udelay(1500); ++ ++ /* back to normal operation */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(50); ++ ++ udelay(1500); ++ ++ /* read previous control byte */ ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": 0x%02x\n", sinp(UART_RX)); ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); ++ ++ /* Set divisor to 1 => 115200 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 1); ++ ++ /* Set DLAB 0, 8 Bit */ ++ soutp(UART_LCR, UART_LCR_WLEN8); ++ /* enable interrupts */ ++ soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); ++#else ++ outb(0, io + UART_MCR); ++ outb(0, io + UART_IER); ++ /* init UART */ ++ /* set DLAB, speed = 115200 */ ++ outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR); ++ outb(1, io + UART_DLL); outb(0, io + UART_DLM); ++ /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */ ++ outb(UART_LCR_WLEN7, io + UART_LCR); ++ /* FIFO operation */ ++ outb(UART_FCR_ENABLE_FIFO, io + UART_FCR); ++ /* interrupts */ ++ /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ ++ outb(UART_IER_RDI, io + UART_IER); ++ /* turn on UART */ ++ outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR); ++#ifdef LIRC_SIR_ACTISYS_ACT200L ++ init_act200(); ++#elif defined(LIRC_SIR_ACTISYS_ACT220L) ++ init_act220(); ++#endif ++#endif ++ spin_unlock_irqrestore(&hardware_lock, flags); ++ return 0; ++} ++ ++static void drop_hardware(void) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&hardware_lock, flags); ++ ++#ifdef LIRC_ON_SA1100 ++ Ser2UTCR3 = 0; ++ ++ Ser2UTCR0 = sr.utcr0; ++ Ser2UTCR1 = sr.utcr1; ++ Ser2UTCR2 = sr.utcr2; ++ Ser2UTCR4 = sr.utcr4; ++ Ser2UTCR3 = sr.utcr3; ++ ++ Ser2HSCR0 = sr.hscr0; ++#ifdef CONFIG_SA1100_BITSY ++ if (machine_is_bitsy()) ++ clr_bitsy_egpio(EGPIO_BITSY_IR_ON); ++#endif ++#ifdef CONFIG_SA1100_COLLIE ++ sa1100_irda_set_power_collie(0); /* power off */ ++#endif ++#else ++ /* turn off interrupts */ ++ outb(0, io + UART_IER); ++#endif ++ spin_unlock_irqrestore(&hardware_lock, flags); ++} ++ ++/* SECTION: Initialisation */ ++ ++static int init_port(void) ++{ ++ int retval; ++ ++ /* get I/O port access and IRQ line */ ++#ifndef LIRC_ON_SA1100 ++ if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": i/o port 0x%.4x already in use.\n", io); ++ return -EBUSY; ++ } ++#endif ++ retval = request_irq(irq, sir_interrupt, IRQF_DISABLED, ++ LIRC_DRIVER_NAME, NULL); ++ if (retval < 0) { ++# ifndef LIRC_ON_SA1100 ++ release_region(io, 8); ++# endif ++ printk(KERN_ERR LIRC_DRIVER_NAME ++ ": IRQ %d already in use.\n", ++ irq); ++ return retval; ++ } ++#ifndef LIRC_ON_SA1100 ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": I/O port 0x%.4x, IRQ %d.\n", ++ io, irq); ++#endif ++ ++ init_timer(&timerlist); ++ timerlist.function = sir_timeout; ++ timerlist.data = 0xabadcafe; ++ ++ return 0; ++} ++ ++static void drop_port(void) ++{ ++ free_irq(irq, NULL); ++ del_timer_sync(&timerlist); ++#ifndef LIRC_ON_SA1100 ++ release_region(io, 8); ++#endif ++} ++ ++#ifdef LIRC_SIR_ACTISYS_ACT200L ++/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */ ++/* some code borrowed from Linux IRDA driver */ ++ ++/* Register 0: Control register #1 */ ++#define ACT200L_REG0 0x00 ++#define ACT200L_TXEN 0x01 /* Enable transmitter */ ++#define ACT200L_RXEN 0x02 /* Enable receiver */ ++#define ACT200L_ECHO 0x08 /* Echo control chars */ ++ ++/* Register 1: Control register #2 */ ++#define ACT200L_REG1 0x10 ++#define ACT200L_LODB 0x01 /* Load new baud rate count value */ ++#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */ ++ ++/* Register 3: Transmit mode register #2 */ ++#define ACT200L_REG3 0x30 ++#define ACT200L_B0 0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ ++#define ACT200L_B1 0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ ++#define ACT200L_CHSY 0x04 /* StartBit Synced 0=bittime, 1=startbit */ ++ ++/* Register 4: Output Power register */ ++#define ACT200L_REG4 0x40 ++#define ACT200L_OP0 0x01 /* Enable LED1C output */ ++#define ACT200L_OP1 0x02 /* Enable LED2C output */ ++#define ACT200L_BLKR 0x04 ++ ++/* Register 5: Receive Mode register */ ++#define ACT200L_REG5 0x50 ++#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */ ++ /*.. other various IRDA bit modes, and TV remote modes..*/ ++ ++/* Register 6: Receive Sensitivity register #1 */ ++#define ACT200L_REG6 0x60 ++#define ACT200L_RS0 0x01 /* receive threshold bit 0 */ ++#define ACT200L_RS1 0x02 /* receive threshold bit 1 */ ++ ++/* Register 7: Receive Sensitivity register #2 */ ++#define ACT200L_REG7 0x70 ++#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */ ++ ++/* Register 8,9: Baud Rate Divider register #1,#2 */ ++#define ACT200L_REG8 0x80 ++#define ACT200L_REG9 0x90 ++ ++#define ACT200L_2400 0x5f ++#define ACT200L_9600 0x17 ++#define ACT200L_19200 0x0b ++#define ACT200L_38400 0x05 ++#define ACT200L_57600 0x03 ++#define ACT200L_115200 0x01 ++ ++/* Register 13: Control register #3 */ ++#define ACT200L_REG13 0xd0 ++#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */ ++ ++/* Register 15: Status register */ ++#define ACT200L_REG15 0xf0 ++ ++/* Register 21: Control register #4 */ ++#define ACT200L_REG21 0x50 ++#define ACT200L_EXCK 0x02 /* Disable clock output driver */ ++#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */ ++ ++static void init_act200(void) ++{ ++ int i; ++ __u8 control[] = { ++ ACT200L_REG15, ++ ACT200L_REG13 | ACT200L_SHDW, ++ ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, ++ ACT200L_REG13, ++ ACT200L_REG7 | ACT200L_ENPOS, ++ ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1, ++ ACT200L_REG5 | ACT200L_RWIDL, ++ ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR, ++ ACT200L_REG3 | ACT200L_B0, ++ ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN, ++ ACT200L_REG8 | (ACT200L_115200 & 0x0f), ++ ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f), ++ ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE ++ }; ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8); ++ ++ /* Set divisor to 12 => 9600 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 12); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, UART_LCR_WLEN8); ++ /* Set divisor to 12 => 9600 Baud */ ++ ++ /* power supply */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ for (i = 0; i < 50; i++) ++ safe_udelay(1000); ++ ++ /* Reset the dongle : set RTS low for 25 ms */ ++ soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); ++ for (i = 0; i < 25; i++) ++ udelay(1000); ++ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(100); ++ ++ /* Clear DTR and set RTS to enter command mode */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); ++ udelay(7); ++ ++ /* send out the control register settings for 115K 7N1 SIR operation */ ++ for (i = 0; i < sizeof(control); i++) { ++ soutp(UART_TX, control[i]); ++ /* one byte takes ~1042 usec to transmit at 9600,8N1 */ ++ udelay(1500); ++ } ++ ++ /* back to normal operation */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(50); ++ ++ udelay(1500); ++ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); ++ ++ /* Set divisor to 1 => 115200 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 1); ++ ++ /* Set DLAB 0. */ ++ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); ++ ++ /* Set DLAB 0, 7 Bit */ ++ soutp(UART_LCR, UART_LCR_WLEN7); ++ ++ /* enable interrupts */ ++ soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); ++} ++#endif ++ ++#ifdef LIRC_SIR_ACTISYS_ACT220L ++/* ++ * Derived from linux IrDA driver (net/irda/actisys.c) ++ * Drop me a mail for any kind of comment: maxx@spaceboyz.net ++ */ ++ ++void init_act220(void) ++{ ++ int i; ++ ++ /* DLAB 1 */ ++ soutp(UART_LCR, UART_LCR_DLAB|UART_LCR_WLEN7); ++ ++ /* 9600 baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 12); ++ ++ /* DLAB 0 */ ++ soutp(UART_LCR, UART_LCR_WLEN7); ++ ++ /* reset the dongle, set DTR low for 10us */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); ++ udelay(10); ++ ++ /* back to normal (still 9600) */ ++ soutp(UART_MCR, UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2); ++ ++ /* ++ * send RTS pulses until we reach 115200 ++ * i hope this is really the same for act220l/act220l+ ++ */ ++ for (i = 0; i < 3; i++) { ++ udelay(10); ++ /* set RTS low for 10 us */ ++ soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); ++ udelay(10); ++ /* set RTS high for 10 us */ ++ soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); ++ } ++ ++ /* back to normal operation */ ++ udelay(1500); /* better safe than sorry ;) */ ++ ++ /* Set DLAB 1. */ ++ soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); ++ ++ /* Set divisor to 1 => 115200 Baud */ ++ soutp(UART_DLM, 0); ++ soutp(UART_DLL, 1); ++ ++ /* Set DLAB 0, 7 Bit */ ++ /* The dongle doesn't seem to have any problems with operation at 7N1 */ ++ soutp(UART_LCR, UART_LCR_WLEN7); ++ ++ /* enable interrupts */ ++ soutp(UART_IER, UART_IER_RDI); ++} ++#endif ++ ++static int init_lirc_sir(void) ++{ ++ int retval; ++ ++ init_waitqueue_head(&lirc_read_queue); ++ retval = init_port(); ++ if (retval < 0) ++ return retval; ++ init_hardware(); ++ printk(KERN_INFO LIRC_DRIVER_NAME ++ ": Installed.\n"); ++ return 0; ++} ++ ++ ++static int __init lirc_sir_init(void) ++{ ++ int retval; ++ ++ retval = init_chrdev(); ++ if (retval < 0) ++ return retval; ++ retval = init_lirc_sir(); ++ if (retval) { ++ drop_chrdev(); ++ return retval; ++ } ++ return 0; ++} ++ ++static void __exit lirc_sir_exit(void) ++{ ++ drop_hardware(); ++ drop_chrdev(); ++ drop_port(); ++ printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); ++} ++ ++module_init(lirc_sir_init); ++module_exit(lirc_sir_exit); ++ ++#ifdef LIRC_SIR_TEKRAM ++MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210"); ++MODULE_AUTHOR("Christoph Bartelmus"); ++#elif defined(LIRC_ON_SA1100) ++MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor"); ++MODULE_AUTHOR("Christoph Bartelmus"); ++#elif defined(LIRC_SIR_ACTISYS_ACT200L) ++MODULE_DESCRIPTION("LIRC driver for Actisys Act200L"); ++MODULE_AUTHOR("Karl Bongers"); ++#elif defined(LIRC_SIR_ACTISYS_ACT220L) ++MODULE_DESCRIPTION("LIRC driver for Actisys Act220L(+)"); ++MODULE_AUTHOR("Jan Roemisch"); ++#else ++MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); ++MODULE_AUTHOR("Milan Pikula"); ++#endif ++MODULE_LICENSE("GPL"); ++ ++#ifdef LIRC_ON_SA1100 ++module_param(irq, int, S_IRUGO); ++MODULE_PARM_DESC(irq, "Interrupt (16)"); ++#else ++module_param(io, int, S_IRUGO); ++MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); ++ ++module_param(irq, int, S_IRUGO); ++MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); ++ ++module_param(threshold, int, S_IRUGO); ++MODULE_PARM_DESC(threshold, "space detection threshold (3)"); ++#endif ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_streamzap.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_streamzap.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_streamzap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_streamzap.c 2010-08-02 09:31:23.651050708 +0200 +@@ -0,0 +1,821 @@ ++/* ++ * Streamzap Remote Control driver ++ * ++ * Copyright (c) 2005 Christoph Bartelmus ++ * ++ * This driver was based on the work of Greg Wickham and Adrian ++ * Dewhurst. It was substantially rewritten to support correct signal ++ * gaps and now maintains a delay buffer, which is used to present ++ * consistent timing behaviour to user space applications. Without the ++ * delay buffer an ugly hack would be required in lircd, which can ++ * cause sluggish signal decoding in certain situations. ++ * ++ * This driver is based on the USB skeleton driver packaged with the ++ * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++#define DRIVER_VERSION "1.28" ++#define DRIVER_NAME "lirc_streamzap" ++#define DRIVER_DESC "Streamzap Remote Control driver" ++ ++static int debug; ++ ++#define USB_STREAMZAP_VENDOR_ID 0x0e9c ++#define USB_STREAMZAP_PRODUCT_ID 0x0000 ++ ++/* Use our own dbg macro */ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG DRIVER_NAME "[%d]: " \ ++ fmt "\n", ## args); \ ++ } while (0) ++ ++/* table of devices that work with this driver */ ++static struct usb_device_id streamzap_table[] = { ++ /* Streamzap Remote Control */ ++ { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, ++ /* Terminating entry */ ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(usb, streamzap_table); ++ ++#define STREAMZAP_PULSE_MASK 0xf0 ++#define STREAMZAP_SPACE_MASK 0x0f ++#define STREAMZAP_TIMEOUT 0xff ++#define STREAMZAP_RESOLUTION 256 ++ ++/* number of samples buffered */ ++#define STREAMZAP_BUF_LEN 128 ++ ++enum StreamzapDecoderState { ++ PulseSpace, ++ FullPulse, ++ FullSpace, ++ IgnorePulse ++}; ++ ++/* Structure to hold all of our device specific stuff ++ * ++ * some remarks regarding locking: ++ * theoretically this struct can be accessed from three threads: ++ * ++ * - from lirc_dev through set_use_inc/set_use_dec ++ * ++ * - from the USB layer throuh probe/disconnect/irq ++ * ++ * Careful placement of lirc_register_driver/lirc_unregister_driver ++ * calls will prevent conflicts. lirc_dev makes sure that ++ * set_use_inc/set_use_dec are not being executed and will not be ++ * called after lirc_unregister_driver returns. ++ * ++ * - by the timer callback ++ * ++ * The timer is only running when the device is connected and the ++ * LIRC device is open. Making sure the timer is deleted by ++ * set_use_dec will make conflicts impossible. ++ */ ++struct usb_streamzap { ++ ++ /* usb */ ++ /* save off the usb device pointer */ ++ struct usb_device *udev; ++ /* the interface for this device */ ++ struct usb_interface *interface; ++ ++ /* buffer & dma */ ++ unsigned char *buf_in; ++ dma_addr_t dma_in; ++ unsigned int buf_in_len; ++ ++ struct usb_endpoint_descriptor *endpoint; ++ ++ /* IRQ */ ++ struct urb *urb_in; ++ ++ /* lirc */ ++ struct lirc_driver *driver; ++ struct lirc_buffer *delay_buf; ++ ++ /* timer used to support delay buffering */ ++ struct timer_list delay_timer; ++ int timer_running; ++ spinlock_t timer_lock; ++ ++ /* tracks whether we are currently receiving some signal */ ++ int idle; ++ /* sum of signal lengths received since signal start */ ++ unsigned long sum; ++ /* start time of signal; necessary for gap tracking */ ++ struct timeval signal_last; ++ struct timeval signal_start; ++ enum StreamzapDecoderState decoder_state; ++ struct timer_list flush_timer; ++ int flush; ++ int in_use; ++ int timeout_enabled; ++}; ++ ++ ++/* local function prototypes */ ++static int streamzap_probe(struct usb_interface *interface, ++ const struct usb_device_id *id); ++static void streamzap_disconnect(struct usb_interface *interface); ++static void usb_streamzap_irq(struct urb *urb); ++static int streamzap_use_inc(void *data); ++static void streamzap_use_dec(void *data); ++static int streamzap_ioctl(struct inode *node, struct file *filep, ++ unsigned int cmd, unsigned long arg); ++static int streamzap_suspend(struct usb_interface *intf, pm_message_t message); ++static int streamzap_resume(struct usb_interface *intf); ++ ++/* usb specific object needed to register this driver with the usb subsystem */ ++ ++static struct usb_driver streamzap_driver = { ++ .name = DRIVER_NAME, ++ .probe = streamzap_probe, ++ .disconnect = streamzap_disconnect, ++ .suspend = streamzap_suspend, ++ .resume = streamzap_resume, ++ .id_table = streamzap_table, ++}; ++ ++static void stop_timer(struct usb_streamzap *sz) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sz->timer_lock, flags); ++ if (sz->timer_running) { ++ sz->timer_running = 0; ++ spin_unlock_irqrestore(&sz->timer_lock, flags); ++ del_timer_sync(&sz->delay_timer); ++ } else { ++ spin_unlock_irqrestore(&sz->timer_lock, flags); ++ } ++} ++ ++static void flush_timeout(unsigned long arg) ++{ ++ struct usb_streamzap *sz = (struct usb_streamzap *) arg; ++ ++ /* finally start accepting data */ ++ sz->flush = 0; ++} ++static void delay_timeout(unsigned long arg) ++{ ++ unsigned long flags; ++ /* deliver data every 10 ms */ ++ static unsigned long timer_inc = ++ (10000/(1000000/HZ)) == 0 ? 1 : (10000/(1000000/HZ)); ++ struct usb_streamzap *sz = (struct usb_streamzap *) arg; ++ int data; ++ ++ spin_lock_irqsave(&sz->timer_lock, flags); ++ ++ if (!lirc_buffer_empty(sz->delay_buf) && ++ !lirc_buffer_full(sz->driver->rbuf)) { ++ lirc_buffer_read(sz->delay_buf, (unsigned char *) &data); ++ lirc_buffer_write(sz->driver->rbuf, (unsigned char *) &data); ++ } ++ if (!lirc_buffer_empty(sz->delay_buf)) { ++ while (lirc_buffer_available(sz->delay_buf) < ++ STREAMZAP_BUF_LEN / 2 && ++ !lirc_buffer_full(sz->driver->rbuf)) { ++ lirc_buffer_read(sz->delay_buf, ++ (unsigned char *) &data); ++ lirc_buffer_write(sz->driver->rbuf, ++ (unsigned char *) &data); ++ } ++ if (sz->timer_running) { ++ sz->delay_timer.expires = jiffies + timer_inc; ++ add_timer(&sz->delay_timer); ++ } ++ } else { ++ sz->timer_running = 0; ++ } ++ ++ if (!lirc_buffer_empty(sz->driver->rbuf)) ++ wake_up(&sz->driver->rbuf->wait_poll); ++ ++ spin_unlock_irqrestore(&sz->timer_lock, flags); ++} ++ ++static void flush_delay_buffer(struct usb_streamzap *sz) ++{ ++ int data; ++ int empty = 1; ++ ++ while (!lirc_buffer_empty(sz->delay_buf)) { ++ empty = 0; ++ lirc_buffer_read(sz->delay_buf, (unsigned char *) &data); ++ if (!lirc_buffer_full(sz->driver->rbuf)) { ++ lirc_buffer_write(sz->driver->rbuf, ++ (unsigned char *) &data); ++ } else { ++ dprintk("buffer overflow", sz->driver->minor); ++ } ++ } ++ if (!empty) ++ wake_up(&sz->driver->rbuf->wait_poll); ++} ++ ++static void push(struct usb_streamzap *sz, unsigned char *data) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&sz->timer_lock, flags); ++ if (lirc_buffer_full(sz->delay_buf)) { ++ int read_data; ++ ++ lirc_buffer_read(sz->delay_buf, ++ (unsigned char *) &read_data); ++ if (!lirc_buffer_full(sz->driver->rbuf)) { ++ lirc_buffer_write(sz->driver->rbuf, ++ (unsigned char *) &read_data); ++ } else { ++ dprintk("buffer overflow", sz->driver->minor); ++ } ++ } ++ ++ lirc_buffer_write(sz->delay_buf, data); ++ ++ if (!sz->timer_running) { ++ sz->delay_timer.expires = jiffies + HZ/10; ++ add_timer(&sz->delay_timer); ++ sz->timer_running = 1; ++ } ++ ++ spin_unlock_irqrestore(&sz->timer_lock, flags); ++} ++ ++static void push_full_pulse(struct usb_streamzap *sz, ++ unsigned char value) ++{ ++ int pulse; ++ ++ if (sz->idle) { ++ long deltv; ++ int tmp; ++ ++ sz->signal_last = sz->signal_start; ++ do_gettimeofday(&sz->signal_start); ++ ++ deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec; ++ if (deltv > 15) { ++ /* really long time */ ++ tmp = LIRC_SPACE(LIRC_VALUE_MASK); ++ } else { ++ tmp = (int) (deltv*1000000+ ++ sz->signal_start.tv_usec - ++ sz->signal_last.tv_usec); ++ tmp -= sz->sum; ++ tmp = LIRC_SPACE(tmp); ++ } ++ dprintk("ls %u", sz->driver->minor, tmp); ++ push(sz, (char *)&tmp); ++ ++ sz->idle = 0; ++ sz->sum = 0; ++ } ++ ++ pulse = ((int) value) * STREAMZAP_RESOLUTION; ++ pulse += STREAMZAP_RESOLUTION / 2; ++ sz->sum += pulse; ++ pulse = LIRC_PULSE(pulse); ++ ++ dprintk("p %u", sz->driver->minor, pulse & PULSE_MASK); ++ push(sz, (char *)&pulse); ++} ++ ++static void push_half_pulse(struct usb_streamzap *sz, ++ unsigned char value) ++{ ++ push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4); ++} ++ ++static void push_full_space(struct usb_streamzap *sz, ++ unsigned char value) ++{ ++ int space; ++ ++ space = ((int) value)*STREAMZAP_RESOLUTION; ++ space += STREAMZAP_RESOLUTION/2; ++ sz->sum += space; ++ space = LIRC_SPACE(space); ++ dprintk("s %u", sz->driver->minor, space); ++ push(sz, (char *)&space); ++} ++ ++static void push_half_space(struct usb_streamzap *sz, ++ unsigned char value) ++{ ++ push_full_space(sz, value & STREAMZAP_SPACE_MASK); ++} ++ ++/** ++ * usb_streamzap_irq - IRQ handler ++ * ++ * This procedure is invoked on reception of data from ++ * the usb remote. ++ */ ++static void usb_streamzap_irq(struct urb *urb) ++{ ++ struct usb_streamzap *sz; ++ int len; ++ unsigned int i = 0; ++ ++ if (!urb) ++ return; ++ ++ sz = urb->context; ++ len = urb->actual_length; ++ ++ switch (urb->status) { ++ case -ECONNRESET: ++ case -ENOENT: ++ case -ESHUTDOWN: ++ /* ++ * this urb is terminated, clean up. ++ * sz might already be invalid at this point ++ */ ++ dprintk("urb status: %d", -1, urb->status); ++ return; ++ default: ++ break; ++ } ++ ++ dprintk("received %d", sz->driver->minor, urb->actual_length); ++ if (!sz->flush) { ++ for (i = 0; i < urb->actual_length; i++) { ++ dprintk("%d: %x", sz->driver->minor, ++ i, (unsigned char) sz->buf_in[i]); ++ switch (sz->decoder_state) { ++ case PulseSpace: ++ if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) == ++ STREAMZAP_PULSE_MASK) { ++ sz->decoder_state = FullPulse; ++ continue; ++ } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ++ == STREAMZAP_SPACE_MASK) { ++ push_half_pulse(sz, sz->buf_in[i]); ++ sz->decoder_state = FullSpace; ++ continue; ++ } else { ++ push_half_pulse(sz, sz->buf_in[i]); ++ push_half_space(sz, sz->buf_in[i]); ++ } ++ break; ++ case FullPulse: ++ push_full_pulse(sz, sz->buf_in[i]); ++ sz->decoder_state = IgnorePulse; ++ break; ++ case FullSpace: ++ if (sz->buf_in[i] == STREAMZAP_TIMEOUT) { ++ sz->idle = 1; ++ stop_timer(sz); ++ if (sz->timeout_enabled) { ++ int timeout = ++ LIRC_TIMEOUT ++ (STREAMZAP_TIMEOUT * ++ STREAMZAP_RESOLUTION); ++ push(sz, (char *)&timeout); ++ } ++ flush_delay_buffer(sz); ++ } else ++ push_full_space(sz, sz->buf_in[i]); ++ sz->decoder_state = PulseSpace; ++ break; ++ case IgnorePulse: ++ if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) == ++ STREAMZAP_SPACE_MASK) { ++ sz->decoder_state = FullSpace; ++ continue; ++ } ++ push_half_space(sz, sz->buf_in[i]); ++ sz->decoder_state = PulseSpace; ++ break; ++ } ++ } ++ } ++ ++ usb_submit_urb(urb, GFP_ATOMIC); ++ ++ return; ++} ++ ++static struct file_operations streamzap_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = streamzap_ioctl, ++ .read = lirc_dev_fop_read, ++ .write = lirc_dev_fop_write, ++ .poll = lirc_dev_fop_poll, ++ .open = lirc_dev_fop_open, ++ .release = lirc_dev_fop_close, ++}; ++ ++ ++/** ++ * streamzap_probe ++ * ++ * Called by usb-core to associated with a candidate device ++ * On any failure the return value is the ERROR ++ * On success return 0 ++ */ ++static int streamzap_probe(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *udev = interface_to_usbdev(interface); ++ struct usb_host_interface *iface_host; ++ struct usb_streamzap *sz; ++ struct lirc_driver *driver; ++ struct lirc_buffer *lirc_buf; ++ struct lirc_buffer *delay_buf; ++ char buf[63], name[128] = ""; ++ int retval = -ENOMEM; ++ int minor = 0; ++ ++ /* Allocate space for device driver specific data */ ++ sz = kzalloc(sizeof(struct usb_streamzap), GFP_KERNEL); ++ if (sz == NULL) ++ return -ENOMEM; ++ ++ sz->udev = udev; ++ sz->interface = interface; ++ ++ /* Check to ensure endpoint information matches requirements */ ++ iface_host = interface->cur_altsetting; ++ ++ if (iface_host->desc.bNumEndpoints != 1) { ++ err("%s: Unexpected desc.bNumEndpoints (%d)", __func__, ++ iface_host->desc.bNumEndpoints); ++ retval = -ENODEV; ++ goto free_sz; ++ } ++ ++ sz->endpoint = &(iface_host->endpoint[0].desc); ++ if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) ++ != USB_DIR_IN) { ++ err("%s: endpoint doesn't match input device 02%02x", ++ __func__, sz->endpoint->bEndpointAddress); ++ retval = -ENODEV; ++ goto free_sz; ++ } ++ ++ if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ++ != USB_ENDPOINT_XFER_INT) { ++ err("%s: endpoint attributes don't match xfer 02%02x", ++ __func__, sz->endpoint->bmAttributes); ++ retval = -ENODEV; ++ goto free_sz; ++ } ++ ++ if (sz->endpoint->wMaxPacketSize == 0) { ++ err("%s: endpoint message size==0? ", __func__); ++ retval = -ENODEV; ++ goto free_sz; ++ } ++ ++ /* Allocate the USB buffer and IRQ URB */ ++ ++ sz->buf_in_len = sz->endpoint->wMaxPacketSize; ++ sz->buf_in = usb_alloc_coherent(sz->udev, sz->buf_in_len, ++ GFP_ATOMIC, &sz->dma_in); ++ if (sz->buf_in == NULL) ++ goto free_sz; ++ ++ sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); ++ if (sz->urb_in == NULL) ++ goto free_sz; ++ ++ /* Connect this device to the LIRC sub-system */ ++ driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); ++ if (!driver) ++ goto free_sz; ++ ++ lirc_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!lirc_buf) ++ goto free_driver; ++ if (lirc_buffer_init(lirc_buf, sizeof(int), STREAMZAP_BUF_LEN)) ++ goto kfree_lirc_buf; ++ ++ delay_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); ++ if (!delay_buf) ++ goto free_lirc_buf; ++ if (lirc_buffer_init(delay_buf, sizeof(int), STREAMZAP_BUF_LEN)) ++ goto kfree_delay_buf; ++ ++ sz->driver = driver; ++ strcpy(sz->driver->name, DRIVER_NAME); ++ sz->driver->minor = -1; ++ sz->driver->sample_rate = 0; ++ sz->driver->code_length = sizeof(int) * 8; ++ sz->driver->features = LIRC_CAN_REC_MODE2 | ++ LIRC_CAN_GET_REC_RESOLUTION | ++ LIRC_CAN_SET_REC_TIMEOUT; ++ sz->driver->data = sz; ++ sz->driver->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION; ++ sz->driver->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION; ++ sz->driver->rbuf = lirc_buf; ++ sz->delay_buf = delay_buf; ++ sz->driver->set_use_inc = &streamzap_use_inc; ++ sz->driver->set_use_dec = &streamzap_use_dec; ++ sz->driver->fops = &streamzap_fops; ++ sz->driver->dev = &interface->dev; ++ sz->driver->owner = THIS_MODULE; ++ ++ sz->idle = 1; ++ sz->decoder_state = PulseSpace; ++ init_timer(&sz->delay_timer); ++ sz->delay_timer.function = delay_timeout; ++ sz->delay_timer.data = (unsigned long) sz; ++ sz->timer_running = 0; ++ spin_lock_init(&sz->timer_lock); ++ ++ init_timer(&sz->flush_timer); ++ sz->flush_timer.function = flush_timeout; ++ sz->flush_timer.data = (unsigned long) sz; ++ /* Complete final initialisations */ ++ ++ usb_fill_int_urb(sz->urb_in, udev, ++ usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress), ++ sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz, ++ sz->endpoint->bInterval); ++ sz->urb_in->transfer_dma = sz->dma_in; ++ sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; ++ ++ if (udev->descriptor.iManufacturer ++ && usb_string(udev, udev->descriptor.iManufacturer, ++ buf, sizeof(buf)) > 0) ++ strlcpy(name, buf, sizeof(name)); ++ ++ if (udev->descriptor.iProduct ++ && usb_string(udev, udev->descriptor.iProduct, ++ buf, sizeof(buf)) > 0) ++ snprintf(name + strlen(name), sizeof(name) - strlen(name), ++ " %s", buf); ++ ++ minor = lirc_register_driver(driver); ++ ++ if (minor < 0) ++ goto free_delay_buf; ++ ++ sz->driver->minor = minor; ++ ++ usb_set_intfdata(interface, sz); ++ ++ printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n", ++ sz->driver->minor, name, ++ udev->bus->busnum, sz->udev->devnum); ++ ++ return 0; ++ ++free_delay_buf: ++ lirc_buffer_free(sz->delay_buf); ++kfree_delay_buf: ++ kfree(delay_buf); ++free_lirc_buf: ++ lirc_buffer_free(sz->driver->rbuf); ++kfree_lirc_buf: ++ kfree(lirc_buf); ++free_driver: ++ kfree(driver); ++free_sz: ++ if (retval == -ENOMEM) ++ err("Out of memory"); ++ ++ if (sz) { ++ usb_free_urb(sz->urb_in); ++ usb_alloc_coherent(udev, sz->buf_in_len, sz->buf_in, sz->dma_in); ++ kfree(sz); ++ } ++ ++ return retval; ++} ++ ++static int streamzap_use_inc(void *data) ++{ ++ struct usb_streamzap *sz = data; ++ ++ if (!sz) { ++ dprintk("%s called with no context", -1, __func__); ++ return -EINVAL; ++ } ++ dprintk("set use inc", sz->driver->minor); ++ ++ lirc_buffer_clear(sz->driver->rbuf); ++ lirc_buffer_clear(sz->delay_buf); ++ ++ sz->flush_timer.expires = jiffies + HZ; ++ sz->flush = 1; ++ add_timer(&sz->flush_timer); ++ ++ sz->urb_in->dev = sz->udev; ++ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { ++ dprintk("open result = -EIO error submitting urb", ++ sz->driver->minor); ++ return -EIO; ++ } ++ sz->in_use++; ++ ++ return 0; ++} ++ ++static void streamzap_use_dec(void *data) ++{ ++ struct usb_streamzap *sz = data; ++ ++ if (!sz) { ++ dprintk("%s called with no context", -1, __func__); ++ return; ++ } ++ dprintk("set use dec", sz->driver->minor); ++ ++ if (sz->flush) { ++ sz->flush = 0; ++ del_timer_sync(&sz->flush_timer); ++ } ++ ++ usb_kill_urb(sz->urb_in); ++ ++ stop_timer(sz); ++ ++ sz->in_use--; ++} ++ ++static int streamzap_ioctl(struct inode *node, struct file *filep, ++ unsigned int cmd, unsigned long arg) ++{ ++ int result = 0; ++ int val; ++ struct usb_streamzap *sz = lirc_get_pdata(filep); ++ ++ switch (cmd) { ++ case LIRC_GET_REC_RESOLUTION: ++ result = put_user(STREAMZAP_RESOLUTION, (unsigned int *) arg); ++ break; ++ case LIRC_SET_REC_TIMEOUT: ++ result = get_user(val, (int *)arg); ++ if (result == 0) { ++ if (val == STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) ++ sz->timeout_enabled = 1; ++ else if (val == 0) ++ sz->timeout_enabled = 0; ++ else ++ result = -EINVAL; ++ } ++ break; ++ default: ++ return lirc_dev_fop_ioctl(node, filep, cmd, arg); ++ } ++ return result; ++} ++ ++/** ++ * streamzap_disconnect ++ * ++ * Called by the usb core when the device is removed from the system. ++ * ++ * This routine guarantees that the driver will not submit any more urbs ++ * by clearing dev->udev. It is also supposed to terminate any currently ++ * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), ++ * does not provide any way to do this. ++ */ ++static void streamzap_disconnect(struct usb_interface *interface) ++{ ++ struct usb_streamzap *sz; ++ int errnum; ++ int minor; ++ ++ sz = usb_get_intfdata(interface); ++ ++ /* unregister from the LIRC sub-system */ ++ ++ errnum = lirc_unregister_driver(sz->driver->minor); ++ if (errnum != 0) ++ dprintk("error in lirc_unregister: (returned %d)", ++ sz->driver->minor, errnum); ++ ++ lirc_buffer_free(sz->delay_buf); ++ lirc_buffer_free(sz->driver->rbuf); ++ ++ /* unregister from the USB sub-system */ ++ ++ usb_free_urb(sz->urb_in); ++ ++ usb_alloc_coherent(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in); ++ ++ minor = sz->driver->minor; ++ kfree(sz->driver->rbuf); ++ kfree(sz->driver); ++ kfree(sz->delay_buf); ++ kfree(sz); ++ ++ printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor); ++} ++ ++static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct usb_streamzap *sz = usb_get_intfdata(intf); ++ ++ printk(KERN_INFO DRIVER_NAME "[%d]: suspend\n", sz->driver->minor); ++ if (sz->in_use) { ++ if (sz->flush) { ++ sz->flush = 0; ++ del_timer_sync(&sz->flush_timer); ++ } ++ ++ stop_timer(sz); ++ ++ usb_kill_urb(sz->urb_in); ++ } ++ return 0; ++} ++ ++static int streamzap_resume(struct usb_interface *intf) ++{ ++ struct usb_streamzap *sz = usb_get_intfdata(intf); ++ ++ lirc_buffer_clear(sz->driver->rbuf); ++ lirc_buffer_clear(sz->delay_buf); ++ ++ if (sz->in_use) { ++ sz->flush_timer.expires = jiffies + HZ; ++ sz->flush = 1; ++ add_timer(&sz->flush_timer); ++ ++ sz->urb_in->dev = sz->udev; ++ if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { ++ dprintk("open result = -EIO error submitting urb", ++ sz->driver->minor); ++ return -EIO; ++ } ++ } ++ return 0; ++} ++ ++/** ++ * usb_streamzap_init ++ */ ++static int __init usb_streamzap_init(void) ++{ ++ int result; ++ ++ /* register this driver with the USB subsystem */ ++ result = usb_register(&streamzap_driver); ++ ++ if (result) { ++ err("usb_register failed. Error number %d", ++ result); ++ return result; ++ } ++ ++ printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n"); ++ return 0; ++} ++ ++/** ++ * usb_streamzap_exit ++ */ ++static void __exit usb_streamzap_exit(void) ++{ ++ usb_deregister(&streamzap_driver); ++} ++ ++ ++module_init(usb_streamzap_init); ++module_exit(usb_streamzap_exit); ++ ++MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst"); ++MODULE_DESCRIPTION(DRIVER_DESC); ++MODULE_LICENSE("GPL"); ++ ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_ttusbir.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ttusbir.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_ttusbir.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_ttusbir.c 2010-08-02 09:28:03.986051565 +0200 +@@ -0,0 +1,397 @@ ++/* ++ * lirc_ttusbir.c ++ * ++ * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver ++ * ++ * Copyright (C) 2007 Stefan Macher ++ * ++ * This LIRC driver provides access to the TechnoTrend USB IR Receiver. ++ * The receiver delivers the IR signal as raw sampled true/false data in ++ * isochronous USB packets each of size 128 byte. ++ * Currently the driver reduces the sampling rate by factor of 8 as this ++ * is still more than enough to decode RC-5 - others should be analyzed. ++ * But the driver does not rely on RC-5 it should be able to decode every ++ * IR signal that is not too fast. ++ */ ++ ++/* ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "lirc_dev.h" ++ ++MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC"); ++MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)"); ++MODULE_LICENSE("GPL"); ++ ++/* #define DEBUG */ ++#ifdef DEBUG ++#define DPRINTK printk ++#else ++#define DPRINTK(_x_, a...) ++#endif ++ ++/* function declarations */ ++static int probe(struct usb_interface *intf, const struct usb_device_id *id); ++static void disconnect(struct usb_interface *intf); ++static void urb_complete(struct urb *urb); ++static int set_use_inc(void *data); ++static void set_use_dec(void *data); ++ ++static int num_urbs = 2; ++module_param(num_urbs, int, S_IRUGO); ++MODULE_PARM_DESC(num_urbs, ++ "Number of URBs in queue. Try to increase to 4 in case " ++ "of problems (default: 2; minimum: 2)"); ++ ++/* table of devices that work with this driver */ ++static struct usb_device_id device_id_table[] = { ++ /* TechnoTrend USB IR Receiver */ ++ { USB_DEVICE(0x0B48, 0x2003) }, ++ /* Terminating entry */ ++ { } ++}; ++MODULE_DEVICE_TABLE(usb, device_id_table); ++ ++/* USB driver definition */ ++static struct usb_driver usb_driver = { ++ .name = "TTUSBIR", ++ .id_table = &(device_id_table[0]), ++ .probe = probe, ++ .disconnect = disconnect, ++}; ++ ++/* USB device definition */ ++struct ttusbir_device { ++ struct usb_driver *usb_driver; ++ struct usb_device *udev; ++ struct usb_interface *interf; ++ struct usb_class_driver class_driver; ++ unsigned int ifnum; /* Interface number to use */ ++ unsigned int alt_setting; /* alternate setting to use */ ++ unsigned int endpoint; /* Endpoint to use */ ++ struct urb **urb; /* num_urb URB pointers*/ ++ char **buffer; /* 128 byte buffer for each URB */ ++ struct lirc_buffer rbuf; /* Buffer towards LIRC */ ++ struct lirc_driver driver; ++ int minor; ++ int last_pulse; /* remembers if last received byte was pulse or space */ ++ int last_num; /* remembers how many last bytes appeared */ ++ int opened; ++}; ++ ++/*** LIRC specific functions ***/ ++static int set_use_inc(void *data) ++{ ++ int i, retval; ++ struct ttusbir_device *ttusbir = data; ++ ++ DPRINTK("Sending first URBs\n"); ++ /* @TODO Do I need to check if I am already opened */ ++ ttusbir->opened = 1; ++ ++ for (i = 0; i < num_urbs; i++) { ++ retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL); ++ if (retval) { ++ err("%s: usb_submit_urb failed on urb %d", ++ __func__, i); ++ return retval; ++ } ++ } ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct ttusbir_device *ttusbir = data; ++ ++ DPRINTK("Device closed\n"); ++ ++ ttusbir->opened = 0; ++} ++ ++/*** USB specific functions ***/ ++ ++/* ++ * This mapping table is used to do a very simple filtering of the ++ * input signal. ++ * For a value with at least 4 bits set it returns 0xFF otherwise ++ * 0x00. For faster IR signals this can not be used. But for RC-5 we ++ * still have about 14 samples per pulse/space, i.e. we sample with 14 ++ * times higher frequency than the signal frequency ++ */ ++const unsigned char map_table[] = ++{ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ++}; ++ ++static void urb_complete(struct urb *urb) ++{ ++ struct ttusbir_device *ttusbir; ++ unsigned char *buf; ++ int i; ++ int l; ++ ++ ttusbir = urb->context; ++ ++ if (!ttusbir->opened) ++ return; ++ ++ buf = (unsigned char *)urb->transfer_buffer; ++ ++ for (i = 0; i < 128; i++) { ++ /* Here we do the filtering and some kind of down sampling */ ++ buf[i] = ~map_table[buf[i]]; ++ if (ttusbir->last_pulse == buf[i]) { ++ if (ttusbir->last_num < PULSE_MASK/63) ++ ttusbir->last_num++; ++ /* ++ * else we are in a idle period and do not need to ++ * increment any longer ++ */ ++ } else { ++ l = ttusbir->last_num * 62; /* about 62 = us/byte */ ++ if (ttusbir->last_pulse) /* pulse or space? */ ++ l |= PULSE_BIT; ++ if (!lirc_buffer_full(&ttusbir->rbuf)) { ++ lirc_buffer_write(&ttusbir->rbuf, (void *)&l); ++ wake_up_interruptible(&ttusbir->rbuf.wait_poll); ++ } ++ ttusbir->last_num = 0; ++ ttusbir->last_pulse = buf[i]; ++ } ++ } ++ usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */ ++} ++ ++/* ++ * Called whenever the USB subsystem thinks we could be the right driver ++ * to handle this device ++ */ ++static int probe(struct usb_interface *intf, const struct usb_device_id *id) ++{ ++ int alt_set, endp; ++ int found = 0; ++ int i, j; ++ int struct_size; ++ struct usb_host_interface *host_interf; ++ struct usb_interface_descriptor *interf_desc; ++ struct usb_host_endpoint *host_endpoint; ++ struct ttusbir_device *ttusbir; ++ ++ DPRINTK("Module ttusbir probe\n"); ++ ++ /* To reduce memory fragmentation we use only one allocation */ ++ struct_size = sizeof(struct ttusbir_device) + ++ (sizeof(struct urb *) * num_urbs) + ++ (sizeof(char *) * num_urbs) + ++ (num_urbs * 128); ++ ttusbir = kzalloc(struct_size, GFP_KERNEL); ++ if (!ttusbir) ++ return -ENOMEM; ++ ++ ttusbir->urb = (struct urb **)((char *)ttusbir + ++ sizeof(struct ttusbir_device)); ++ ttusbir->buffer = (char **)((char *)ttusbir->urb + ++ (sizeof(struct urb *) * num_urbs)); ++ for (i = 0; i < num_urbs; i++) ++ ttusbir->buffer[i] = (char *)ttusbir->buffer + ++ (sizeof(char *)*num_urbs) + (i * 128); ++ ++ ttusbir->usb_driver = &usb_driver; ++ ttusbir->alt_setting = -1; ++ /* @TODO check if error can be returned */ ++ ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); ++ ttusbir->interf = intf; ++ ttusbir->last_pulse = 0x00; ++ ttusbir->last_num = 0; ++ ++ /* ++ * Now look for interface setting we can handle ++ * We are searching for the alt setting where end point ++ * 0x82 has max packet size 16 ++ */ ++ for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { ++ host_interf = &intf->altsetting[alt_set]; ++ interf_desc = &host_interf->desc; ++ for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { ++ host_endpoint = &host_interf->endpoint[endp]; ++ if ((host_endpoint->desc.bEndpointAddress == 0x82) && ++ (host_endpoint->desc.wMaxPacketSize == 0x10)) { ++ ttusbir->alt_setting = alt_set; ++ ttusbir->endpoint = endp; ++ found = 1; ++ break; ++ } ++ } ++ } ++ if (ttusbir->alt_setting != -1) ++ DPRINTK("alt setting: %d\n", ttusbir->alt_setting); ++ else { ++ err("Could not find alternate setting\n"); ++ kfree(ttusbir); ++ return -EINVAL; ++ } ++ ++ /* OK lets setup this interface setting */ ++ usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); ++ ++ /* Store device info in interface structure */ ++ usb_set_intfdata(intf, ttusbir); ++ ++ /* Register as a LIRC driver */ ++ if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) { ++ err("Could not get memory for LIRC data buffer\n"); ++ usb_set_intfdata(intf, NULL); ++ kfree(ttusbir); ++ return -ENOMEM; ++ } ++ strcpy(ttusbir->driver.name, "TTUSBIR"); ++ ttusbir->driver.minor = -1; ++ ttusbir->driver.code_length = 1; ++ ttusbir->driver.sample_rate = 0; ++ ttusbir->driver.data = ttusbir; ++ ttusbir->driver.add_to_buf = NULL; ++ ttusbir->driver.rbuf = &ttusbir->rbuf; ++ ttusbir->driver.set_use_inc = set_use_inc; ++ ttusbir->driver.set_use_dec = set_use_dec; ++ ttusbir->driver.dev = &intf->dev; ++ ttusbir->driver.owner = THIS_MODULE; ++ ttusbir->driver.features = LIRC_CAN_REC_MODE2; ++ ttusbir->minor = lirc_register_driver(&ttusbir->driver); ++ if (ttusbir->minor < 0) { ++ err("Error registering as LIRC driver\n"); ++ usb_set_intfdata(intf, NULL); ++ lirc_buffer_free(&ttusbir->rbuf); ++ kfree(ttusbir); ++ return -EIO; ++ } ++ ++ /* Allocate and setup the URB that we will use to talk to the device */ ++ for (i = 0; i < num_urbs; i++) { ++ ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); ++ if (!ttusbir->urb[i]) { ++ err("Could not allocate memory for the URB\n"); ++ for (j = i - 1; j >= 0; j--) ++ kfree(ttusbir->urb[j]); ++ lirc_buffer_free(&ttusbir->rbuf); ++ lirc_unregister_driver(ttusbir->minor); ++ kfree(ttusbir); ++ usb_set_intfdata(intf, NULL); ++ return -ENOMEM; ++ } ++ ttusbir->urb[i]->dev = ttusbir->udev; ++ ttusbir->urb[i]->context = ttusbir; ++ ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, ++ ttusbir->endpoint); ++ ttusbir->urb[i]->interval = 1; ++ ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; ++ ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; ++ ttusbir->urb[i]->complete = urb_complete; ++ ttusbir->urb[i]->number_of_packets = 8; ++ ttusbir->urb[i]->transfer_buffer_length = 128; ++ for (j = 0; j < 8; j++) { ++ ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; ++ ttusbir->urb[i]->iso_frame_desc[j].length = 16; ++ } ++ } ++ return 0; ++} ++ ++/** ++ * Called when the driver is unloaded or the device is unplugged ++ */ ++static void disconnect(struct usb_interface *intf) ++{ ++ int i; ++ struct ttusbir_device *ttusbir; ++ ++ DPRINTK("Module ttusbir disconnect\n"); ++ ++ ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf); ++ usb_set_intfdata(intf, NULL); ++ lirc_unregister_driver(ttusbir->minor); ++ DPRINTK("unregistered\n"); ++ ++ for (i = 0; i < num_urbs; i++) { ++ usb_kill_urb(ttusbir->urb[i]); ++ usb_free_urb(ttusbir->urb[i]); ++ } ++ DPRINTK("URBs killed\n"); ++ lirc_buffer_free(&ttusbir->rbuf); ++ kfree(ttusbir); ++} ++ ++static int ttusbir_init_module(void) ++{ ++ int result; ++ ++ DPRINTK(KERN_DEBUG "Module ttusbir init\n"); ++ ++ /* register this driver with the USB subsystem */ ++ result = usb_register(&usb_driver); ++ if (result) ++ err("usb_register failed. Error number %d", result); ++ return result; ++} ++ ++static void ttusbir_exit_module(void) ++{ ++ printk(KERN_DEBUG "Module ttusbir exit\n"); ++ usb_deregister(&usb_driver); ++} ++ ++module_init(ttusbir_init_module); ++module_exit(ttusbir_exit_module); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/lirc_zilog.c linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_zilog.c +--- linux-2.6.35-rc6/drivers/input/lirc/lirc_zilog.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/lirc_zilog.c 2010-08-02 09:28:03.990051699 +0200 +@@ -0,0 +1,1388 @@ ++/* ++ * i2c IR lirc driver for devices with zilog IR processors ++ * ++ * Copyright (c) 2000 Gerd Knorr ++ * modified for PixelView (BT878P+W/FM) by ++ * Michal Kochanowicz ++ * Christoph Bartelmus ++ * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by ++ * Ulrich Mueller ++ * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by ++ * Stefan Jahn ++ * modified for inclusion into kernel sources by ++ * Jerome Brock ++ * modified for Leadtek Winfast PVR2000 by ++ * Thomas Reitmayr (treitmayr@yahoo.com) ++ * modified for Hauppauge PVR-150 IR TX device by ++ * Mark Weaver ++ * changed name from lirc_pvr150 to lirc_zilog, works on more than pvr-150 ++ * Jarod Wilson ++ * ++ * parts are cut&pasted from the lirc_i2c.c driver ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "lirc_dev.h" ++#include ++ ++struct IR { ++ struct lirc_driver l; ++ ++ /* Device info */ ++ struct mutex ir_lock; ++ int open; ++ ++ /* RX device */ ++ struct i2c_client c_rx; ++ int have_rx; ++ ++ /* RX device buffer & lock */ ++ struct lirc_buffer buf; ++ struct mutex buf_lock; ++ ++ /* RX polling thread data */ ++ struct completion *t_notify; ++ struct completion *t_notify2; ++ int shutdown; ++ struct task_struct *task; ++ ++ /* RX read data */ ++ unsigned char b[3]; ++ ++ /* TX device */ ++ struct i2c_client c_tx; ++ int need_boot; ++ int have_tx; ++}; ++ ++/* Minor -> data mapping */ ++static struct IR *ir_devices[MAX_IRCTL_DEVICES]; ++ ++/* Block size for IR transmitter */ ++#define TX_BLOCK_SIZE 99 ++ ++/* Hauppauge IR transmitter data */ ++struct tx_data_struct { ++ /* Boot block */ ++ unsigned char *boot_data; ++ ++ /* Start of binary data block */ ++ unsigned char *datap; ++ ++ /* End of binary data block */ ++ unsigned char *endp; ++ ++ /* Number of installed codesets */ ++ unsigned int num_code_sets; ++ ++ /* Pointers to codesets */ ++ unsigned char **code_sets; ++ ++ /* Global fixed data template */ ++ int fixed[TX_BLOCK_SIZE]; ++}; ++ ++static struct tx_data_struct *tx_data; ++static struct mutex tx_data_lock; ++ ++#define zilog_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, \ ++ ## args) ++#define zilog_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args) ++ ++#define ZILOG_HAUPPAUGE_IR_RX_NAME "Zilog/Hauppauge IR RX" ++#define ZILOG_HAUPPAUGE_IR_TX_NAME "Zilog/Hauppauge IR TX" ++ ++/* module parameters */ ++static int debug; /* debug output */ ++static int disable_rx; /* disable RX device */ ++static int disable_tx; /* disable TX device */ ++static int minor = -1; /* minor number */ ++ ++#define dprintk(fmt, args...) \ ++ do { \ ++ if (debug) \ ++ printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ ++ ## args); \ ++ } while (0) ++ ++static int add_to_buf(struct IR *ir) ++{ ++ __u16 code; ++ unsigned char codes[2]; ++ unsigned char keybuf[6]; ++ int got_data = 0; ++ int ret; ++ int failures = 0; ++ unsigned char sendbuf[1] = { 0 }; ++ ++ if (lirc_buffer_full(&ir->buf)) { ++ dprintk("buffer overflow\n"); ++ return -EOVERFLOW; ++ } ++ ++ /* ++ * service the device as long as it is returning ++ * data and we have space ++ */ ++ do { ++ /* ++ * Lock i2c bus for the duration. RX/TX chips interfere so ++ * this is worth it ++ */ ++ mutex_lock(&ir->ir_lock); ++ ++ /* ++ * Send random "poll command" (?) Windows driver does this ++ * and it is a good point to detect chip failure. ++ */ ++ ret = i2c_master_send(&ir->c_rx, sendbuf, 1); ++ if (ret != 1) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ if (failures >= 3) { ++ mutex_unlock(&ir->ir_lock); ++ zilog_error("unable to read from the IR chip " ++ "after 3 resets, giving up\n"); ++ return ret; ++ } ++ ++ /* Looks like the chip crashed, reset it */ ++ zilog_error("polling the IR receiver chip failed, " ++ "trying reset\n"); ++ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((100 * HZ + 999) / 1000); ++ ir->need_boot = 1; ++ ++ ++failures; ++ mutex_unlock(&ir->ir_lock); ++ continue; ++ } ++ ++ ret = i2c_master_recv(&ir->c_rx, keybuf, sizeof(keybuf)); ++ mutex_unlock(&ir->ir_lock); ++ if (ret != sizeof(keybuf)) { ++ zilog_error("i2c_master_recv failed with %d -- " ++ "keeping last read buffer\n", ret); ++ } else { ++ ir->b[0] = keybuf[3]; ++ ir->b[1] = keybuf[4]; ++ ir->b[2] = keybuf[5]; ++ dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); ++ } ++ ++ /* key pressed ? */ ++#ifdef I2C_HW_B_HDPVR ++ if (ir->c_rx.adapter->id == I2C_HW_B_HDPVR) { ++ if (got_data && (keybuf[0] == 0x80)) ++ return 0; ++ else if (got_data && (keybuf[0] == 0x00)) ++ return -ENODATA; ++ } else if ((ir->b[0] & 0x80) == 0) ++#else ++ if ((ir->b[0] & 0x80) == 0) ++#endif ++ return got_data ? 0 : -ENODATA; ++ ++ /* look what we have */ ++ code = (((__u16)ir->b[0] & 0x7f) << 6) | (ir->b[1] >> 2); ++ ++ codes[0] = (code >> 8) & 0xff; ++ codes[1] = code & 0xff; ++ ++ /* return it */ ++ lirc_buffer_write(&ir->buf, codes); ++ ++got_data; ++ } while (!lirc_buffer_full(&ir->buf)); ++ ++ return 0; ++} ++ ++/* ++ * Main function of the polling thread -- from lirc_dev. ++ * We don't fit the LIRC model at all anymore. This is horrible, but ++ * basically we have a single RX/TX device with a nasty failure mode ++ * that needs to be accounted for across the pair. lirc lets us provide ++ * fops, but prevents us from using the internal polling, etc. if we do ++ * so. Hence the replication. Might be neater to extend the LIRC model ++ * to account for this but I'd think it's a very special case of seriously ++ * messed up hardware. ++ */ ++static int lirc_thread(void *arg) ++{ ++ struct IR *ir = arg; ++ ++ if (ir->t_notify != NULL) ++ complete(ir->t_notify); ++ ++ dprintk("poll thread started\n"); ++ ++ do { ++ if (ir->open) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ /* ++ * This is ~113*2 + 24 + jitter (2*repeat gap + ++ * code length). We use this interval as the chip ++ * resets every time you poll it (bad!). This is ++ * therefore just sufficient to catch all of the ++ * button presses. It makes the remote much more ++ * responsive. You can see the difference by ++ * running irw and holding down a button. With ++ * 100ms, the old polling interval, you'll notice ++ * breaks in the repeat sequence corresponding to ++ * lost keypresses. ++ */ ++ schedule_timeout((260 * HZ) / 1000); ++ if (ir->shutdown) ++ break; ++ if (!add_to_buf(ir)) ++ wake_up_interruptible(&ir->buf.wait_poll); ++ } else { ++ /* if device not opened so we can sleep half a second */ ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(HZ/2); ++ } ++ } while (!ir->shutdown); ++ ++ if (ir->t_notify2 != NULL) ++ wait_for_completion(ir->t_notify2); ++ ++ ir->task = NULL; ++ if (ir->t_notify != NULL) ++ complete(ir->t_notify); ++ ++ dprintk("poll thread ended\n"); ++ return 0; ++} ++ ++static int set_use_inc(void *data) ++{ ++ struct IR *ir = data; ++ ++ if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0) ++ return -ENODEV; ++ ++ /* lock bttv in memory while /dev/lirc is in use */ ++ /* ++ * this is completely broken code. lirc_unregister_driver() ++ * must be possible even when the device is open ++ */ ++ if (ir->c_rx.addr) ++ i2c_use_client(&ir->c_rx); ++ if (ir->c_tx.addr) ++ i2c_use_client(&ir->c_tx); ++ ++ return 0; ++} ++ ++static void set_use_dec(void *data) ++{ ++ struct IR *ir = data; ++ ++ if (ir->c_rx.addr) ++ i2c_release_client(&ir->c_rx); ++ if (ir->c_tx.addr) ++ i2c_release_client(&ir->c_tx); ++ if (ir->l.owner != NULL) ++ module_put(ir->l.owner); ++} ++ ++/* safe read of a uint32 (always network byte order) */ ++static int read_uint32(unsigned char **data, ++ unsigned char *endp, unsigned int *val) ++{ ++ if (*data + 4 > endp) ++ return 0; ++ *val = ((*data)[0] << 24) | ((*data)[1] << 16) | ++ ((*data)[2] << 8) | (*data)[3]; ++ *data += 4; ++ return 1; ++} ++ ++/* safe read of a uint8 */ ++static int read_uint8(unsigned char **data, ++ unsigned char *endp, unsigned char *val) ++{ ++ if (*data + 1 > endp) ++ return 0; ++ *val = *((*data)++); ++ return 1; ++} ++ ++/* safe skipping of N bytes */ ++static int skip(unsigned char **data, ++ unsigned char *endp, unsigned int distance) ++{ ++ if (*data + distance > endp) ++ return 0; ++ *data += distance; ++ return 1; ++} ++ ++/* decompress key data into the given buffer */ ++static int get_key_data(unsigned char *buf, ++ unsigned int codeset, unsigned int key) ++{ ++ unsigned char *data, *endp, *diffs, *key_block; ++ unsigned char keys, ndiffs, id; ++ unsigned int base, lim, pos, i; ++ ++ /* Binary search for the codeset */ ++ for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) { ++ pos = base + (lim >> 1); ++ data = tx_data->code_sets[pos]; ++ ++ if (!read_uint32(&data, tx_data->endp, &i)) ++ goto corrupt; ++ ++ if (i == codeset) ++ break; ++ else if (codeset > i) { ++ base = pos + 1; ++ --lim; ++ } ++ } ++ /* Not found? */ ++ if (!lim) ++ return -EPROTO; ++ ++ /* Set end of data block */ ++ endp = pos < tx_data->num_code_sets - 1 ? ++ tx_data->code_sets[pos + 1] : tx_data->endp; ++ ++ /* Read the block header */ ++ if (!read_uint8(&data, endp, &keys) || ++ !read_uint8(&data, endp, &ndiffs) || ++ ndiffs > TX_BLOCK_SIZE || keys == 0) ++ goto corrupt; ++ ++ /* Save diffs & skip */ ++ diffs = data; ++ if (!skip(&data, endp, ndiffs)) ++ goto corrupt; ++ ++ /* Read the id of the first key */ ++ if (!read_uint8(&data, endp, &id)) ++ goto corrupt; ++ ++ /* Unpack the first key's data */ ++ for (i = 0; i < TX_BLOCK_SIZE; ++i) { ++ if (tx_data->fixed[i] == -1) { ++ if (!read_uint8(&data, endp, &buf[i])) ++ goto corrupt; ++ } else { ++ buf[i] = (unsigned char)tx_data->fixed[i]; ++ } ++ } ++ ++ /* Early out key found/not found */ ++ if (key == id) ++ return 0; ++ if (keys == 1) ++ return -EPROTO; ++ ++ /* Sanity check */ ++ key_block = data; ++ if (!skip(&data, endp, (keys - 1) * (ndiffs + 1))) ++ goto corrupt; ++ ++ /* Binary search for the key */ ++ for (base = 0, lim = keys - 1; lim; lim >>= 1) { ++ /* Seek to block */ ++ unsigned char *key_data; ++ pos = base + (lim >> 1); ++ key_data = key_block + (ndiffs + 1) * pos; ++ ++ if (*key_data == key) { ++ /* skip key id */ ++ ++key_data; ++ ++ /* found, so unpack the diffs */ ++ for (i = 0; i < ndiffs; ++i) { ++ unsigned char val; ++ if (!read_uint8(&key_data, endp, &val) || ++ diffs[i] >= TX_BLOCK_SIZE) ++ goto corrupt; ++ buf[diffs[i]] = val; ++ } ++ ++ return 0; ++ } else if (key > *key_data) { ++ base = pos + 1; ++ --lim; ++ } ++ } ++ /* Key not found */ ++ return -EPROTO; ++ ++corrupt: ++ zilog_error("firmware is corrupt\n"); ++ return -EFAULT; ++} ++ ++/* send a block of data to the IR TX device */ ++static int send_data_block(struct IR *ir, unsigned char *data_block) ++{ ++ int i, j, ret; ++ unsigned char buf[5]; ++ ++ for (i = 0; i < TX_BLOCK_SIZE;) { ++ int tosend = TX_BLOCK_SIZE - i; ++ if (tosend > 4) ++ tosend = 4; ++ buf[0] = (unsigned char)(i + 1); ++ for (j = 0; j < tosend; ++j) ++ buf[1 + j] = data_block[i + j]; ++ dprintk("%02x %02x %02x %02x %02x", ++ buf[0], buf[1], buf[2], buf[3], buf[4]); ++ ret = i2c_master_send(&ir->c_tx, buf, tosend + 1); ++ if (ret != tosend + 1) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ i += tosend; ++ } ++ return 0; ++} ++ ++/* send boot data to the IR TX device */ ++static int send_boot_data(struct IR *ir) ++{ ++ int ret; ++ unsigned char buf[4]; ++ ++ /* send the boot block */ ++ ret = send_data_block(ir, tx_data->boot_data); ++ if (ret != 0) ++ return ret; ++ ++ /* kick it off? */ ++ buf[0] = 0x00; ++ buf[1] = 0x20; ++ ret = i2c_master_send(&ir->c_tx, buf, 2); ++ if (ret != 2) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ret = i2c_master_send(&ir->c_tx, buf, 1); ++ if (ret != 1) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ++ /* Here comes the firmware version... (hopefully) */ ++ ret = i2c_master_recv(&ir->c_tx, buf, 4); ++ if (ret != 4) { ++ zilog_error("i2c_master_recv failed with %d\n", ret); ++ return 0; ++ } ++ if (buf[0] != 0x80) { ++ zilog_error("unexpected IR TX response: %02x\n", buf[0]); ++ return 0; ++ } ++ zilog_notify("Zilog/Hauppauge IR blaster firmware version " ++ "%d.%d.%d loaded\n", buf[1], buf[2], buf[3]); ++ ++ return 0; ++} ++ ++/* unload "firmware", lock held */ ++static void fw_unload_locked(void) ++{ ++ if (tx_data) { ++ if (tx_data->code_sets) ++ vfree(tx_data->code_sets); ++ ++ if (tx_data->datap) ++ vfree(tx_data->datap); ++ ++ vfree(tx_data); ++ tx_data = NULL; ++ dprintk("successfully unloaded IR blaster firmware\n"); ++ } ++} ++ ++/* unload "firmware" for the IR TX device */ ++static void fw_unload(void) ++{ ++ mutex_lock(&tx_data_lock); ++ fw_unload_locked(); ++ mutex_unlock(&tx_data_lock); ++} ++ ++/* load "firmware" for the IR TX device */ ++static int fw_load(struct IR *ir) ++{ ++ int ret; ++ unsigned int i; ++ unsigned char *data, version, num_global_fixed; ++ const struct firmware *fw_entry; ++ ++ /* Already loaded? */ ++ mutex_lock(&tx_data_lock); ++ if (tx_data) { ++ ret = 0; ++ goto out; ++ } ++ ++ /* Request codeset data file */ ++ ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &ir->c_tx.dev); ++ if (ret != 0) { ++ zilog_error("firmware haup-ir-blaster.bin not available " ++ "(%d)\n", ret); ++ ret = ret < 0 ? ret : -EFAULT; ++ goto out; ++ } ++ dprintk("firmware of size %zu loaded\n", fw_entry->size); ++ ++ /* Parse the file */ ++ tx_data = vmalloc(sizeof(*tx_data)); ++ if (tx_data == NULL) { ++ zilog_error("out of memory\n"); ++ release_firmware(fw_entry); ++ ret = -ENOMEM; ++ goto out; ++ } ++ tx_data->code_sets = NULL; ++ ++ /* Copy the data so hotplug doesn't get confused and timeout */ ++ tx_data->datap = vmalloc(fw_entry->size); ++ if (tx_data->datap == NULL) { ++ zilog_error("out of memory\n"); ++ release_firmware(fw_entry); ++ vfree(tx_data); ++ ret = -ENOMEM; ++ goto out; ++ } ++ memcpy(tx_data->datap, fw_entry->data, fw_entry->size); ++ tx_data->endp = tx_data->datap + fw_entry->size; ++ release_firmware(fw_entry); fw_entry = NULL; ++ ++ /* Check version */ ++ data = tx_data->datap; ++ if (!read_uint8(&data, tx_data->endp, &version)) ++ goto corrupt; ++ if (version != 1) { ++ zilog_error("unsupported code set file version (%u, expected" ++ "1) -- please upgrade to a newer driver", ++ version); ++ fw_unload_locked(); ++ ret = -EFAULT; ++ goto out; ++ } ++ ++ /* Save boot block for later */ ++ tx_data->boot_data = data; ++ if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE)) ++ goto corrupt; ++ ++ if (!read_uint32(&data, tx_data->endp, ++ &tx_data->num_code_sets)) ++ goto corrupt; ++ ++ dprintk("%u IR blaster codesets loaded\n", tx_data->num_code_sets); ++ ++ tx_data->code_sets = vmalloc( ++ tx_data->num_code_sets * sizeof(char *)); ++ if (tx_data->code_sets == NULL) { ++ fw_unload_locked(); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ for (i = 0; i < TX_BLOCK_SIZE; ++i) ++ tx_data->fixed[i] = -1; ++ ++ /* Read global fixed data template */ ++ if (!read_uint8(&data, tx_data->endp, &num_global_fixed) || ++ num_global_fixed > TX_BLOCK_SIZE) ++ goto corrupt; ++ for (i = 0; i < num_global_fixed; ++i) { ++ unsigned char pos, val; ++ if (!read_uint8(&data, tx_data->endp, &pos) || ++ !read_uint8(&data, tx_data->endp, &val) || ++ pos >= TX_BLOCK_SIZE) ++ goto corrupt; ++ tx_data->fixed[pos] = (int)val; ++ } ++ ++ /* Filch out the position of each code set */ ++ for (i = 0; i < tx_data->num_code_sets; ++i) { ++ unsigned int id; ++ unsigned char keys; ++ unsigned char ndiffs; ++ ++ /* Save the codeset position */ ++ tx_data->code_sets[i] = data; ++ ++ /* Read header */ ++ if (!read_uint32(&data, tx_data->endp, &id) || ++ !read_uint8(&data, tx_data->endp, &keys) || ++ !read_uint8(&data, tx_data->endp, &ndiffs) || ++ ndiffs > TX_BLOCK_SIZE || keys == 0) ++ goto corrupt; ++ ++ /* skip diff positions */ ++ if (!skip(&data, tx_data->endp, ndiffs)) ++ goto corrupt; ++ ++ /* ++ * After the diffs we have the first key id + data - ++ * global fixed ++ */ ++ if (!skip(&data, tx_data->endp, ++ 1 + TX_BLOCK_SIZE - num_global_fixed)) ++ goto corrupt; ++ ++ /* Then we have keys-1 blocks of key id+diffs */ ++ if (!skip(&data, tx_data->endp, ++ (ndiffs + 1) * (keys - 1))) ++ goto corrupt; ++ } ++ ret = 0; ++ goto out; ++ ++corrupt: ++ zilog_error("firmware is corrupt\n"); ++ fw_unload_locked(); ++ ret = -EFAULT; ++ ++out: ++ mutex_unlock(&tx_data_lock); ++ return ret; ++} ++ ++/* initialise the IR TX device */ ++static int tx_init(struct IR *ir) ++{ ++ int ret; ++ ++ /* Load 'firmware' */ ++ ret = fw_load(ir); ++ if (ret != 0) ++ return ret; ++ ++ /* Send boot block */ ++ ret = send_boot_data(ir); ++ if (ret != 0) ++ return ret; ++ ir->need_boot = 0; ++ ++ /* Looks good */ ++ return 0; ++} ++ ++/* do nothing stub to make LIRC happy */ ++static loff_t lseek(struct file *filep, loff_t offset, int orig) ++{ ++ return -ESPIPE; ++} ++ ++/* copied from lirc_dev */ ++static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) ++{ ++ struct IR *ir = (struct IR *)filep->private_data; ++ unsigned char buf[ir->buf.chunk_size]; ++ int ret = 0, written = 0; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ dprintk("read called\n"); ++ if (ir->c_rx.addr == 0) ++ return -ENODEV; ++ ++ if (mutex_lock_interruptible(&ir->buf_lock)) ++ return -ERESTARTSYS; ++ ++ if (n % ir->buf.chunk_size) { ++ dprintk("read result = -EINVAL\n"); ++ mutex_unlock(&ir->buf_lock); ++ return -EINVAL; ++ } ++ ++ /* ++ * we add ourselves to the task queue before buffer check ++ * to avoid losing scan code (in case when queue is awaken somewhere ++ * between while condition checking and scheduling) ++ */ ++ add_wait_queue(&ir->buf.wait_poll, &wait); ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ /* ++ * while we didn't provide 'length' bytes, device is opened in blocking ++ * mode and 'copy_to_user' is happy, wait for data. ++ */ ++ while (written < n && ret == 0) { ++ if (lirc_buffer_empty(&ir->buf)) { ++ /* ++ * According to the read(2) man page, 'written' can be ++ * returned as less than 'n', instead of blocking ++ * again, returning -EWOULDBLOCK, or returning ++ * -ERESTARTSYS ++ */ ++ if (written) ++ break; ++ if (filep->f_flags & O_NONBLOCK) { ++ ret = -EWOULDBLOCK; ++ break; ++ } ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ schedule(); ++ set_current_state(TASK_INTERRUPTIBLE); ++ } else { ++ lirc_buffer_read(&ir->buf, buf); ++ ret = copy_to_user((void *)outbuf+written, buf, ++ ir->buf.chunk_size); ++ written += ir->buf.chunk_size; ++ } ++ } ++ ++ remove_wait_queue(&ir->buf.wait_poll, &wait); ++ set_current_state(TASK_RUNNING); ++ mutex_unlock(&ir->buf_lock); ++ ++ dprintk("read result = %s (%d)\n", ++ ret ? "-EFAULT" : "OK", ret); ++ ++ return ret ? ret : written; ++} ++ ++/* send a keypress to the IR TX device */ ++static int send_code(struct IR *ir, unsigned int code, unsigned int key) ++{ ++ unsigned char data_block[TX_BLOCK_SIZE]; ++ unsigned char buf[2]; ++ int i, ret; ++ ++ /* Get data for the codeset/key */ ++ ret = get_key_data(data_block, code, key); ++ ++ if (ret == -EPROTO) { ++ zilog_error("failed to get data for code %u, key %u -- check " ++ "lircd.conf entries\n", code, key); ++ return ret; ++ } else if (ret != 0) ++ return ret; ++ ++ /* Send the data block */ ++ ret = send_data_block(ir, data_block); ++ if (ret != 0) ++ return ret; ++ ++ /* Send data block length? */ ++ buf[0] = 0x00; ++ buf[1] = 0x40; ++ ret = i2c_master_send(&ir->c_tx, buf, 2); ++ if (ret != 2) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ret = i2c_master_send(&ir->c_tx, buf, 1); ++ if (ret != 1) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ++ /* Send finished download? */ ++ ret = i2c_master_recv(&ir->c_tx, buf, 1); ++ if (ret != 1) { ++ zilog_error("i2c_master_recv failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ if (buf[0] != 0xA0) { ++ zilog_error("unexpected IR TX response #1: %02x\n", ++ buf[0]); ++ return -EFAULT; ++ } ++ ++ /* Send prepare command? */ ++ buf[0] = 0x00; ++ buf[1] = 0x80; ++ ret = i2c_master_send(&ir->c_tx, buf, 2); ++ if (ret != 2) { ++ zilog_error("i2c_master_send failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ++#ifdef I2C_HW_B_HDPVR ++ /* ++ * The sleep bits aren't necessary on the HD PVR, and in fact, the ++ * last i2c_master_recv always fails with a -5, so for now, we're ++ * going to skip this whole mess and say we're done on the HD PVR ++ */ ++ if (ir->c_rx.adapter->id == I2C_HW_B_HDPVR) ++ goto done; ++#endif ++ ++ /* ++ * This bit NAKs until the device is ready, so we retry it ++ * sleeping a bit each time. This seems to be what the windows ++ * driver does, approximately. ++ * Try for up to 1s. ++ */ ++ for (i = 0; i < 20; ++i) { ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((50 * HZ + 999) / 1000); ++ ret = i2c_master_send(&ir->c_tx, buf, 1); ++ if (ret == 1) ++ break; ++ dprintk("NAK expected: i2c_master_send " ++ "failed with %d (try %d)\n", ret, i+1); ++ } ++ if (ret != 1) { ++ zilog_error("IR TX chip never got ready: last i2c_master_send " ++ "failed with %d\n", ret); ++ return ret < 0 ? ret : -EFAULT; ++ } ++ ++ /* Seems to be an 'ok' response */ ++ i = i2c_master_recv(&ir->c_tx, buf, 1); ++ if (i != 1) { ++ zilog_error("i2c_master_recv failed with %d\n", ret); ++ return -EFAULT; ++ } ++ if (buf[0] != 0x80) { ++ zilog_error("unexpected IR TX response #2: %02x\n", buf[0]); ++ return -EFAULT; ++ } ++ ++done: ++ /* Oh good, it worked */ ++ dprintk("sent code %u, key %u\n", code, key); ++ return 0; ++} ++ ++/* ++ * Write a code to the device. We take in a 32-bit number (an int) and then ++ * decode this to a codeset/key index. The key data is then decompressed and ++ * sent to the device. We have a spin lock as per i2c documentation to prevent ++ * multiple concurrent sends which would probably cause the device to explode. ++ */ ++static ssize_t write(struct file *filep, const char *buf, size_t n, ++ loff_t *ppos) ++{ ++ struct IR *ir = (struct IR *)filep->private_data; ++ size_t i; ++ int failures = 0; ++ ++ if (ir->c_tx.addr == 0) ++ return -ENODEV; ++ ++ /* Validate user parameters */ ++ if (n % sizeof(int)) ++ return -EINVAL; ++ ++ /* Lock i2c bus for the duration */ ++ mutex_lock(&ir->ir_lock); ++ ++ /* Send each keypress */ ++ for (i = 0; i < n;) { ++ int ret = 0; ++ int command; ++ ++ if (copy_from_user(&command, buf + i, sizeof(command))) { ++ mutex_unlock(&ir->ir_lock); ++ return -EFAULT; ++ } ++ ++ /* Send boot data first if required */ ++ if (ir->need_boot == 1) { ++ ret = send_boot_data(ir); ++ if (ret == 0) ++ ir->need_boot = 0; ++ } ++ ++ /* Send the code */ ++ if (ret == 0) { ++ ret = send_code(ir, (unsigned)command >> 16, ++ (unsigned)command & 0xFFFF); ++ if (ret == -EPROTO) { ++ mutex_unlock(&ir->ir_lock); ++ return ret; ++ } ++ } ++ ++ /* ++ * Hmm, a failure. If we've had a few then give up, otherwise ++ * try a reset ++ */ ++ if (ret != 0) { ++ /* Looks like the chip crashed, reset it */ ++ zilog_error("sending to the IR transmitter chip " ++ "failed, trying reset\n"); ++ ++ if (failures >= 3) { ++ zilog_error("unable to send to the IR chip " ++ "after 3 resets, giving up\n"); ++ mutex_unlock(&ir->ir_lock); ++ return ret; ++ } ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ schedule_timeout((100 * HZ + 999) / 1000); ++ ir->need_boot = 1; ++ ++failures; ++ } else ++ i += sizeof(int); ++ } ++ ++ /* Release i2c bus */ ++ mutex_unlock(&ir->ir_lock); ++ ++ /* All looks good */ ++ return n; ++} ++ ++/* copied from lirc_dev */ ++static unsigned int poll(struct file *filep, poll_table *wait) ++{ ++ struct IR *ir = (struct IR *)filep->private_data; ++ unsigned int ret; ++ ++ dprintk("poll called\n"); ++ if (ir->c_rx.addr == 0) ++ return -ENODEV; ++ ++ mutex_lock(&ir->buf_lock); ++ ++ poll_wait(filep, &ir->buf.wait_poll, wait); ++ ++ dprintk("poll result = %s\n", ++ lirc_buffer_empty(&ir->buf) ? "0" : "POLLIN|POLLRDNORM"); ++ ++ ret = lirc_buffer_empty(&ir->buf) ? 0 : (POLLIN|POLLRDNORM); ++ ++ mutex_unlock(&ir->buf_lock); ++ return ret; ++} ++ ++static int ioctl(struct inode *node, struct file *filep, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct IR *ir = (struct IR *)filep->private_data; ++ int result; ++ unsigned long mode, features = 0; ++ ++ if (ir->c_rx.addr != 0) ++ features |= LIRC_CAN_REC_LIRCCODE; ++ if (ir->c_tx.addr != 0) ++ features |= LIRC_CAN_SEND_PULSE; ++ ++ switch (cmd) { ++ case LIRC_GET_LENGTH: ++ result = put_user((unsigned long)13, ++ (unsigned long *)arg); ++ break; ++ case LIRC_GET_FEATURES: ++ result = put_user(features, (unsigned long *) arg); ++ break; ++ case LIRC_GET_REC_MODE: ++ if (!(features&LIRC_CAN_REC_MASK)) ++ return -ENOSYS; ++ ++ result = put_user(LIRC_REC2MODE ++ (features&LIRC_CAN_REC_MASK), ++ (unsigned long *)arg); ++ break; ++ case LIRC_SET_REC_MODE: ++ if (!(features&LIRC_CAN_REC_MASK)) ++ return -ENOSYS; ++ ++ result = get_user(mode, (unsigned long *)arg); ++ if (!result && !(LIRC_MODE2REC(mode) & features)) ++ result = -EINVAL; ++ break; ++ case LIRC_GET_SEND_MODE: ++ if (!(features&LIRC_CAN_SEND_MASK)) ++ return -ENOSYS; ++ ++ result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); ++ break; ++ case LIRC_SET_SEND_MODE: ++ if (!(features&LIRC_CAN_SEND_MASK)) ++ return -ENOSYS; ++ ++ result = get_user(mode, (unsigned long *) arg); ++ if (!result && mode != LIRC_MODE_PULSE) ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ return result; ++} ++ ++/* ++ * Open the IR device. Get hold of our IR structure and ++ * stash it in private_data for the file ++ */ ++static int open(struct inode *node, struct file *filep) ++{ ++ struct IR *ir; ++ int ret; ++ ++ /* find our IR struct */ ++ unsigned minor = MINOR(node->i_rdev); ++ if (minor >= MAX_IRCTL_DEVICES) { ++ dprintk("minor %d: open result = -ENODEV\n", ++ minor); ++ return -ENODEV; ++ } ++ ir = ir_devices[minor]; ++ ++ /* increment in use count */ ++ mutex_lock(&ir->ir_lock); ++ ++ir->open; ++ ret = set_use_inc(ir); ++ if (ret != 0) { ++ --ir->open; ++ mutex_unlock(&ir->ir_lock); ++ return ret; ++ } ++ mutex_unlock(&ir->ir_lock); ++ ++ /* stash our IR struct */ ++ filep->private_data = ir; ++ ++ return 0; ++} ++ ++/* Close the IR device */ ++static int close(struct inode *node, struct file *filep) ++{ ++ /* find our IR struct */ ++ struct IR *ir = (struct IR *)filep->private_data; ++ if (ir == NULL) { ++ zilog_error("close: no private_data attached to the file!\n"); ++ return -ENODEV; ++ } ++ ++ /* decrement in use count */ ++ mutex_lock(&ir->ir_lock); ++ --ir->open; ++ set_use_dec(ir); ++ mutex_unlock(&ir->ir_lock); ++ ++ return 0; ++} ++ ++static struct lirc_driver lirc_template = { ++ .name = "lirc_zilog", ++ .set_use_inc = set_use_inc, ++ .set_use_dec = set_use_dec, ++ .owner = THIS_MODULE ++}; ++ ++static int ir_remove(struct i2c_client *client); ++static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); ++static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); ++ ++static const struct i2c_device_id ir_transceiver_id[] = { ++ /* Generic entry for any IR transceiver */ ++ { "ir_video", 0 }, ++ /* IR device specific entries should be added here */ ++ { "ir_tx_z8f0811_haup", 0 }, ++ { "ir_rx_z8f0811_haup", 0 }, ++ { } ++}; ++ ++static struct i2c_driver driver = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "Zilog/Hauppauge i2c IR", ++ }, ++ .probe = ir_probe, ++ .remove = ir_remove, ++ .command = ir_command, ++ .id_table = ir_transceiver_id, ++}; ++ ++static struct file_operations lirc_fops = { ++ .owner = THIS_MODULE, ++ .llseek = lseek, ++ .read = read, ++ .write = write, ++ .poll = poll, ++ .ioctl = ioctl, ++ .open = open, ++ .release = close ++}; ++ ++static int ir_remove(struct i2c_client *client) ++{ ++ struct IR *ir = i2c_get_clientdata(client); ++ ++ mutex_lock(&ir->ir_lock); ++ ++ if (ir->have_rx || ir->have_tx) { ++ DECLARE_COMPLETION(tn); ++ DECLARE_COMPLETION(tn2); ++ ++ /* end up polling thread */ ++ if (ir->task && !IS_ERR(ir->task)) { ++ ir->t_notify = &tn; ++ ir->t_notify2 = &tn2; ++ ir->shutdown = 1; ++ wake_up_process(ir->task); ++ complete(&tn2); ++ wait_for_completion(&tn); ++ ir->t_notify = NULL; ++ ir->t_notify2 = NULL; ++ } ++ ++ } else { ++ mutex_unlock(&ir->ir_lock); ++ zilog_error("%s: detached from something we didn't " ++ "attach to\n", __func__); ++ return -ENODEV; ++ } ++ ++ /* unregister lirc driver */ ++ if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) { ++ lirc_unregister_driver(ir->l.minor); ++ ir_devices[ir->l.minor] = NULL; ++ } ++ ++ /* free memory */ ++ lirc_buffer_free(&ir->buf); ++ mutex_unlock(&ir->ir_lock); ++ kfree(ir); ++ ++ return 0; ++} ++ ++static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ struct IR *ir = NULL; ++ struct i2c_adapter *adap = client->adapter; ++ char buf; ++ int ret; ++ int have_rx = 0, have_tx = 0; ++ ++ dprintk("%s: adapter id=0x%x, client addr=0x%02x\n", ++ __func__, adap->id, client->addr); ++ ++ /* ++ * The external IR receiver is at i2c address 0x71. ++ * The IR transmitter is at 0x70. ++ */ ++ client->addr = 0x70; ++ ++ if (!disable_tx) { ++ if (i2c_master_recv(client, &buf, 1) == 1) ++ have_tx = 1; ++ dprintk("probe 0x70 @ %s: %s\n", ++ adap->name, have_tx ? "success" : "failed"); ++ } ++ ++ if (!disable_rx) { ++ client->addr = 0x71; ++ if (i2c_master_recv(client, &buf, 1) == 1) ++ have_rx = 1; ++ dprintk("probe 0x71 @ %s: %s\n", ++ adap->name, have_rx ? "success" : "failed"); ++ } ++ ++ if (!(have_rx || have_tx)) { ++ zilog_error("%s: no devices found\n", adap->name); ++ goto out_nodev; ++ } ++ ++ printk(KERN_INFO "lirc_zilog: chip found with %s\n", ++ have_rx && have_tx ? "RX and TX" : ++ have_rx ? "RX only" : "TX only"); ++ ++ ir = kzalloc(sizeof(struct IR), GFP_KERNEL); ++ ++ if (!ir) ++ goto out_nomem; ++ ++ ret = lirc_buffer_init(&ir->buf, 2, BUFLEN / 2); ++ if (ret) ++ goto out_nomem; ++ ++ mutex_init(&ir->ir_lock); ++ mutex_init(&ir->buf_lock); ++ ir->need_boot = 1; ++ ++ memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); ++ ir->l.minor = -1; ++ ++ /* I2C attach to device */ ++ i2c_set_clientdata(client, ir); ++ ++ /* initialise RX device */ ++ if (have_rx) { ++ DECLARE_COMPLETION(tn); ++ memcpy(&ir->c_rx, client, sizeof(struct i2c_client)); ++ ++ ir->c_rx.addr = 0x71; ++ strlcpy(ir->c_rx.name, ZILOG_HAUPPAUGE_IR_RX_NAME, ++ I2C_NAME_SIZE); ++ ++ /* try to fire up polling thread */ ++ ir->t_notify = &tn; ++ ir->task = kthread_run(lirc_thread, ir, "lirc_zilog"); ++ if (IS_ERR(ir->task)) { ++ ret = PTR_ERR(ir->task); ++ zilog_error("lirc_register_driver: cannot run " ++ "poll thread %d\n", ret); ++ goto err; ++ } ++ wait_for_completion(&tn); ++ ir->t_notify = NULL; ++ ir->have_rx = 1; ++ } ++ ++ /* initialise TX device */ ++ if (have_tx) { ++ memcpy(&ir->c_tx, client, sizeof(struct i2c_client)); ++ ir->c_tx.addr = 0x70; ++ strlcpy(ir->c_tx.name, ZILOG_HAUPPAUGE_IR_TX_NAME, ++ I2C_NAME_SIZE); ++ ir->have_tx = 1; ++ } ++ ++ /* set lirc_dev stuff */ ++ ir->l.code_length = 13; ++ ir->l.rbuf = &ir->buf; ++ ir->l.fops = &lirc_fops; ++ ir->l.data = ir; ++ ir->l.minor = minor; ++ ir->l.dev = &adap->dev; ++ ir->l.sample_rate = 0; ++ ++ /* register with lirc */ ++ ir->l.minor = lirc_register_driver(&ir->l); ++ if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { ++ zilog_error("ir_attach: \"minor\" must be between 0 and %d " ++ "(%d)!\n", MAX_IRCTL_DEVICES-1, ir->l.minor); ++ ret = -EBADRQC; ++ goto err; ++ } ++ ++ /* store this for getting back in open() later on */ ++ ir_devices[ir->l.minor] = ir; ++ ++ /* ++ * if we have the tx device, load the 'firmware'. We do this ++ * after registering with lirc as otherwise hotplug seems to take ++ * 10s to create the lirc device. ++ */ ++ if (have_tx) { ++ /* Special TX init */ ++ ret = tx_init(ir); ++ if (ret != 0) ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ /* undo everything, hopefully... */ ++ if (ir->c_rx.addr) ++ ir_remove(&ir->c_rx); ++ if (ir->c_tx.addr) ++ ir_remove(&ir->c_tx); ++ return ret; ++ ++out_nodev: ++ zilog_error("no device found\n"); ++ return -ENODEV; ++ ++out_nomem: ++ zilog_error("memory allocation failure\n"); ++ kfree(ir); ++ return -ENOMEM; ++} ++ ++static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg) ++{ ++ /* nothing */ ++ return 0; ++} ++ ++static int __init zilog_init(void) ++{ ++ int ret; ++ ++ zilog_notify("Zilog/Hauppauge IR driver initializing\n"); ++ ++ mutex_init(&tx_data_lock); ++ ++ request_module("firmware_class"); ++ ++ ret = i2c_add_driver(&driver); ++ if (ret) ++ zilog_error("initialization failed\n"); ++ else ++ zilog_notify("initialization complete\n"); ++ ++ return ret; ++} ++ ++static void __exit zilog_exit(void) ++{ ++ i2c_del_driver(&driver); ++ /* if loaded */ ++ fw_unload(); ++ zilog_notify("Zilog/Hauppauge IR driver unloaded\n"); ++} ++ ++module_init(zilog_init); ++module_exit(zilog_exit); ++ ++MODULE_DESCRIPTION("Zilog/Hauppauge infrared transmitter driver (i2c stack)"); ++MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, " ++ "Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver"); ++MODULE_LICENSE("GPL"); ++/* for compat with old name, which isn't all that accurate anymore */ ++MODULE_ALIAS("lirc_pvr150"); ++ ++module_param(minor, int, 0444); ++MODULE_PARM_DESC(minor, "Preferred minor device number"); ++ ++module_param(debug, bool, 0644); ++MODULE_PARM_DESC(debug, "Enable debugging messages"); ++ ++module_param(disable_rx, bool, 0644); ++MODULE_PARM_DESC(disable_rx, "Disable the IR receiver device"); ++ ++module_param(disable_tx, bool, 0644); ++MODULE_PARM_DESC(disable_tx, "Disable the IR transmitter device"); +diff -Naur linux-2.6.35-rc6/drivers/input/lirc/Makefile linux-2.6.35-rc6.patch/drivers/input/lirc/Makefile +--- linux-2.6.35-rc6/drivers/input/lirc/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/lirc/Makefile 2010-08-02 09:28:03.990051699 +0200 +@@ -0,0 +1,21 @@ ++# Makefile for the lirc drivers. ++# ++ ++# Each configuration option enables a list of files. ++ ++obj-$(CONFIG_INPUT_LIRC) += lirc_dev.o ++obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o ++obj-$(CONFIG_LIRC_ENE0100) += lirc_ene0100.o ++obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o ++obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o ++obj-$(CONFIG_LIRC_IMON) += lirc_imon.o ++obj-$(CONFIG_LIRC_IT87) += lirc_it87.o ++obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o ++obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o ++obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o ++obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o ++obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o ++obj-$(CONFIG_LIRC_SIR) += lirc_sir.o ++obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap.o ++obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o ++obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o +diff -Naur linux-2.6.35-rc6/drivers/input/Makefile linux-2.6.35-rc6.patch/drivers/input/Makefile +--- linux-2.6.35-rc6/drivers/input/Makefile 2010-07-22 21:13:38.000000000 +0200 ++++ linux-2.6.35-rc6.patch/drivers/input/Makefile 2010-08-02 09:28:03.991050074 +0200 +@@ -26,3 +26,5 @@ + obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o + + obj-$(CONFIG_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o ++ ++obj-$(CONFIG_INPUT_LIRC) += lirc/ +diff -Naur linux-2.6.35-rc6/drivers/input/misc/imon.c linux-2.6.35-rc6.patch/drivers/input/misc/imon.c +--- linux-2.6.35-rc6/drivers/input/misc/imon.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/drivers/input/misc/imon.c 2010-08-02 09:28:03.993924653 +0200 +@@ -0,0 +1,2537 @@ ++/* ++ * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD ++ * ++ * Copyright(C) 2009 Jarod Wilson ++ * Portions based on the original lirc_imon driver, ++ * Copyright(C) 2004 Venky Raju(dev@venky.ws) ++ * ++ * imon is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MOD_AUTHOR "Jarod Wilson " ++#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" ++#define MOD_NAME "imon" ++#define MOD_VERSION "0.8" ++ ++#define DISPLAY_MINOR_BASE 144 ++#define DEVICE_NAME "lcd%d" ++ ++#define BUF_CHUNK_SIZE 8 ++#define BUF_SIZE 128 ++ ++#define BIT_DURATION 250 /* each bit received is 250us */ ++ ++#define IMON_CLOCK_ENABLE_PACKETS 2 ++#define IMON_KEY_RELEASE_OFFSET 1000 ++ ++/*** P R O T O T Y P E S ***/ ++ ++/* USB Callback prototypes */ ++static int imon_probe(struct usb_interface *interface, ++ const struct usb_device_id *id); ++static void imon_disconnect(struct usb_interface *interface); ++static void usb_rx_callback_intf0(struct urb *urb); ++static void usb_rx_callback_intf1(struct urb *urb); ++static void usb_tx_callback(struct urb *urb); ++ ++/* suspend/resume support */ ++static int imon_resume(struct usb_interface *intf); ++static int imon_suspend(struct usb_interface *intf, pm_message_t message); ++ ++/* Display file_operations function prototypes */ ++static int display_open(struct inode *inode, struct file *file); ++static int display_close(struct inode *inode, struct file *file); ++ ++/* VFD write operation */ ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos); ++ ++/* LCD file_operations override function prototypes */ ++static ssize_t lcd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos); ++ ++/*** G L O B A L S ***/ ++ ++struct imon_context { ++ struct device *dev; ++ struct usb_device *usbdev_intf0; ++ /* Newer devices have two interfaces */ ++ struct usb_device *usbdev_intf1; ++ bool display_supported; /* not all controllers do */ ++ bool display_isopen; /* display port has been opened */ ++ bool ir_isassociating; /* IR port open for association */ ++ bool dev_present_intf0; /* USB device presence, interface 0 */ ++ bool dev_present_intf1; /* USB device presence, interface 1 */ ++ struct mutex lock; /* to lock this object */ ++ wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ ++ ++ struct usb_endpoint_descriptor *rx_endpoint_intf0; ++ struct usb_endpoint_descriptor *rx_endpoint_intf1; ++ struct usb_endpoint_descriptor *tx_endpoint; ++ struct urb *rx_urb_intf0; ++ struct urb *rx_urb_intf1; ++ struct urb *tx_urb; ++ bool tx_control; ++ unsigned char usb_rx_buf[8]; ++ unsigned char usb_tx_buf[8]; ++ ++ struct tx_t { ++ unsigned char data_buf[35]; /* user data buffer */ ++ struct completion finished; /* wait for write to finish */ ++ bool busy; /* write in progress */ ++ int status; /* status of tx completion */ ++ } tx; ++ ++ u16 vendor; /* usb vendor ID */ ++ u16 product; /* usb product ID */ ++ int ir_protocol; /* iMON or MCE (RC6) IR protocol? */ ++ struct input_dev *idev; /* input device for remote */ ++ struct input_dev *touch; /* input device for touchscreen */ ++ int ki; /* current input keycode key index */ ++ u16 kc; /* current input keycode */ ++ u16 last_keycode; /* last reported input keycode */ ++ u8 mce_toggle_bit; /* last mce toggle bit */ ++ int display_type; /* store the display type */ ++ bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */ ++ int touch_x; /* x coordinate on touchscreen */ ++ int touch_y; /* y coordinate on touchscreen */ ++ char name_idev[128]; /* input device name */ ++ char phys_idev[64]; /* input device phys path */ ++ struct timer_list itimer; /* input device timer, need for rc6 */ ++ char name_touch[128]; /* touch screen name */ ++ char phys_touch[64]; /* touch screen phys path */ ++ struct timer_list ttimer; /* touch screen timer */ ++}; ++ ++#define TOUCH_TIMEOUT (HZ/30) ++#define MCE_TIMEOUT_MS 200 ++ ++/* vfd character device file operations */ ++static const struct file_operations vfd_fops = { ++ .owner = THIS_MODULE, ++ .open = &display_open, ++ .write = &vfd_write, ++ .release = &display_close ++}; ++ ++/* lcd character device file operations */ ++static const struct file_operations lcd_fops = { ++ .owner = THIS_MODULE, ++ .open = &display_open, ++ .write = &lcd_write, ++ .release = &display_close ++}; ++ ++enum { ++ IMON_DISPLAY_TYPE_AUTO = 0, ++ IMON_DISPLAY_TYPE_VFD = 1, ++ IMON_DISPLAY_TYPE_LCD = 2, ++ IMON_DISPLAY_TYPE_VGA = 3, ++ IMON_DISPLAY_TYPE_NONE = 4, ++}; ++ ++enum { ++ IMON_IR_PROTOCOL_IMON = 0, ++ IMON_IR_PROTOCOL_MCE = 1, ++ IMON_IR_PROTOCOL_IMON_NOPAD = 2, ++}; ++ ++enum { ++ IMON_BUTTON_IMON = 0, ++ IMON_BUTTON_MCE = 1, ++ IMON_BUTTON_PANEL = 2, ++}; ++ ++/* ++ * USB Device ID for iMON USB Control Boards ++ * ++ * The Windows drivers contain 6 different inf files, more or less one for ++ * each new device until the 0x0034-0x0046 devices, which all use the same ++ * driver. Some of the devices in the 34-46 range haven't been definitively ++ * identified yet. Early devices have either a TriGem Computer, Inc. or a ++ * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later ++ * devices use the SoundGraph vendor ID (0x15c2). This driver only supports ++ * the ffdc and later devices, which do onboard decoding. ++ */ ++static struct usb_device_id imon_usb_id_table[] = { ++ /* ++ * Several devices with this same device ID, all use iMON_PAD.inf ++ * SoundGraph iMON PAD (IR & VFD) ++ * SoundGraph iMON PAD (IR & LCD) ++ * SoundGraph iMON Knob (IR only) ++ */ ++ { USB_DEVICE(0x15c2, 0xffdc) }, ++ ++ /* ++ * Newer devices, all driven by the latest iMON Windows driver, full ++ * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2' ++ * Need user input to fill in details on unknown devices. ++ */ ++ /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */ ++ { USB_DEVICE(0x15c2, 0x0034) }, ++ /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */ ++ { USB_DEVICE(0x15c2, 0x0035) }, ++ /* SoundGraph iMON OEM VFD (IR & VFD) */ ++ { USB_DEVICE(0x15c2, 0x0036) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x0037) }, ++ /* SoundGraph iMON OEM LCD (IR & LCD) */ ++ { USB_DEVICE(0x15c2, 0x0038) }, ++ /* SoundGraph iMON UltraBay (IR & LCD) */ ++ { USB_DEVICE(0x15c2, 0x0039) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x003a) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x003b) }, ++ /* SoundGraph iMON OEM Inside (IR only) */ ++ { USB_DEVICE(0x15c2, 0x003c) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x003d) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x003e) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x003f) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x0040) }, ++ /* SoundGraph iMON MINI (IR only) */ ++ { USB_DEVICE(0x15c2, 0x0041) }, ++ /* Antec Veris Multimedia Station EZ External (IR only) */ ++ { USB_DEVICE(0x15c2, 0x0042) }, ++ /* Antec Veris Multimedia Station Basic Internal (IR only) */ ++ { USB_DEVICE(0x15c2, 0x0043) }, ++ /* Antec Veris Multimedia Station Elite (IR & VFD) */ ++ { USB_DEVICE(0x15c2, 0x0044) }, ++ /* Antec Veris Multimedia Station Premiere (IR & LCD) */ ++ { USB_DEVICE(0x15c2, 0x0045) }, ++ /* device specifics unknown */ ++ { USB_DEVICE(0x15c2, 0x0046) }, ++ {} ++}; ++ ++/* iMON LCD models use a different write op */ ++static struct usb_device_id lcd_device_list[] = { ++ { USB_DEVICE(0x15c2, 0xffdc) }, ++ { USB_DEVICE(0x15c2, 0x0038) }, ++ { USB_DEVICE(0x15c2, 0x0039) }, ++ { USB_DEVICE(0x15c2, 0x0045) }, ++ {} ++}; ++ ++/* Some iMON devices have no lcd/vfd, don't set one up */ ++static struct usb_device_id ir_only_list[] = { ++ /* the first imon lcd and the knob share this device id. :\ */ ++ /*{ USB_DEVICE(0x15c2, 0xffdc) },*/ ++ { USB_DEVICE(0x15c2, 0x003c) }, ++ { USB_DEVICE(0x15c2, 0x0041) }, ++ { USB_DEVICE(0x15c2, 0x0042) }, ++ { USB_DEVICE(0x15c2, 0x0043) }, ++ {} ++}; ++ ++/* iMON devices with VGA touchscreens */ ++static struct usb_device_id imon_touchscreen_list[] = { ++ { USB_DEVICE(0x15c2, 0x0034) }, ++ { USB_DEVICE(0x15c2, 0x0035) }, ++ {} ++}; ++ ++/* USB Device data */ ++static struct usb_driver imon_driver = { ++ .name = MOD_NAME, ++ .probe = imon_probe, ++ .disconnect = imon_disconnect, ++ .suspend = imon_suspend, ++ .resume = imon_resume, ++ .id_table = imon_usb_id_table, ++}; ++ ++static struct usb_class_driver imon_vfd_class = { ++ .name = DEVICE_NAME, ++ .fops = &vfd_fops, ++ .minor_base = DISPLAY_MINOR_BASE, ++}; ++ ++static struct usb_class_driver imon_lcd_class = { ++ .name = DEVICE_NAME, ++ .fops = &lcd_fops, ++ .minor_base = DISPLAY_MINOR_BASE, ++}; ++ ++/* ++ * standard imon remote key table, which isn't really entirely ++ * "standard", as different receivers decode the same key on the ++ * same remote to different hex codes... ugh. ++ */ ++static const struct key_entry imon_remote_key_table[] = { ++ /* keys sorted mostly by frequency of use to optimize lookups */ ++ { KE_KEY, 0x2a8195b7, { KEY_REWIND } }, ++ { KE_KEY, 0x298315b7, { KEY_REWIND } }, ++ { KE_KEY, 0x2b8115b7, { KEY_FASTFORWARD } }, ++ { KE_KEY, 0x2b8315b7, { KEY_FASTFORWARD } }, ++ { KE_KEY, 0x2b9115b7, { KEY_PREVIOUS } }, ++ { KE_KEY, 0x298195b7, { KEY_NEXT } }, ++ ++ { KE_KEY, 0x2a8115b7, { KEY_PLAY } }, ++ { KE_KEY, 0x2a8315b7, { KEY_PLAY } }, ++ { KE_KEY, 0x2a9115b7, { KEY_PAUSE } }, ++ { KE_KEY, 0x2b9715b7, { KEY_STOP } }, ++ { KE_KEY, 0x298115b7, { KEY_RECORD } }, ++ ++ { KE_KEY, 0x01008000, { KEY_UP } }, ++ { KE_KEY, 0x01007f00, { KEY_DOWN } }, ++ { KE_KEY, 0x01000080, { KEY_LEFT } }, ++ { KE_KEY, 0x0100007f, { KEY_RIGHT } }, ++ ++ { KE_KEY, 0x2aa515b7, { KEY_UP } }, ++ { KE_KEY, 0x289515b7, { KEY_DOWN } }, ++ { KE_KEY, 0x29a515b7, { KEY_LEFT } }, ++ { KE_KEY, 0x2ba515b7, { KEY_RIGHT } }, ++ ++ { KE_KEY, 0x0200002c, { KEY_SPACE } }, /* Select/Space */ ++ { KE_KEY, 0x2a9315b7, { KEY_SPACE } }, /* Select/Space */ ++ { KE_KEY, 0x02000028, { KEY_ENTER } }, ++ { KE_KEY, 0x28a195b7, { KEY_ENTER } }, ++ { KE_KEY, 0x288195b7, { KEY_EXIT } }, ++ { KE_KEY, 0x02000029, { KEY_ESC } }, ++ { KE_KEY, 0x2bb715b7, { KEY_ESC } }, ++ { KE_KEY, 0x0200002a, { KEY_BACKSPACE } }, ++ { KE_KEY, 0x28a115b7, { KEY_BACKSPACE } }, ++ ++ { KE_KEY, 0x2b9595b7, { KEY_MUTE } }, ++ { KE_KEY, 0x28a395b7, { KEY_VOLUMEUP } }, ++ { KE_KEY, 0x28a595b7, { KEY_VOLUMEDOWN } }, ++ { KE_KEY, 0x289395b7, { KEY_CHANNELUP } }, ++ { KE_KEY, 0x288795b7, { KEY_CHANNELDOWN } }, ++ ++ { KE_KEY, 0x0200001e, { KEY_NUMERIC_1 } }, ++ { KE_KEY, 0x0200001f, { KEY_NUMERIC_2 } }, ++ { KE_KEY, 0x02000020, { KEY_NUMERIC_3 } }, ++ { KE_KEY, 0x02000021, { KEY_NUMERIC_4 } }, ++ { KE_KEY, 0x02000022, { KEY_NUMERIC_5 } }, ++ { KE_KEY, 0x02000023, { KEY_NUMERIC_6 } }, ++ { KE_KEY, 0x02000024, { KEY_NUMERIC_7 } }, ++ { KE_KEY, 0x02000025, { KEY_NUMERIC_8 } }, ++ { KE_KEY, 0x02000026, { KEY_NUMERIC_9 } }, ++ { KE_KEY, 0x02000027, { KEY_NUMERIC_0 } }, ++ ++ { KE_KEY, 0x28b595b7, { KEY_NUMERIC_1 } }, ++ { KE_KEY, 0x2bb195b7, { KEY_NUMERIC_2 } }, ++ { KE_KEY, 0x28b195b7, { KEY_NUMERIC_3 } }, ++ { KE_KEY, 0x2a8595b7, { KEY_NUMERIC_4 } }, ++ { KE_KEY, 0x299595b7, { KEY_NUMERIC_5 } }, ++ { KE_KEY, 0x2aa595b7, { KEY_NUMERIC_6 } }, ++ { KE_KEY, 0x2b9395b7, { KEY_NUMERIC_7 } }, ++ { KE_KEY, 0x2a8515b7, { KEY_NUMERIC_8 } }, ++ { KE_KEY, 0x2aa115b7, { KEY_NUMERIC_9 } }, ++ { KE_KEY, 0x2ba595b7, { KEY_NUMERIC_0 } }, ++ ++ { KE_KEY, 0x02200025, { KEY_NUMERIC_STAR } }, ++ { KE_KEY, 0x28b515b7, { KEY_NUMERIC_STAR } }, ++ { KE_KEY, 0x02200020, { KEY_NUMERIC_POUND } }, ++ { KE_KEY, 0x29a115b7, { KEY_NUMERIC_POUND } }, ++ ++ { KE_KEY, 0x2b8515b7, { KEY_VIDEO } }, ++ { KE_KEY, 0x299195b7, { KEY_AUDIO } }, ++ { KE_KEY, 0x2ba115b7, { KEY_CAMERA } }, ++ { KE_KEY, 0x28a515b7, { KEY_TV } }, ++ { KE_KEY, 0x29a395b7, { KEY_DVD } }, ++ { KE_KEY, 0x29a295b7, { KEY_DVD } }, ++ ++ /* the Menu key between DVD and Subtitle on the RM-200... */ ++ { KE_KEY, 0x2ba385b7, { KEY_MENU } }, ++ { KE_KEY, 0x2ba395b7, { KEY_MENU } }, ++ ++ { KE_KEY, 0x288515b7, { KEY_BOOKMARKS } }, ++ { KE_KEY, 0x2ab715b7, { KEY_MEDIA } }, /* Thumbnail */ ++ { KE_KEY, 0x298595b7, { KEY_SUBTITLE } }, ++ { KE_KEY, 0x2b8595b7, { KEY_LANGUAGE } }, ++ ++ { KE_KEY, 0x29a595b7, { KEY_ZOOM } }, ++ { KE_KEY, 0x2aa395b7, { KEY_SCREEN } }, /* FullScreen */ ++ ++ { KE_KEY, 0x299115b7, { KEY_KEYBOARD } }, ++ { KE_KEY, 0x299135b7, { KEY_KEYBOARD } }, ++ ++ { KE_KEY, 0x01010000, { BTN_LEFT } }, ++ { KE_KEY, 0x01020000, { BTN_RIGHT } }, ++ { KE_KEY, 0x01010080, { BTN_LEFT } }, ++ { KE_KEY, 0x01020080, { BTN_RIGHT } }, ++ { KE_KEY, 0x688301b7, { BTN_LEFT } }, ++ { KE_KEY, 0x688481b7, { BTN_RIGHT } }, ++ ++ { KE_KEY, 0x2a9395b7, { KEY_CYCLEWINDOWS } }, /* TaskSwitcher */ ++ { KE_KEY, 0x2b8395b7, { KEY_TIME } }, /* Timer */ ++ ++ { KE_KEY, 0x289115b7, { KEY_POWER } }, ++ { KE_KEY, 0x29b195b7, { KEY_EJECTCD } }, /* the one next to play */ ++ { KE_KEY, 0x299395b7, { KEY_EJECTCLOSECD } }, /* eject (by TaskSw) */ ++ ++ { KE_KEY, 0x02800000, { KEY_CONTEXT_MENU } }, /* Left Menu */ ++ { KE_KEY, 0x2b8195b7, { KEY_CONTEXT_MENU } }, /* Left Menu*/ ++ { KE_KEY, 0x02000065, { KEY_COMPOSE } }, /* RightMenu */ ++ { KE_KEY, 0x28b715b7, { KEY_COMPOSE } }, /* RightMenu */ ++ { KE_KEY, 0x2ab195b7, { KEY_PROG1 } }, /* Go or MultiMon */ ++ { KE_KEY, 0x29b715b7, { KEY_DASHBOARD } }, /* AppLauncher */ ++ { KE_END, 0 } ++}; ++ ++/* mce-mode imon mce remote key table */ ++static const struct key_entry imon_mce_key_table[] = { ++ /* keys sorted mostly by frequency of use to optimize lookups */ ++ { KE_KEY, 0x800ff415, { KEY_REWIND } }, ++ { KE_KEY, 0x800ff414, { KEY_FASTFORWARD } }, ++ { KE_KEY, 0x800ff41b, { KEY_PREVIOUS } }, ++ { KE_KEY, 0x800ff41a, { KEY_NEXT } }, ++ ++ { KE_KEY, 0x800ff416, { KEY_PLAY } }, ++ { KE_KEY, 0x800ff418, { KEY_PAUSE } }, ++ { KE_KEY, 0x800ff419, { KEY_STOP } }, ++ { KE_KEY, 0x800ff417, { KEY_RECORD } }, ++ ++ { KE_KEY, 0x02000052, { KEY_UP } }, ++ { KE_KEY, 0x02000051, { KEY_DOWN } }, ++ { KE_KEY, 0x02000050, { KEY_LEFT } }, ++ { KE_KEY, 0x0200004f, { KEY_RIGHT } }, ++ ++ { KE_KEY, 0x800ff41e, { KEY_UP } }, ++ { KE_KEY, 0x800ff41f, { KEY_DOWN } }, ++ { KE_KEY, 0x800ff420, { KEY_LEFT } }, ++ { KE_KEY, 0x800ff421, { KEY_RIGHT } }, ++ ++ /* 0x800ff40b also KEY_NUMERIC_POUND on some receivers */ ++ { KE_KEY, 0x800ff40b, { KEY_ENTER } }, ++ { KE_KEY, 0x02000028, { KEY_ENTER } }, ++/* the OK and Enter buttons decode to the same value on some remotes ++ { KE_KEY, 0x02000028, { KEY_OK } }, */ ++ { KE_KEY, 0x800ff422, { KEY_OK } }, ++ { KE_KEY, 0x0200002a, { KEY_EXIT } }, ++ { KE_KEY, 0x800ff423, { KEY_EXIT } }, ++ { KE_KEY, 0x02000029, { KEY_DELETE } }, ++ /* 0x800ff40a also KEY_NUMERIC_STAR on some receivers */ ++ { KE_KEY, 0x800ff40a, { KEY_DELETE } }, ++ ++ { KE_KEY, 0x800ff40e, { KEY_MUTE } }, ++ { KE_KEY, 0x800ff410, { KEY_VOLUMEUP } }, ++ { KE_KEY, 0x800ff411, { KEY_VOLUMEDOWN } }, ++ { KE_KEY, 0x800ff412, { KEY_CHANNELUP } }, ++ { KE_KEY, 0x800ff413, { KEY_CHANNELDOWN } }, ++ ++ { KE_KEY, 0x0200001e, { KEY_NUMERIC_1 } }, ++ { KE_KEY, 0x0200001f, { KEY_NUMERIC_2 } }, ++ { KE_KEY, 0x02000020, { KEY_NUMERIC_3 } }, ++ { KE_KEY, 0x02000021, { KEY_NUMERIC_4 } }, ++ { KE_KEY, 0x02000022, { KEY_NUMERIC_5 } }, ++ { KE_KEY, 0x02000023, { KEY_NUMERIC_6 } }, ++ { KE_KEY, 0x02000024, { KEY_NUMERIC_7 } }, ++ { KE_KEY, 0x02000025, { KEY_NUMERIC_8 } }, ++ { KE_KEY, 0x02000026, { KEY_NUMERIC_9 } }, ++ { KE_KEY, 0x02000027, { KEY_NUMERIC_0 } }, ++ ++ { KE_KEY, 0x800ff401, { KEY_NUMERIC_1 } }, ++ { KE_KEY, 0x800ff402, { KEY_NUMERIC_2 } }, ++ { KE_KEY, 0x800ff403, { KEY_NUMERIC_3 } }, ++ { KE_KEY, 0x800ff404, { KEY_NUMERIC_4 } }, ++ { KE_KEY, 0x800ff405, { KEY_NUMERIC_5 } }, ++ { KE_KEY, 0x800ff406, { KEY_NUMERIC_6 } }, ++ { KE_KEY, 0x800ff407, { KEY_NUMERIC_7 } }, ++ { KE_KEY, 0x800ff408, { KEY_NUMERIC_8 } }, ++ { KE_KEY, 0x800ff409, { KEY_NUMERIC_9 } }, ++ { KE_KEY, 0x800ff400, { KEY_NUMERIC_0 } }, ++ ++ { KE_KEY, 0x02200025, { KEY_NUMERIC_STAR } }, ++ { KE_KEY, 0x02200020, { KEY_NUMERIC_POUND } }, ++ /* 0x800ff41d also KEY_BLUE on some receivers */ ++ { KE_KEY, 0x800ff41d, { KEY_NUMERIC_STAR } }, ++ /* 0x800ff41c also KEY_PREVIOUS on some receivers */ ++ { KE_KEY, 0x800ff41c, { KEY_NUMERIC_POUND } }, ++ ++ { KE_KEY, 0x800ff446, { KEY_TV } }, ++ { KE_KEY, 0x800ff447, { KEY_AUDIO } }, /* My Music */ ++ { KE_KEY, 0x800ff448, { KEY_PVR } }, /* RecordedTV */ ++ { KE_KEY, 0x800ff449, { KEY_CAMERA } }, ++ { KE_KEY, 0x800ff44a, { KEY_VIDEO } }, ++ /* 0x800ff424 also KEY_MENU on some receivers */ ++ { KE_KEY, 0x800ff424, { KEY_DVD } }, ++ /* 0x800ff425 also KEY_GREEN on some receivers */ ++ { KE_KEY, 0x800ff425, { KEY_TUNER } }, /* LiveTV */ ++ { KE_KEY, 0x800ff450, { KEY_RADIO } }, ++ ++ { KE_KEY, 0x800ff44c, { KEY_LANGUAGE } }, ++ { KE_KEY, 0x800ff427, { KEY_ZOOM } }, /* Aspect */ ++ ++ { KE_KEY, 0x800ff45b, { KEY_RED } }, ++ { KE_KEY, 0x800ff45c, { KEY_GREEN } }, ++ { KE_KEY, 0x800ff45d, { KEY_YELLOW } }, ++ { KE_KEY, 0x800ff45e, { KEY_BLUE } }, ++ ++ { KE_KEY, 0x800ff466, { KEY_RED } }, ++ /* { KE_KEY, 0x800ff425, { KEY_GREEN } }, */ ++ { KE_KEY, 0x800ff468, { KEY_YELLOW } }, ++ /* { KE_KEY, 0x800ff41d, { KEY_BLUE } }, */ ++ ++ { KE_KEY, 0x800ff40f, { KEY_INFO } }, ++ { KE_KEY, 0x800ff426, { KEY_EPG } }, /* Guide */ ++ { KE_KEY, 0x800ff45a, { KEY_SUBTITLE } }, /* Caption/Teletext */ ++ { KE_KEY, 0x800ff44d, { KEY_TITLE } }, ++ ++ { KE_KEY, 0x800ff40c, { KEY_POWER } }, ++ { KE_KEY, 0x800ff40d, { KEY_PROG1 } }, /* Windows MCE button */ ++ { KE_END, 0 } ++ ++}; ++ ++/* imon receiver front panel/knob key table */ ++static const struct { ++ u64 hw_code; ++ u16 keycode; ++} imon_panel_key_table[] = { ++ { 0x000000000f00ffee, KEY_PROG1 }, /* Go */ ++ { 0x000000001f00ffee, KEY_AUDIO }, ++ { 0x000000002000ffee, KEY_VIDEO }, ++ { 0x000000002100ffee, KEY_CAMERA }, ++ { 0x000000002700ffee, KEY_DVD }, ++ { 0x000000002300ffee, KEY_TV }, ++ { 0x000000000500ffee, KEY_PREVIOUS }, ++ { 0x000000000700ffee, KEY_REWIND }, ++ { 0x000000000400ffee, KEY_STOP }, ++ { 0x000000003c00ffee, KEY_PLAYPAUSE }, ++ { 0x000000000800ffee, KEY_FASTFORWARD }, ++ { 0x000000000600ffee, KEY_NEXT }, ++ { 0x000000010000ffee, KEY_RIGHT }, ++ { 0x000001000000ffee, KEY_LEFT }, ++ { 0x000000003d00ffee, KEY_SELECT }, ++ { 0x000100000000ffee, KEY_VOLUMEUP }, ++ { 0x010000000000ffee, KEY_VOLUMEDOWN }, ++ { 0x000000000100ffee, KEY_MUTE }, ++ /* iMON Knob values */ ++ { 0x000100ffffffffee, KEY_VOLUMEUP }, ++ { 0x010000ffffffffee, KEY_VOLUMEDOWN }, ++ { 0x000008ffffffffee, KEY_MUTE }, ++}; ++ ++/* to prevent races between open() and disconnect(), probing, etc */ ++static DEFINE_MUTEX(driver_lock); ++ ++/* Module bookkeeping bits */ ++MODULE_AUTHOR(MOD_AUTHOR); ++MODULE_DESCRIPTION(MOD_DESC); ++MODULE_VERSION(MOD_VERSION); ++MODULE_LICENSE("GPL"); ++MODULE_DEVICE_TABLE(usb, imon_usb_id_table); ++ ++static bool debug; ++module_param(debug, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); ++ ++/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */ ++static int display_type; ++module_param(display_type, int, S_IRUGO); ++MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, " ++ "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)"); ++ ++/* IR protocol: native iMON, Windows MCE (RC-6), or iMON w/o PAD stabilize */ ++static int ir_protocol; ++module_param(ir_protocol, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(ir_protocol, "Which IR protocol to use. 0=native iMON, " ++ "1=Windows Media Center Ed. (RC-6), 2=iMON w/o PAD stabilize " ++ "(default: native iMON)"); ++ ++/* ++ * In certain use cases, mouse mode isn't really helpful, and could actually ++ * cause confusion, so allow disabling it when the IR device is open. ++ */ ++static bool nomouse; ++module_param(nomouse, bool, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is " ++ "open. 0=don't disable, 1=disable. (default: don't disable)"); ++ ++/* threshold at which a pad push registers as an arrow key in kbd mode */ ++static int pad_thresh; ++module_param(pad_thresh, int, S_IRUGO | S_IWUSR); ++MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an " ++ "arrow key in kbd mode (default: 28)"); ++ ++ ++static void free_imon_context(struct imon_context *ictx) ++{ ++ struct device *dev = ictx->dev; ++ ++ usb_free_urb(ictx->tx_urb); ++ usb_free_urb(ictx->rx_urb_intf0); ++ usb_free_urb(ictx->rx_urb_intf1); ++ kfree(ictx); ++ ++ dev_dbg(dev, "%s: iMON context freed\n", __func__); ++} ++ ++/** ++ * Called when the Display device (e.g. /dev/lcd0) ++ * is opened by the application. ++ */ ++static int display_open(struct inode *inode, struct file *file) ++{ ++ struct usb_interface *interface; ++ struct imon_context *ictx = NULL; ++ int subminor; ++ int retval = 0; ++ ++ /* prevent races with disconnect */ ++ mutex_lock(&driver_lock); ++ ++ subminor = iminor(inode); ++ interface = usb_find_interface(&imon_driver, subminor); ++ if (!interface) { ++ err("%s: could not find interface for minor %d", ++ __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ictx = usb_get_intfdata(interface); ++ ++ if (!ictx) { ++ err("%s: no context found for minor %d", __func__, subminor); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->display_supported) { ++ err("%s: display not supported by device", __func__); ++ retval = -ENODEV; ++ } else if (ictx->display_isopen) { ++ err("%s: display port is already open", __func__); ++ retval = -EBUSY; ++ } else { ++ ictx->display_isopen = 1; ++ file->private_data = ictx; ++ dev_dbg(ictx->dev, "display port opened\n"); ++ } ++ ++ mutex_unlock(&ictx->lock); ++ ++exit: ++ mutex_unlock(&driver_lock); ++ return retval; ++} ++ ++/** ++ * Called when the display device (e.g. /dev/lcd0) ++ * is closed by the application. ++ */ ++static int display_close(struct inode *inode, struct file *file) ++{ ++ struct imon_context *ictx = NULL; ++ int retval = 0; ++ ++ ictx = (struct imon_context *)file->private_data; ++ ++ if (!ictx) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->display_supported) { ++ err("%s: display not supported by device", __func__); ++ retval = -ENODEV; ++ } else if (!ictx->display_isopen) { ++ err("%s: display is not open", __func__); ++ retval = -EIO; ++ } else { ++ ictx->display_isopen = 0; ++ dev_dbg(ictx->dev, "display port closed\n"); ++ if (!ictx->dev_present_intf0) { ++ /* ++ * Device disconnected before close and IR port is not ++ * open. If IR port is open, context will be deleted by ++ * ir_close. ++ */ ++ mutex_unlock(&ictx->lock); ++ free_imon_context(ictx); ++ return retval; ++ } ++ } ++ ++ mutex_unlock(&ictx->lock); ++ return retval; ++} ++ ++/** ++ * Sends a packet to the device -- this function must be called ++ * with ictx->lock held. ++ */ ++static int send_packet(struct imon_context *ictx) ++{ ++ unsigned int pipe; ++ int interval = 0; ++ int retval = 0; ++ struct usb_ctrlrequest *control_req = NULL; ++ ++ /* Check if we need to use control or interrupt urb */ ++ if (!ictx->tx_control) { ++ pipe = usb_sndintpipe(ictx->usbdev_intf0, ++ ictx->tx_endpoint->bEndpointAddress); ++ interval = ictx->tx_endpoint->bInterval; ++ ++ usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe, ++ ictx->usb_tx_buf, ++ sizeof(ictx->usb_tx_buf), ++ usb_tx_callback, ictx, interval); ++ ++ ictx->tx_urb->actual_length = 0; ++ } else { ++ /* fill request into kmalloc'ed space: */ ++ control_req = kmalloc(sizeof(struct usb_ctrlrequest), ++ GFP_KERNEL); ++ if (control_req == NULL) ++ return -ENOMEM; ++ ++ /* setup packet is '21 09 0200 0001 0008' */ ++ control_req->bRequestType = 0x21; ++ control_req->bRequest = 0x09; ++ control_req->wValue = cpu_to_le16(0x0200); ++ control_req->wIndex = cpu_to_le16(0x0001); ++ control_req->wLength = cpu_to_le16(0x0008); ++ ++ /* control pipe is endpoint 0x00 */ ++ pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0); ++ ++ /* build the control urb */ ++ usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0, ++ pipe, (unsigned char *)control_req, ++ ictx->usb_tx_buf, ++ sizeof(ictx->usb_tx_buf), ++ usb_tx_callback, ictx); ++ ictx->tx_urb->actual_length = 0; ++ } ++ ++ init_completion(&ictx->tx.finished); ++ ictx->tx.busy = 1; ++ smp_rmb(); /* ensure later readers know we're busy */ ++ ++ retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL); ++ if (retval) { ++ ictx->tx.busy = 0; ++ smp_rmb(); /* ensure later readers know we're not busy */ ++ err("%s: error submitting urb(%d)", __func__, retval); ++ } else { ++ /* Wait for transmission to complete (or abort) */ ++ mutex_unlock(&ictx->lock); ++ retval = wait_for_completion_interruptible( ++ &ictx->tx.finished); ++ if (retval) ++ err("%s: task interrupted", __func__); ++ mutex_lock(&ictx->lock); ++ ++ retval = ictx->tx.status; ++ if (retval) ++ err("%s: packet tx failed (%d)", __func__, retval); ++ } ++ ++ kfree(control_req); ++ ++ return retval; ++} ++ ++/** ++ * Sends an associate packet to the iMON 2.4G. ++ * ++ * This might not be such a good idea, since it has an id collision with ++ * some versions of the "IR & VFD" combo. The only way to determine if it ++ * is an RF version is to look at the product description string. (Which ++ * we currently do not fetch). ++ */ ++static int send_associate_24g(struct imon_context *ictx) ++{ ++ int retval; ++ const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x20 }; ++ ++ if (!ictx) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ if (!ictx->dev_present_intf0) { ++ err("%s: no iMON device present", __func__); ++ return -ENODEV; ++ } ++ ++ memcpy(ictx->usb_tx_buf, packet, sizeof(packet)); ++ retval = send_packet(ictx); ++ ++ return retval; ++} ++ ++/** ++ * Sends packets to setup and show clock on iMON display ++ * ++ * Arguments: year - last 2 digits of year, month - 1..12, ++ * day - 1..31, dow - day of the week (0-Sun...6-Sat), ++ * hour - 0..23, minute - 0..59, second - 0..59 ++ */ ++static int send_set_imon_clock(struct imon_context *ictx, ++ unsigned int year, unsigned int month, ++ unsigned int day, unsigned int dow, ++ unsigned int hour, unsigned int minute, ++ unsigned int second) ++{ ++ unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8]; ++ int retval = 0; ++ int i; ++ ++ if (!ictx) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ switch (ictx->display_type) { ++ case IMON_DISPLAY_TYPE_LCD: ++ clock_enable_pkt[0][0] = 0x80; ++ clock_enable_pkt[0][1] = year; ++ clock_enable_pkt[0][2] = month-1; ++ clock_enable_pkt[0][3] = day; ++ clock_enable_pkt[0][4] = hour; ++ clock_enable_pkt[0][5] = minute; ++ clock_enable_pkt[0][6] = second; ++ ++ clock_enable_pkt[1][0] = 0x80; ++ clock_enable_pkt[1][1] = 0; ++ clock_enable_pkt[1][2] = 0; ++ clock_enable_pkt[1][3] = 0; ++ clock_enable_pkt[1][4] = 0; ++ clock_enable_pkt[1][5] = 0; ++ clock_enable_pkt[1][6] = 0; ++ ++ if (ictx->product == 0xffdc) { ++ clock_enable_pkt[0][7] = 0x50; ++ clock_enable_pkt[1][7] = 0x51; ++ } else { ++ clock_enable_pkt[0][7] = 0x88; ++ clock_enable_pkt[1][7] = 0x8a; ++ } ++ ++ break; ++ ++ case IMON_DISPLAY_TYPE_VFD: ++ clock_enable_pkt[0][0] = year; ++ clock_enable_pkt[0][1] = month-1; ++ clock_enable_pkt[0][2] = day; ++ clock_enable_pkt[0][3] = dow; ++ clock_enable_pkt[0][4] = hour; ++ clock_enable_pkt[0][5] = minute; ++ clock_enable_pkt[0][6] = second; ++ clock_enable_pkt[0][7] = 0x40; ++ ++ clock_enable_pkt[1][0] = 0; ++ clock_enable_pkt[1][1] = 0; ++ clock_enable_pkt[1][2] = 1; ++ clock_enable_pkt[1][3] = 0; ++ clock_enable_pkt[1][4] = 0; ++ clock_enable_pkt[1][5] = 0; ++ clock_enable_pkt[1][6] = 0; ++ clock_enable_pkt[1][7] = 0x42; ++ ++ break; ++ ++ default: ++ return -ENODEV; ++ } ++ ++ for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) { ++ memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8); ++ retval = send_packet(ictx); ++ if (retval) { ++ err("%s: send_packet failed for packet %d", ++ __func__, i); ++ break; ++ } ++ } ++ ++ return retval; ++} ++ ++/** ++ * These are the sysfs functions to handle the association on the iMON 2.4G LT. ++ */ ++static ssize_t show_associate_remote(struct device *d, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct imon_context *ictx = dev_get_drvdata(d); ++ ++ if (!ictx) ++ return -ENODEV; ++ ++ mutex_lock(&ictx->lock); ++ if (ictx->ir_isassociating) ++ strcpy(buf, "associating\n"); ++ else ++ strcpy(buf, "closed\n"); ++ ++ dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for " ++ "instructions on how to associate your iMON 2.4G DT/LT " ++ "remote\n"); ++ mutex_unlock(&ictx->lock); ++ return strlen(buf); ++} ++ ++static ssize_t store_associate_remote(struct device *d, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct imon_context *ictx; ++ ++ ictx = dev_get_drvdata(d); ++ ++ if (!ictx) ++ return -ENODEV; ++ ++ mutex_lock(&ictx->lock); ++ ictx->ir_isassociating = 1; ++ send_associate_24g(ictx); ++ mutex_unlock(&ictx->lock); ++ ++ return count; ++} ++ ++/** ++ * sysfs functions to control internal imon clock ++ */ ++static ssize_t show_imon_clock(struct device *d, ++ struct device_attribute *attr, char *buf) ++{ ++ struct imon_context *ictx = dev_get_drvdata(d); ++ size_t len; ++ ++ if (!ictx) ++ return -ENODEV; ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->display_supported) { ++ len = snprintf(buf, PAGE_SIZE, "Not supported."); ++ } else { ++ len = snprintf(buf, PAGE_SIZE, ++ "To set the clock on your iMON display:\n" ++ "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n" ++ "%s", ictx->display_isopen ? ++ "\nNOTE: imon device must be closed\n" : ""); ++ } ++ ++ mutex_unlock(&ictx->lock); ++ ++ return len; ++} ++ ++static ssize_t store_imon_clock(struct device *d, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct imon_context *ictx = dev_get_drvdata(d); ++ ssize_t retval; ++ unsigned int year, month, day, dow, hour, minute, second; ++ ++ if (!ictx) ++ return -ENODEV; ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->display_supported) { ++ retval = -ENODEV; ++ goto exit; ++ } else if (ictx->display_isopen) { ++ retval = -EBUSY; ++ goto exit; ++ } ++ ++ if (sscanf(buf, "%u %u %u %u %u %u %u", &year, &month, &day, &dow, ++ &hour, &minute, &second) != 7) { ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ if ((month < 1 || month > 12) || ++ (day < 1 || day > 31) || (dow > 6) || ++ (hour > 23) || (minute > 59) || (second > 59)) { ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ retval = send_set_imon_clock(ictx, year, month, day, dow, ++ hour, minute, second); ++ if (retval) ++ goto exit; ++ ++ retval = count; ++exit: ++ mutex_unlock(&ictx->lock); ++ ++ return retval; ++} ++ ++ ++static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock, ++ store_imon_clock); ++ ++static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote, ++ store_associate_remote); ++ ++static struct attribute *imon_display_sysfs_entries[] = { ++ &dev_attr_imon_clock.attr, ++ NULL ++}; ++ ++static struct attribute_group imon_display_attribute_group = { ++ .attrs = imon_display_sysfs_entries ++}; ++ ++static struct attribute *imon_rf_sysfs_entries[] = { ++ &dev_attr_associate_remote.attr, ++ NULL ++}; ++ ++static struct attribute_group imon_rf_attribute_group = { ++ .attrs = imon_rf_sysfs_entries ++}; ++ ++/** ++ * Writes data to the VFD. The iMON VFD is 2x16 characters ++ * and requires data in 5 consecutive USB interrupt packets, ++ * each packet but the last carrying 7 bytes. ++ * ++ * I don't know if the VFD board supports features such as ++ * scrolling, clearing rows, blanking, etc. so at ++ * the caller must provide a full screen of data. If fewer ++ * than 32 bytes are provided spaces will be appended to ++ * generate a full screen. ++ */ ++static ssize_t vfd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos) ++{ ++ int i; ++ int offset; ++ int seq; ++ int retval = 0; ++ struct imon_context *ictx; ++ const unsigned char vfd_packet6[] = { ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; ++ ++ ictx = (struct imon_context *)file->private_data; ++ if (!ictx) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->dev_present_intf0) { ++ err("%s: no iMON device present", __func__); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ if (n_bytes <= 0 || n_bytes > 32) { ++ err("%s: invalid payload size", __func__); ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) { ++ retval = -EFAULT; ++ goto exit; ++ } ++ ++ /* Pad with spaces */ ++ for (i = n_bytes; i < 32; ++i) ++ ictx->tx.data_buf[i] = ' '; ++ ++ for (i = 32; i < 35; ++i) ++ ictx->tx.data_buf[i] = 0xFF; ++ ++ offset = 0; ++ seq = 0; ++ ++ do { ++ memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7); ++ ictx->usb_tx_buf[7] = (unsigned char) seq; ++ ++ retval = send_packet(ictx); ++ if (retval) { ++ err("%s: send packet failed for packet #%d", ++ __func__, seq/2); ++ goto exit; ++ } else { ++ seq += 2; ++ offset += 7; ++ } ++ ++ } while (offset < 35); ++ ++ /* Send packet #6 */ ++ memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6)); ++ ictx->usb_tx_buf[7] = (unsigned char) seq; ++ retval = send_packet(ictx); ++ if (retval) ++ err("%s: send packet failed for packet #%d", ++ __func__, seq / 2); ++ ++exit: ++ mutex_unlock(&ictx->lock); ++ ++ return (!retval) ? n_bytes : retval; ++} ++ ++/** ++ * Writes data to the LCD. The iMON OEM LCD screen expects 8-byte ++ * packets. We accept data as 16 hexadecimal digits, followed by a ++ * newline (to make it easy to drive the device from a command-line ++ * -- even though the actual binary data is a bit complicated). ++ * ++ * The device itself is not a "traditional" text-mode display. It's ++ * actually a 16x96 pixel bitmap display. That means if you want to ++ * display text, you've got to have your own "font" and translate the ++ * text into bitmaps for display. This is really flexible (you can ++ * display whatever diacritics you need, and so on), but it's also ++ * a lot more complicated than most LCDs... ++ */ ++static ssize_t lcd_write(struct file *file, const char *buf, ++ size_t n_bytes, loff_t *pos) ++{ ++ int retval = 0; ++ struct imon_context *ictx; ++ ++ ictx = (struct imon_context *)file->private_data; ++ if (!ictx) { ++ err("%s: no context for device", __func__); ++ return -ENODEV; ++ } ++ ++ mutex_lock(&ictx->lock); ++ ++ if (!ictx->display_supported) { ++ err("%s: no iMON display present", __func__); ++ retval = -ENODEV; ++ goto exit; ++ } ++ ++ if (n_bytes != 8) { ++ err("%s: invalid payload size: %d (expecting 8)", ++ __func__, (int) n_bytes); ++ retval = -EINVAL; ++ goto exit; ++ } ++ ++ if (copy_from_user(ictx->usb_tx_buf, buf, 8)) { ++ retval = -EFAULT; ++ goto exit; ++ } ++ ++ retval = send_packet(ictx); ++ if (retval) { ++ err("%s: send packet failed!", __func__); ++ goto exit; ++ } else { ++ dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n", ++ __func__, (int) n_bytes); ++ } ++exit: ++ mutex_unlock(&ictx->lock); ++ return (!retval) ? n_bytes : retval; ++} ++ ++/** ++ * Callback function for USB core API: transmit data ++ */ ++static void usb_tx_callback(struct urb *urb) ++{ ++ struct imon_context *ictx; ++ ++ if (!urb) ++ return; ++ ictx = (struct imon_context *)urb->context; ++ if (!ictx) ++ return; ++ ++ ictx->tx.status = urb->status; ++ ++ /* notify waiters that write has finished */ ++ ictx->tx.busy = 0; ++ smp_rmb(); /* ensure later readers know we're not busy */ ++ complete(&ictx->tx.finished); ++} ++ ++/** ++ * iMON IR receivers support two different signal sets -- those used by ++ * the iMON remotes, and those used by the Windows MCE remotes (which is ++ * really just RC-6), but only one or the other at a time, as the signals ++ * are decoded onboard the receiver. ++ */ ++static void imon_set_ir_protocol(struct imon_context *ictx) ++{ ++ int retval; ++ struct device *dev = ictx->dev; ++ unsigned char ir_proto_packet[] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; ++ ++ switch (ir_protocol) { ++ case IMON_IR_PROTOCOL_MCE: ++ dev_dbg(dev, "Configuring IR receiver for MCE protocol\n"); ++ ir_proto_packet[0] = 0x01; ++ ictx->ir_protocol = IMON_IR_PROTOCOL_MCE; ++ ictx->pad_mouse = 0; ++ break; ++ case IMON_IR_PROTOCOL_IMON: ++ dev_dbg(dev, "Configuring IR receiver for iMON protocol\n"); ++ /* ir_proto_packet[0] = 0x00; // already the default */ ++ ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; ++ ictx->pad_mouse = 1; ++ break; ++ case IMON_IR_PROTOCOL_IMON_NOPAD: ++ dev_dbg(dev, "Configuring IR receiver for iMON protocol " ++ "without PAD stabilize function enabled\n"); ++ /* ir_proto_packet[0] = 0x00; // already the default */ ++ ictx->ir_protocol = IMON_IR_PROTOCOL_IMON_NOPAD; ++ ictx->pad_mouse = 0; ++ break; ++ default: ++ dev_info(dev, "%s: unknown IR protocol specified, will " ++ "just default to iMON protocol\n", __func__); ++ ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; ++ ictx->pad_mouse = 1; ++ break; ++ } ++ ++ memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); ++ ++ retval = send_packet(ictx); ++ if (retval) { ++ dev_info(dev, "%s: failed to set IR protocol, falling back " ++ "to standard iMON protocol mode\n", __func__); ++ ir_protocol = IMON_IR_PROTOCOL_IMON; ++ ictx->ir_protocol = IMON_IR_PROTOCOL_IMON; ++ } ++} ++ ++static inline int tv2int(const struct timeval *a, const struct timeval *b) ++{ ++ int usecs = 0; ++ int sec = 0; ++ ++ if (b->tv_usec > a->tv_usec) { ++ usecs = 1000000; ++ sec--; ++ } ++ ++ usecs += a->tv_usec - b->tv_usec; ++ ++ sec += a->tv_sec - b->tv_sec; ++ sec *= 1000; ++ usecs /= 1000; ++ sec += usecs; ++ ++ if (sec < 0) ++ sec = 1000; ++ ++ return sec; ++} ++ ++/** ++ * The directional pad behaves a bit differently, depending on whether this is ++ * one of the older ffdc devices or a newer device. Newer devices appear to ++ * have a higher resolution matrix for more precise mouse movement, but it ++ * makes things overly sensitive in keyboard mode, so we do some interesting ++ * contortions to make it less touchy. Older devices run through the same ++ * routine with shorter timeout and a smaller threshold. ++ */ ++static int stabilize(int a, int b, u16 timeout, u16 threshold) ++{ ++ struct timeval ct; ++ static struct timeval prev_time = {0, 0}; ++ static struct timeval hit_time = {0, 0}; ++ static int x, y, prev_result, hits; ++ int result = 0; ++ int msec, msec_hit; ++ ++ do_gettimeofday(&ct); ++ msec = tv2int(&ct, &prev_time); ++ msec_hit = tv2int(&ct, &hit_time); ++ ++ if (msec > 100) { ++ x = 0; ++ y = 0; ++ hits = 0; ++ } ++ ++ x += a; ++ y += b; ++ ++ prev_time = ct; ++ ++ if (abs(x) > threshold || abs(y) > threshold) { ++ if (abs(y) > abs(x)) ++ result = (y > 0) ? 0x7F : 0x80; ++ else ++ result = (x > 0) ? 0x7F00 : 0x8000; ++ ++ x = 0; ++ y = 0; ++ ++ if (result == prev_result) { ++ hits++; ++ ++ if (hits > 3) { ++ switch (result) { ++ case 0x7F: ++ y = 17 * threshold / 30; ++ break; ++ case 0x80: ++ y -= 17 * threshold / 30; ++ break; ++ case 0x7F00: ++ x = 17 * threshold / 30; ++ break; ++ case 0x8000: ++ x -= 17 * threshold / 30; ++ break; ++ } ++ } ++ ++ if (hits == 2 && msec_hit < timeout) { ++ result = 0; ++ hits = 1; ++ } ++ } else { ++ prev_result = result; ++ hits = 1; ++ hit_time = ct; ++ } ++ } ++ ++ return result; ++} ++ ++static int imon_remote_key_lookup(u32 hw_code) ++{ ++ int i; ++ u32 code = be32_to_cpu(hw_code); ++ ++ /* Look for the initial press of a button */ ++ for (i = 0; i < ARRAY_SIZE(imon_remote_key_table); i++) ++ if (imon_remote_key_table[i].code == code) ++ return i; ++ ++ /* Look for the release of a button, return index + offset */ ++ for (i = 0; i < ARRAY_SIZE(imon_remote_key_table); i++) ++ if ((imon_remote_key_table[i].code | 0x4000) == code) ++ return i + IMON_KEY_RELEASE_OFFSET; ++ ++ return -1; ++} ++ ++static int imon_mce_key_lookup(u32 hw_code) ++{ ++ int i; ++ u32 code = be32_to_cpu(hw_code); ++ ++#define MCE_KEY_MASK 0x7000 ++#define MCE_TOGGLE_BIT 0x8000 ++ ++ /* ++ * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx ++ * (the toggle bit flipping between alternating key presses), while ++ * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep ++ * the table trim, we always or in the bits to look up 0x8000ff4xx, ++ * but we can't or them into all codes, as some keys are decoded in ++ * a different way w/o the same use of the toggle bit... ++ */ ++ if ((code >> 24) & 0x80) ++ code = code | MCE_KEY_MASK | MCE_TOGGLE_BIT; ++ ++ for (i = 0; i < ARRAY_SIZE(imon_mce_key_table); i++) ++ if (imon_mce_key_table[i].code == code) ++ return i; ++ ++ return -1; ++} ++ ++static int imon_panel_key_lookup(u64 hw_code) ++{ ++ int i; ++ u64 code = be64_to_cpu(hw_code); ++ ++ for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) ++ if (imon_panel_key_table[i].hw_code == (code | 0xffee)) ++ return i; ++ ++ return -1; ++} ++ ++static bool imon_mouse_event(struct imon_context *ictx, ++ unsigned char *buf, int len) ++{ ++ char rel_x = 0x00, rel_y = 0x00; ++ u8 right_shift = 1; ++ bool mouse_input = 1; ++ int dir = 0; ++ ++ /* newer iMON device PAD or mouse button */ ++ if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) { ++ rel_x = buf[2]; ++ rel_y = buf[3]; ++ right_shift = 1; ++ /* 0xffdc iMON PAD or mouse button input */ ++ } else if (ictx->product == 0xffdc && (buf[0] & 0x40) && ++ !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) { ++ rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | ++ (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; ++ if (buf[0] & 0x02) ++ rel_x |= ~0x0f; ++ rel_x = rel_x + rel_x / 2; ++ rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | ++ (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; ++ if (buf[0] & 0x01) ++ rel_y |= ~0x0f; ++ rel_y = rel_y + rel_y / 2; ++ right_shift = 2; ++ /* some ffdc devices decode mouse buttons differently... */ ++ } else if (ictx->product == 0xffdc && (buf[0] == 0x68)) { ++ right_shift = 2; ++ /* ch+/- buttons, which we use for an emulated scroll wheel */ ++ } else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) { ++ dir = 1; ++ } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) { ++ dir = -1; ++ } else ++ mouse_input = 0; ++ ++ if (mouse_input) { ++ dev_dbg(ictx->dev, "sending mouse data via input subsystem\n"); ++ ++ if (dir) { ++ input_report_rel(ictx->idev, REL_WHEEL, dir); ++ } else if (rel_x || rel_y) { ++ input_report_rel(ictx->idev, REL_X, rel_x); ++ input_report_rel(ictx->idev, REL_Y, rel_y); ++ } else { ++ input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1); ++ input_report_key(ictx->idev, BTN_RIGHT, ++ buf[1] >> right_shift & 0x1); ++ } ++ input_sync(ictx->idev); ++ ictx->last_keycode = ictx->kc; ++ } ++ ++ return mouse_input; ++} ++ ++static void imon_touch_event(struct imon_context *ictx, unsigned char *buf) ++{ ++ mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT); ++ ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4); ++ ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf)); ++ input_report_abs(ictx->touch, ABS_X, ictx->touch_x); ++ input_report_abs(ictx->touch, ABS_Y, ictx->touch_y); ++ input_report_key(ictx->touch, BTN_TOUCH, 0x01); ++ input_sync(ictx->touch); ++} ++ ++static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf) ++{ ++ int ki = 1; ++ int dir = 0; ++ int offset = IMON_KEY_RELEASE_OFFSET; ++ char rel_x = 0x00, rel_y = 0x00; ++ u16 timeout, threshold; ++ u64 temp_key; ++ u32 remote_key; ++ ++ /* ++ * The imon directional pad functions more like a touchpad. Bytes 3 & 4 ++ * contain a position coordinate (x,y), with each component ranging ++ * from -14 to 14. We want to down-sample this to only 4 discrete values ++ * for up/down/left/right arrow keys. Also, when you get too close to ++ * diagonals, it has a tendancy to jump back and forth, so lets try to ++ * ignore when they get too close. ++ */ ++ if (ictx->product != 0xffdc) { ++ /* first, pad to 8 bytes so it conforms with everything else */ ++ buf[5] = buf[6] = buf[7] = 0; ++ timeout = 500; /* in msecs */ ++ /* (2*threshold) x (2*threshold) square */ ++ threshold = pad_thresh ? pad_thresh : 28; ++ rel_x = buf[2]; ++ rel_y = buf[3]; ++ ++ if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) { ++ if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) { ++ dir = stabilize((int)rel_x, (int)rel_y, ++ timeout, threshold); ++ if (!dir) { ++ ictx->kc = KEY_UNKNOWN; ++ return; ++ } ++ buf[2] = dir & 0xFF; ++ buf[3] = (dir >> 8) & 0xFF; ++ memcpy(&temp_key, buf, sizeof(temp_key)); ++ remote_key = (u32) (le64_to_cpu(temp_key) ++ & 0xffffffff); ++ ki = imon_remote_key_lookup(remote_key); ++ ictx->kc = ++ imon_remote_key_table[ki % offset].keycode; ++ } ++ } else { ++ if (abs(rel_y) > abs(rel_x)) { ++ buf[2] = (rel_y > 0) ? 0x7F : 0x80; ++ buf[3] = 0; ++ ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; ++ } else { ++ buf[2] = 0; ++ buf[3] = (rel_x > 0) ? 0x7F : 0x80; ++ ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; ++ } ++ } ++ ++ /* ++ * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad ++ * device (15c2:ffdc). The remote generates various codes from ++ * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates ++ * 0x688301b7 and the right one 0x688481b7. All other keys generate ++ * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with ++ * reversed endianess. Extract direction from buffer, rotate endianess, ++ * adjust sign and feed the values into stabilize(). The resulting codes ++ * will be 0x01008000, 0x01007F00, which match the newer devices. ++ */ ++ } else { ++ timeout = 10; /* in msecs */ ++ /* (2*threshold) x (2*threshold) square */ ++ threshold = pad_thresh ? pad_thresh : 15; ++ ++ /* buf[1] is x */ ++ rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | ++ (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; ++ if (buf[0] & 0x02) ++ rel_x |= ~0x10+1; ++ /* buf[2] is y */ ++ rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | ++ (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; ++ if (buf[0] & 0x01) ++ rel_y |= ~0x10+1; ++ ++ buf[0] = 0x01; ++ buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0; ++ ++ if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) { ++ dir = stabilize((int)rel_x, (int)rel_y, ++ timeout, threshold); ++ if (!dir) { ++ ictx->kc = KEY_UNKNOWN; ++ return; ++ } ++ buf[2] = dir & 0xFF; ++ buf[3] = (dir >> 8) & 0xFF; ++ memcpy(&temp_key, buf, sizeof(temp_key)); ++ remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); ++ ki = imon_remote_key_lookup(remote_key); ++ ictx->kc = imon_remote_key_table[ki % offset].keycode; ++ } else { ++ if (abs(rel_y) > abs(rel_x)) { ++ buf[2] = (rel_y > 0) ? 0x7F : 0x80; ++ buf[3] = 0; ++ ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP; ++ } else { ++ buf[2] = 0; ++ buf[3] = (rel_x > 0) ? 0x7F : 0x80; ++ ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT; ++ } ++ } ++ } ++ ++ ictx->ki = ki; ++} ++ ++static int imon_parse_press_type(struct imon_context *ictx, ++ unsigned char *buf, u8 ksrc) ++{ ++ int press_type = 0; ++ ++ /* key release of 0x02XXXXXX key */ ++ if (ictx->ki == -1 && buf[0] == 0x02 && buf[3] == 0x00) ++ ictx->kc = ictx->last_keycode; ++ ++ /* mouse button release on (some) 0xffdc devices */ ++ else if (ictx->ki == -1 && buf[0] == 0x68 && buf[1] == 0x82 && ++ buf[2] == 0x81 && buf[3] == 0xb7) ++ ictx->kc = ictx->last_keycode; ++ ++ /* mouse button release on (some other) 0xffdc devices */ ++ else if (ictx->ki == -1 && buf[0] == 0x01 && buf[1] == 0x00 && ++ buf[2] == 0x81 && buf[3] == 0xb7) ++ ictx->kc = ictx->last_keycode; ++ ++ /* mce-specific button handling */ ++ else if (ksrc == IMON_BUTTON_MCE) { ++ /* initial press */ ++ if (ictx->kc != ictx->last_keycode ++ || buf[2] != ictx->mce_toggle_bit) { ++ ictx->last_keycode = ictx->kc; ++ ictx->mce_toggle_bit = buf[2]; ++ press_type = 1; ++ mod_timer(&ictx->itimer, ++ jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS)); ++ /* repeat */ ++ } else { ++ press_type = 2; ++ mod_timer(&ictx->itimer, ++ jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS)); ++ } ++ ++ /* incoherent or irrelevant data */ ++ } else if (ictx->ki == -1) ++ press_type = -EINVAL; ++ ++ /* key release of 0xXXXXXXb7 key */ ++ else if (ictx->ki >= IMON_KEY_RELEASE_OFFSET) ++ press_type = 0; ++ ++ /* this is a button press */ ++ else ++ press_type = 1; ++ ++ return press_type; ++} ++ ++/** ++ * Process the incoming packet ++ */ ++static void imon_incoming_packet(struct imon_context *ictx, ++ struct urb *urb, int intf) ++{ ++ int len = urb->actual_length; ++ unsigned char *buf = urb->transfer_buffer; ++ struct device *dev = ictx->dev; ++ u16 kc; ++ bool norelease = 0; ++ int i, ki; ++ int offset = IMON_KEY_RELEASE_OFFSET; ++ u64 temp_key; ++ u64 panel_key = 0; ++ u32 remote_key = 0; ++ struct input_dev *idev = NULL; ++ int press_type = 0; ++ int msec; ++ struct timeval t; ++ static struct timeval prev_time = { 0, 0 }; ++ u8 ksrc = IMON_BUTTON_IMON; ++ ++ idev = ictx->idev; ++ ++ /* filter out junk data on the older 0xffdc imon devices */ ++ if ((buf[0] == 0xff) && (buf[7] == 0xff)) ++ return; ++ ++ /* Figure out what key was pressed */ ++ memcpy(&temp_key, buf, sizeof(temp_key)); ++ if (len == 8 && buf[7] == 0xee) { ++ ksrc = IMON_BUTTON_PANEL; ++ panel_key = le64_to_cpu(temp_key); ++ ki = imon_panel_key_lookup(panel_key); ++ if (ki < 0) ++ kc = KEY_UNKNOWN; ++ else ++ kc = imon_panel_key_table[ki].keycode; ++ } else { ++ remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff); ++ if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE) { ++ if (buf[0] == 0x80) ++ ksrc = IMON_BUTTON_MCE; ++ ki = imon_mce_key_lookup(remote_key); ++ if (ki < 0) ++ kc = KEY_UNKNOWN; ++ else ++ kc = imon_mce_key_table[ki].keycode; ++ } else { ++ ki = imon_remote_key_lookup(remote_key); ++ if (ki < 0) ++ kc = KEY_UNKNOWN; ++ else ++ kc = imon_remote_key_table[ki % offset].keycode; ++ } ++ } ++ ++ /* keyboard/mouse mode toggle button */ ++ if (kc == KEY_KEYBOARD && ki < offset) { ++ ictx->last_keycode = kc; ++ if (!nomouse) { ++ ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1; ++ dev_dbg(dev, "toggling to %s mode\n", ++ ictx->pad_mouse ? "mouse" : "keyboard"); ++ return; ++ } else { ++ ictx->pad_mouse = 0; ++ dev_dbg(dev, "mouse mode disabled, passing key value\n"); ++ } ++ } ++ ++ ictx->ki = ki; ++ ictx->kc = kc; ++ ++ /* send touchscreen events through input subsystem if touchpad data */ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 && ++ buf[7] == 0x86) { ++ imon_touch_event(ictx, buf); ++ ++ /* look for mouse events with pad in mouse mode */ ++ } else if (ictx->pad_mouse) { ++ if (imon_mouse_event(ictx, buf, len)) ++ return; ++ } ++ ++ /* Now for some special handling to convert pad input to arrow keys */ ++ if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) || ++ ((len == 8) && (buf[0] & 0x40) && ++ !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) { ++ len = 8; ++ imon_pad_to_keys(ictx, buf); ++ norelease = 1; ++ } ++ ++ if (debug) { ++ printk(KERN_INFO "intf%d decoded packet: ", intf); ++ for (i = 0; i < len; ++i) ++ printk("%02x ", buf[i]); ++ printk("\n"); ++ } ++ ++ press_type = imon_parse_press_type(ictx, buf, ksrc); ++ if (press_type < 0) ++ goto not_input_data; ++ ++ if (ictx->kc == KEY_UNKNOWN) ++ goto unknown_key; ++ ++ /* KEY_MUTE repeats from MCE and knob need to be suppressed */ ++ if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) ++ && (buf[7] == 0xee || ksrc == IMON_BUTTON_MCE)) { ++ do_gettimeofday(&t); ++ msec = tv2int(&t, &prev_time); ++ prev_time = t; ++ if (msec < 200) ++ return; ++ } ++ ++ input_report_key(idev, ictx->kc, press_type); ++ input_sync(idev); ++ ++ /* panel keys and some remote keys don't generate a release */ ++ if (panel_key || norelease) { ++ input_report_key(idev, ictx->kc, 0); ++ input_sync(idev); ++ } ++ ++ ictx->last_keycode = ictx->kc; ++ ++ return; ++ ++unknown_key: ++ dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__, ++ (panel_key ? be64_to_cpu(panel_key) : ++ be32_to_cpu(remote_key))); ++ return; ++ ++not_input_data: ++ if (len != 8) { ++ dev_warn(dev, "imon %s: invalid incoming packet " ++ "size (len = %d, intf%d)\n", __func__, len, intf); ++ return; ++ } ++ ++ /* iMON 2.4G associate frame */ ++ if (buf[0] == 0x00 && ++ buf[2] == 0xFF && /* REFID */ ++ buf[3] == 0xFF && ++ buf[4] == 0xFF && ++ buf[5] == 0xFF && /* iMON 2.4G */ ++ ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */ ++ (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ ++ dev_warn(dev, "%s: remote associated refid=%02X\n", ++ __func__, buf[1]); ++ ictx->ir_isassociating = 0; ++ } ++} ++ ++/** ++ * mce/rc6 keypresses have no distinct release code, use timer ++ */ ++static void imon_mce_timeout(unsigned long data) ++{ ++ struct imon_context *ictx = (struct imon_context *)data; ++ ++ input_report_key(ictx->idev, ictx->last_keycode, 0); ++ input_sync(ictx->idev); ++} ++ ++/** ++ * report touchscreen input ++ */ ++static void imon_touch_display_timeout(unsigned long data) ++{ ++ struct imon_context *ictx = (struct imon_context *)data; ++ ++ if (!ictx->display_type == IMON_DISPLAY_TYPE_VGA) ++ return; ++ ++ input_report_abs(ictx->touch, ABS_X, ictx->touch_x); ++ input_report_abs(ictx->touch, ABS_Y, ictx->touch_y); ++ input_report_key(ictx->touch, BTN_TOUCH, 0x00); ++ input_sync(ictx->touch); ++} ++ ++/** ++ * Callback function for USB core API: receive data ++ */ ++static void usb_rx_callback_intf0(struct urb *urb) ++{ ++ struct imon_context *ictx; ++ unsigned char *buf; ++ int len; ++ int intfnum = 0; ++ ++ if (!urb) ++ return; ++ ++ ictx = (struct imon_context *)urb->context; ++ if (!ictx) ++ return; ++ ++ buf = urb->transfer_buffer; ++ len = urb->actual_length; ++ ++ switch (urb->status) { ++ case -ENOENT: /* usbcore unlink successful! */ ++ return; ++ ++ case -ESHUTDOWN: /* transport endpoint was shut down */ ++ break; ++ ++ case 0: ++ imon_incoming_packet(ictx, urb, intfnum); ++ break; ++ ++ default: ++ dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", ++ __func__, urb->status); ++ break; ++ } ++ ++ usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC); ++} ++ ++static void usb_rx_callback_intf1(struct urb *urb) ++{ ++ struct imon_context *ictx; ++ unsigned char *buf; ++ int len; ++ int intfnum = 1; ++ ++ if (!urb) ++ return; ++ ++ ictx = (struct imon_context *)urb->context; ++ if (!ictx) ++ return; ++ ++ buf = urb->transfer_buffer; ++ len = urb->actual_length; ++ ++ switch (urb->status) { ++ case -ENOENT: /* usbcore unlink successful! */ ++ return; ++ ++ case -ESHUTDOWN: /* transport endpoint was shut down */ ++ break; ++ ++ case 0: ++ imon_incoming_packet(ictx, urb, intfnum); ++ break; ++ ++ default: ++ dev_warn(ictx->dev, "imon %s: status(%d): ignored\n", ++ __func__, urb->status); ++ break; ++ } ++ ++ usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); ++} ++ ++static struct input_dev *imon_init_idev(struct imon_context *ictx) ++{ ++ struct input_dev *idev; ++ int ret, i; ++ ++ idev = input_allocate_device(); ++ if (!idev) { ++ dev_err(ictx->dev, "remote input dev allocation failed\n"); ++ goto idev_alloc_failed; ++ } ++ ++ snprintf(ictx->name_idev, sizeof(ictx->name_idev), ++ "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); ++ idev->name = ictx->name_idev; ++ ++ usb_make_path(ictx->usbdev_intf0, ictx->phys_idev, ++ sizeof(ictx->phys_idev)); ++ strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev)); ++ idev->phys = ictx->phys_idev; ++ ++ idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); ++ ++ idev->keybit[BIT_WORD(BTN_MOUSE)] = ++ BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT); ++ idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) | ++ BIT_MASK(REL_WHEEL); ++ ++ input_set_drvdata(idev, ictx); ++ ++ if (ir_protocol == IMON_IR_PROTOCOL_MCE) ++ ret = sparse_keymap_setup(idev, imon_mce_key_table, NULL); ++ else ++ ret = sparse_keymap_setup(idev, imon_remote_key_table, NULL); ++ if (ret) ++ goto keymap_failed; ++ ++ /* can't use sparse keymap atm, 64-bit keycodes */ ++ for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) { ++ u16 kc = imon_panel_key_table[i].keycode; ++ __set_bit(kc, idev->keybit); ++ } ++ ++ usb_to_input_id(ictx->usbdev_intf0, &idev->id); ++ idev->dev.parent = ictx->dev; ++ ret = input_register_device(idev); ++ if (ret < 0) { ++ dev_err(ictx->dev, "remote input dev register failed\n"); ++ goto idev_register_failed; ++ } ++ ++ return idev; ++ ++idev_register_failed: ++ sparse_keymap_free(idev); ++keymap_failed: ++ input_free_device(idev); ++idev_alloc_failed: ++ ++ return NULL; ++} ++ ++static struct input_dev *imon_init_touch(struct imon_context *ictx) ++{ ++ struct input_dev *touch; ++ int ret; ++ ++ touch = input_allocate_device(); ++ if (!touch) { ++ dev_err(ictx->dev, "touchscreen input dev allocation failed\n"); ++ goto touch_alloc_failed; ++ } ++ ++ snprintf(ictx->name_touch, sizeof(ictx->name_touch), ++ "iMON USB Touchscreen (%04x:%04x)", ++ ictx->vendor, ictx->product); ++ touch->name = ictx->name_touch; ++ ++ usb_make_path(ictx->usbdev_intf1, ictx->phys_touch, ++ sizeof(ictx->phys_touch)); ++ strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch)); ++ touch->phys = ictx->phys_touch; ++ ++ touch->evbit[0] = ++ BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ touch->keybit[BIT_WORD(BTN_TOUCH)] = ++ BIT_MASK(BTN_TOUCH); ++ input_set_abs_params(touch, ABS_X, ++ 0x00, 0xfff, 0, 0); ++ input_set_abs_params(touch, ABS_Y, ++ 0x00, 0xfff, 0, 0); ++ ++ input_set_drvdata(touch, ictx); ++ ++ usb_to_input_id(ictx->usbdev_intf1, &touch->id); ++ touch->dev.parent = ictx->dev; ++ ret = input_register_device(touch); ++ if (ret < 0) { ++ dev_info(ictx->dev, "touchscreen input dev register failed\n"); ++ goto touch_register_failed; ++ } ++ ++ return touch; ++ ++touch_register_failed: ++ input_free_device(ictx->touch); ++ mutex_unlock(&ictx->lock); ++ ++touch_alloc_failed: ++ return NULL; ++} ++ ++static bool imon_find_endpoints(struct imon_context *ictx, ++ struct usb_host_interface *iface_desc) ++{ ++ struct usb_endpoint_descriptor *ep; ++ struct usb_endpoint_descriptor *rx_endpoint = NULL; ++ struct usb_endpoint_descriptor *tx_endpoint = NULL; ++ int ifnum = iface_desc->desc.bInterfaceNumber; ++ int num_endpts = iface_desc->desc.bNumEndpoints; ++ int i, ep_dir, ep_type; ++ bool ir_ep_found = 0; ++ bool display_ep_found = 0; ++ bool tx_control = 0; ++ ++ /* ++ * Scan the endpoint list and set: ++ * first input endpoint = IR endpoint ++ * first output endpoint = display endpoint ++ */ ++ for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) { ++ ep = &iface_desc->endpoint[i].desc; ++ ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; ++ ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ ++ if (!ir_ep_found && ep_dir == USB_DIR_IN && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ ++ rx_endpoint = ep; ++ ir_ep_found = 1; ++ dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__); ++ ++ } else if (!display_ep_found && ep_dir == USB_DIR_OUT && ++ ep_type == USB_ENDPOINT_XFER_INT) { ++ tx_endpoint = ep; ++ display_ep_found = 1; ++ dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__); ++ } ++ } ++ ++ if (ifnum == 0) { ++ ictx->rx_endpoint_intf0 = rx_endpoint; ++ /* ++ * tx is used to send characters to lcd/vfd, associate RF ++ * remotes, set IR protocol, and maybe more... ++ */ ++ ictx->tx_endpoint = tx_endpoint; ++ } else { ++ ictx->rx_endpoint_intf1 = rx_endpoint; ++ } ++ ++ /* ++ * If we didn't find a display endpoint, this is probably one of the ++ * newer iMON devices that use control urb instead of interrupt ++ */ ++ if (!display_ep_found) { ++ tx_control = 1; ++ display_ep_found = 1; ++ dev_dbg(ictx->dev, "%s: device uses control endpoint, not " ++ "interface OUT endpoint\n", __func__); ++ } ++ ++ /* ++ * Some iMON receivers have no display. Unfortunately, it seems ++ * that SoundGraph recycles device IDs between devices both with ++ * and without... :\ ++ */ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) { ++ display_ep_found = 0; ++ dev_dbg(ictx->dev, "%s: device has no display\n", __func__); ++ } ++ ++ /* ++ * iMON Touch devices have a VGA touchscreen, but no "display", as ++ * that refers to e.g. /dev/lcd0 (a character device LCD or VFD). ++ */ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { ++ display_ep_found = 0; ++ dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__); ++ } ++ ++ /* Input endpoint is mandatory */ ++ if (!ir_ep_found) ++ err("%s: no valid input (IR) endpoint found.", __func__); ++ ++ ictx->tx_control = tx_control; ++ ++ if (display_ep_found) ++ ictx->display_supported = 1; ++ ++ return ir_ep_found; ++ ++} ++ ++static struct imon_context *imon_init_intf0(struct usb_interface *intf) ++{ ++ struct imon_context *ictx; ++ struct urb *rx_urb; ++ struct urb *tx_urb; ++ struct device *dev = &intf->dev; ++ struct usb_host_interface *iface_desc; ++ int ret; ++ ++ ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL); ++ if (!ictx) { ++ dev_err(dev, "%s: kzalloc failed for context", __func__); ++ goto exit; ++ } ++ rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!rx_urb) { ++ dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__); ++ goto rx_urb_alloc_failed; ++ } ++ tx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!tx_urb) { ++ dev_err(dev, "%s: usb_alloc_urb failed for display urb", ++ __func__); ++ goto tx_urb_alloc_failed; ++ } ++ ++ mutex_init(&ictx->lock); ++ ++ mutex_lock(&ictx->lock); ++ ++ if (ir_protocol == IMON_IR_PROTOCOL_MCE) { ++ init_timer(&ictx->itimer); ++ ictx->itimer.data = (unsigned long)ictx; ++ ictx->itimer.function = imon_mce_timeout; ++ } ++ ++ ictx->dev = dev; ++ ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf)); ++ ictx->dev_present_intf0 = 1; ++ ictx->rx_urb_intf0 = rx_urb; ++ ictx->tx_urb = tx_urb; ++ ++ ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor); ++ ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct); ++ ++ iface_desc = intf->cur_altsetting; ++ if (!imon_find_endpoints(ictx, iface_desc)) ++ goto find_endpoint_failed; ++ ++ ictx->idev = imon_init_idev(ictx); ++ if (!ictx->idev) { ++ dev_err(dev, "%s: input device setup failed\n", __func__); ++ goto idev_setup_failed; ++ } ++ ++ usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, ++ usb_rcvintpipe(ictx->usbdev_intf0, ++ ictx->rx_endpoint_intf0->bEndpointAddress), ++ ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), ++ usb_rx_callback_intf0, ictx, ++ ictx->rx_endpoint_intf0->bInterval); ++ ++ ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL); ++ if (ret) { ++ err("%s: usb_submit_urb failed for intf0 (%d)", ++ __func__, ret); ++ goto urb_submit_failed; ++ } ++ ++ return ictx; ++ ++urb_submit_failed: ++ sparse_keymap_free(ictx->idev); ++ input_unregister_device(ictx->idev); ++ input_free_device(ictx->idev); ++idev_setup_failed: ++find_endpoint_failed: ++ mutex_unlock(&ictx->lock); ++ usb_free_urb(tx_urb); ++tx_urb_alloc_failed: ++ usb_free_urb(rx_urb); ++rx_urb_alloc_failed: ++ kfree(ictx); ++exit: ++ dev_err(dev, "unable to initialize intf0, err %d\n", ret); ++ ++ return NULL; ++} ++ ++static struct imon_context *imon_init_intf1(struct usb_interface *intf, ++ struct imon_context *ictx) ++{ ++ struct urb *rx_urb; ++ struct usb_host_interface *iface_desc; ++ int ret; ++ ++ rx_urb = usb_alloc_urb(0, GFP_KERNEL); ++ if (!rx_urb) { ++ err("%s: usb_alloc_urb failed for IR urb", __func__); ++ ret = -ENOMEM; ++ goto rx_urb_alloc_failed; ++ } ++ ++ mutex_lock(&ictx->lock); ++ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { ++ init_timer(&ictx->ttimer); ++ ictx->ttimer.data = (unsigned long)ictx; ++ ictx->ttimer.function = imon_touch_display_timeout; ++ } ++ ++ ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf)); ++ ictx->dev_present_intf1 = 1; ++ ictx->rx_urb_intf1 = rx_urb; ++ ++ iface_desc = intf->cur_altsetting; ++ if (!imon_find_endpoints(ictx, iface_desc)) ++ goto find_endpoint_failed; ++ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) { ++ ictx->touch = imon_init_touch(ictx); ++ if (!ictx->touch) ++ goto touch_setup_failed; ++ } else ++ ictx->touch = NULL; ++ ++ usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1, ++ usb_rcvintpipe(ictx->usbdev_intf1, ++ ictx->rx_endpoint_intf1->bEndpointAddress), ++ ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), ++ usb_rx_callback_intf1, ictx, ++ ictx->rx_endpoint_intf1->bInterval); ++ ++ ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL); ++ ++ if (ret) { ++ err("%s: usb_submit_urb failed for intf1 (%d)", ++ __func__, ret); ++ goto urb_submit_failed; ++ } ++ ++ return ictx; ++ ++urb_submit_failed: ++ if (ictx->touch) { ++ input_unregister_device(ictx->touch); ++ input_free_device(ictx->touch); ++ } ++touch_setup_failed: ++find_endpoint_failed: ++ mutex_unlock(&ictx->lock); ++ usb_free_urb(rx_urb); ++rx_urb_alloc_failed: ++ dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret); ++ ++ return NULL; ++} ++ ++static void imon_set_display_type(struct imon_context *ictx, ++ struct usb_interface *intf) ++{ ++ int configured_display_type = IMON_DISPLAY_TYPE_VFD; ++ ++ /* ++ * Try to auto-detect the type of display if the user hasn't set ++ * it by hand via the display_type modparam. Default is VFD. ++ */ ++ if (display_type == IMON_DISPLAY_TYPE_AUTO) { ++ if (usb_match_id(intf, lcd_device_list)) ++ configured_display_type = IMON_DISPLAY_TYPE_LCD; ++ else if (usb_match_id(intf, imon_touchscreen_list)) ++ configured_display_type = IMON_DISPLAY_TYPE_VGA; ++ else if (usb_match_id(intf, ir_only_list)) ++ configured_display_type = IMON_DISPLAY_TYPE_NONE; ++ else ++ configured_display_type = IMON_DISPLAY_TYPE_VFD; ++ } else { ++ configured_display_type = display_type; ++ dev_dbg(ictx->dev, "%s: overriding display type to %d via " ++ "modparam\n", __func__, display_type); ++ } ++ ++ ictx->display_type = configured_display_type; ++} ++ ++static void imon_init_display(struct imon_context *ictx, ++ struct usb_interface *intf) ++{ ++ int ret; ++ const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x88 }; ++ ++ dev_dbg(ictx->dev, "Registering iMON display with sysfs\n"); ++ ++ /* set up sysfs entry for built-in clock */ ++ ret = sysfs_create_group(&intf->dev.kobj, ++ &imon_display_attribute_group); ++ if (ret) ++ dev_err(ictx->dev, "Could not create display sysfs " ++ "entries(%d)", ret); ++ ++ if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) ++ ret = usb_register_dev(intf, &imon_lcd_class); ++ else ++ ret = usb_register_dev(intf, &imon_vfd_class); ++ if (ret) ++ /* Not a fatal error, so ignore */ ++ dev_info(ictx->dev, "could not get a minor number for " ++ "display\n"); ++ ++ /* Enable front-panel buttons and/or knobs */ ++ memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet)); ++ ret = send_packet(ictx); ++ /* Not fatal, but warn about it */ ++ if (ret) ++ dev_info(ictx->dev, "failed to enable front-panel " ++ "buttons and/or knobs\n"); ++} ++ ++/** ++ * Callback function for USB core API: Probe ++ */ ++static int __devinit imon_probe(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ struct usb_device *usbdev = NULL; ++ struct usb_host_interface *iface_desc = NULL; ++ struct usb_interface *first_if; ++ struct device *dev = &interface->dev; ++ int ifnum, code_length, sysfs_err; ++ int ret = 0; ++ struct imon_context *ictx = NULL; ++ struct imon_context *first_if_ctx = NULL; ++ u16 vendor, product; ++ ++ code_length = BUF_CHUNK_SIZE * 8; ++ ++ usbdev = usb_get_dev(interface_to_usbdev(interface)); ++ iface_desc = interface->cur_altsetting; ++ ifnum = iface_desc->desc.bInterfaceNumber; ++ vendor = le16_to_cpu(usbdev->descriptor.idVendor); ++ product = le16_to_cpu(usbdev->descriptor.idProduct); ++ ++ dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n", ++ __func__, vendor, product, ifnum); ++ ++ /* prevent races probing devices w/multiple interfaces */ ++ mutex_lock(&driver_lock); ++ ++ first_if = usb_ifnum_to_if(usbdev, 0); ++ first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if); ++ ++ ++ if (ifnum == 0) { ++ ictx = imon_init_intf0(interface); ++ if (!ictx) { ++ err("%s: failed to initialize context!\n", __func__); ++ ret = -ENODEV; ++ goto fail; ++ } ++ ++ imon_set_display_type(ictx, interface); ++ ++ if (ictx->display_supported) ++ imon_init_display(ictx, interface); ++ ++ if (product == 0xffdc) { ++ /* RF products *also* use 0xffdc... sigh... */ ++ sysfs_err = sysfs_create_group(&interface->dev.kobj, ++ &imon_rf_attribute_group); ++ if (sysfs_err) ++ err("%s: Could not create RF sysfs entries(%d)", ++ __func__, sysfs_err); ++ } ++ ++ } else { ++ /* this is the secondary interface on the device */ ++ ictx = imon_init_intf1(interface, first_if_ctx); ++ if (!ictx) { ++ err("%s: failed to attach to context!\n", __func__); ++ ret = -ENODEV; ++ goto fail; ++ } ++ ++ } ++ ++ usb_set_intfdata(interface, ictx); ++ ++ /* set IR protocol/remote type */ ++ imon_set_ir_protocol(ictx); ++ ++ dev_info(dev, "iMON device (%04x:%04x, intf%d) on " ++ "usb<%d:%d> initialized\n", vendor, product, ifnum, ++ usbdev->bus->busnum, usbdev->devnum); ++ ++ mutex_unlock(&ictx->lock); ++ mutex_unlock(&driver_lock); ++ ++ return 0; ++ ++fail: ++ mutex_unlock(&driver_lock); ++ dev_err(dev, "unable to register, err %d\n", ret); ++ ++ return ret; ++} ++ ++/** ++ * Callback function for USB core API: disconnect ++ */ ++static void __devexit imon_disconnect(struct usb_interface *interface) ++{ ++ struct imon_context *ictx; ++ struct device *dev; ++ int ifnum; ++ ++ /* prevent races with multi-interface device probing and display_open */ ++ mutex_lock(&driver_lock); ++ ++ ictx = usb_get_intfdata(interface); ++ dev = ictx->dev; ++ ifnum = interface->cur_altsetting->desc.bInterfaceNumber; ++ ++ mutex_lock(&ictx->lock); ++ ++ /* ++ * sysfs_remove_group is safe to call even if sysfs_create_group ++ * hasn't been called ++ */ ++ sysfs_remove_group(&interface->dev.kobj, ++ &imon_display_attribute_group); ++ sysfs_remove_group(&interface->dev.kobj, ++ &imon_rf_attribute_group); ++ ++ usb_set_intfdata(interface, NULL); ++ ++ /* Abort ongoing write */ ++ if (ictx->tx.busy) { ++ usb_kill_urb(ictx->tx_urb); ++ complete_all(&ictx->tx.finished); ++ } ++ ++ if (ifnum == 0) { ++ ictx->dev_present_intf0 = 0; ++ usb_kill_urb(ictx->rx_urb_intf0); ++ sparse_keymap_free(ictx->idev); ++ input_unregister_device(ictx->idev); ++ if (ictx->display_supported) { ++ if (ictx->display_type == IMON_DISPLAY_TYPE_LCD) ++ usb_deregister_dev(interface, &imon_lcd_class); ++ else ++ usb_deregister_dev(interface, &imon_vfd_class); ++ } ++ } else { ++ ictx->dev_present_intf1 = 0; ++ usb_kill_urb(ictx->rx_urb_intf1); ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) ++ input_unregister_device(ictx->touch); ++ } ++ ++ if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) { ++ if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) ++ del_timer_sync(&ictx->ttimer); ++ mutex_unlock(&ictx->lock); ++ if (!ictx->display_isopen) ++ free_imon_context(ictx); ++ } else { ++ if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE) ++ del_timer_sync(&ictx->itimer); ++ mutex_unlock(&ictx->lock); ++ } ++ ++ mutex_unlock(&driver_lock); ++ ++ dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n", ++ __func__, ifnum); ++} ++ ++static int imon_suspend(struct usb_interface *intf, pm_message_t message) ++{ ++ struct imon_context *ictx = usb_get_intfdata(intf); ++ int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; ++ ++ if (ifnum == 0) ++ usb_kill_urb(ictx->rx_urb_intf0); ++ else ++ usb_kill_urb(ictx->rx_urb_intf1); ++ ++ return 0; ++} ++ ++static int imon_resume(struct usb_interface *intf) ++{ ++ int rc = 0; ++ struct imon_context *ictx = usb_get_intfdata(intf); ++ int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; ++ ++ if (ifnum == 0) { ++ usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0, ++ usb_rcvintpipe(ictx->usbdev_intf0, ++ ictx->rx_endpoint_intf0->bEndpointAddress), ++ ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), ++ usb_rx_callback_intf0, ictx, ++ ictx->rx_endpoint_intf0->bInterval); ++ ++ rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC); ++ ++ } else { ++ usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1, ++ usb_rcvintpipe(ictx->usbdev_intf1, ++ ictx->rx_endpoint_intf1->bEndpointAddress), ++ ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf), ++ usb_rx_callback_intf1, ictx, ++ ictx->rx_endpoint_intf1->bInterval); ++ ++ rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC); ++ } ++ ++ return rc; ++} ++ ++static int __init imon_init(void) ++{ ++ int rc; ++ ++ rc = usb_register(&imon_driver); ++ if (rc) { ++ err("%s: usb register failed(%d)", __func__, rc); ++ rc = -ENODEV; ++ } ++ ++ return rc; ++} ++ ++static void __exit imon_exit(void) ++{ ++ usb_deregister(&imon_driver); ++} ++ ++module_init(imon_init); ++module_exit(imon_exit); +diff -Naur linux-2.6.35-rc6/drivers/input/misc/Kconfig linux-2.6.35-rc6.patch/drivers/input/misc/Kconfig +--- linux-2.6.35-rc6/drivers/input/misc/Kconfig 2010-07-22 21:13:38.000000000 +0200 ++++ linux-2.6.35-rc6.patch/drivers/input/misc/Kconfig 2010-08-02 09:28:03.994931619 +0200 +@@ -390,4 +390,16 @@ + To compile this driver as a module, choose M here: the + module will be called pcap_keys. + ++config INPUT_IMON ++ tristate "SoundGraph iMON Receiver and Display" ++ depends on USB_ARCH_HAS_HCD ++ select USB ++ select INPUT_SPARSEKMAP ++ help ++ Say Y here if you want to use a SoundGraph iMON (aka Antec Veris) ++ IR Receiver and/or LCD/VFD/VGA display. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called imon. ++ + endif +diff -Naur linux-2.6.35-rc6/drivers/input/misc/Kconfig.orig linux-2.6.35-rc6.patch/drivers/input/misc/Kconfig.orig +diff -Naur linux-2.6.35-rc6/drivers/input/misc/Makefile linux-2.6.35-rc6.patch/drivers/input/misc/Makefile +--- linux-2.6.35-rc6/drivers/input/misc/Makefile 2010-07-22 21:13:38.000000000 +0200 ++++ linux-2.6.35-rc6.patch/drivers/input/misc/Makefile 2010-08-02 09:28:03.995933276 +0200 +@@ -17,6 +17,7 @@ + obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o + obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o + obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o ++obj-$(CONFIG_INPUT_IMON) += imon.o + obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o + obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o + obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o +diff -Naur linux-2.6.35-rc6/drivers/input/misc/Makefile.orig linux-2.6.35-rc6.patch/drivers/input/misc/Makefile.orig +diff -Naur linux-2.6.35-rc6/include/linux/lirc.h linux-2.6.35-rc6.patch/include/linux/lirc.h +--- linux-2.6.35-rc6/include/linux/lirc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.35-rc6.patch/include/linux/lirc.h 2010-08-02 09:28:03.996942057 +0200 +@@ -0,0 +1,159 @@ ++/* ++ * lirc.h - linux infrared remote control header file ++ * last modified 2007/09/27 ++ */ ++ ++#ifndef _LINUX_LIRC_H ++#define _LINUX_LIRC_H ++ ++#include ++#include ++ ++/* */ ++#define PULSE_BIT 0x01000000 ++#define PULSE_MASK 0x00FFFFFF ++/* */ ++ ++#define LIRC_MODE2_SPACE 0x00000000 ++#define LIRC_MODE2_PULSE 0x01000000 ++#define LIRC_MODE2_FREQUENCY 0x02000000 ++#define LIRC_MODE2_TIMEOUT 0x03000000 ++ ++#define LIRC_VALUE_MASK 0x00FFFFFF ++#define LIRC_MODE2_MASK 0xFF000000 ++ ++#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) ++#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) ++#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) ++#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) ++ ++#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) ++#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) ++ ++#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) ++#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) ++#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) ++#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) ++ ++/*** lirc compatible hardware features ***/ ++ ++#define LIRC_MODE2SEND(x) (x) ++#define LIRC_SEND2MODE(x) (x) ++#define LIRC_MODE2REC(x) ((x) << 16) ++#define LIRC_REC2MODE(x) ((x) >> 16) ++ ++#define LIRC_MODE_RAW 0x00000001 ++#define LIRC_MODE_PULSE 0x00000002 ++#define LIRC_MODE_MODE2 0x00000004 ++#define LIRC_MODE_LIRCCODE 0x00000010 ++ ++ ++#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) ++#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) ++#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) ++#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) ++ ++#define LIRC_CAN_SEND_MASK 0x0000003f ++ ++#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 ++#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 ++#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 ++ ++#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) ++#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) ++#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) ++#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) ++ ++#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) ++ ++#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) ++#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) ++ ++#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 ++#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 ++#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 ++#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 ++#define LIRC_CAN_SET_REC_FILTER 0x08000000 ++ ++#define LIRC_CAN_MEASURE_CARRIER 0x02000000 ++ ++#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) ++#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) ++ ++#define LIRC_CAN_NOTIFY_DECODE 0x01000000 ++ ++/*** IOCTL commands for lirc driver ***/ ++ ++#define LIRC_GET_FEATURES _IOR('i', 0x00000000, unsigned long) ++ ++#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, unsigned long) ++#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, unsigned long) ++#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, unsigned int) ++#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, unsigned int) ++#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, unsigned int) ++#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, unsigned int) ++#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, unsigned int) ++ ++#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, uint32_t) ++#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, uint32_t) ++ ++#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, uint32_t) ++#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, uint32_t) ++#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, uint32_t) ++#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, uint32_t) ++ ++/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ ++#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, unsigned long) ++ ++#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, unsigned long) ++#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, unsigned long) ++/* Note: these can reset the according pulse_width */ ++#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, unsigned int) ++#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, unsigned int) ++#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, unsigned int) ++#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, unsigned int) ++#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, unsigned int) ++ ++/* ++ * when a timeout != 0 is set the driver will send a ++ * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is ++ * never sent, timeout is disabled by default ++ */ ++#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, uint32_t) ++ ++/* ++ * pulses shorter than this are filtered out by hardware (software ++ * emulation in lirc_dev?) ++ */ ++#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x00000019, uint32_t) ++/* ++ * spaces shorter than this are filtered out by hardware (software ++ * emulation in lirc_dev?) ++ */ ++#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001a, uint32_t) ++/* ++ * if filter cannot be set independantly for pulse/space, this should ++ * be used ++ */ ++#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001b, uint32_t) ++ ++/* ++ * to set a range use ++ * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the ++ * lower bound first and later ++ * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound ++ */ ++ ++#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, unsigned int) ++#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, unsigned int) ++ ++#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) ++ ++/* ++ * from the next key press on the driver will send ++ * LIRC_MODE2_FREQUENCY packets ++ */ ++#define LIRC_MEASURE_CARRIER_ENABLE _IO('i', 0x00000021) ++#define LIRC_MEASURE_CARRIER_DISABLE _IO('i', 0x00000022) ++ ++#endif diff --git a/packages/linux/patches/linux-2.6.35-ti.980.1r14-321-linux_fix_SMC_instructions.patch b/packages/linux/patches/linux-2.6.35-ti.980.1r14-321-linux_fix_SMC_instructions.patch new file mode 100644 index 0000000000..69b1de8ad4 --- /dev/null +++ b/packages/linux/patches/linux-2.6.35-ti.980.1r14-321-linux_fix_SMC_instructions.patch @@ -0,0 +1,22 @@ +diff -Naur linux-2.6.35-980.1release14/arch/arm/mach-omap2/Makefile linux-2.6.35-980.1release14a/arch/arm/mach-omap2/Makefile +--- linux-2.6.35-980.1release14/arch/arm/mach-omap2/Makefile 2011-01-19 11:27:25.000000000 +0100 ++++ linux-2.6.35-980.1release14a/arch/arm/mach-omap2/Makefile 2011-02-27 17:50:38.370778859 +0100 +@@ -29,7 +29,9 @@ + obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o \ + omap4-wakeupgen.o + +-AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a ++plus_sec := $(call as-instr,.arch_extension sec,+sec) ++AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) ++AFLAGS_omap-headsmp.o :=-Wa,-march=armv7-a$(plus_sec) + + # Functions loaded to SRAM + obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o +@@ -63,6 +65,7 @@ + + AFLAGS_sleep24xx.o :=-Wa,-march=armv6 + AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a ++AFLAGS_sleep44xx.o :=-Wa,-march=armv7-a$(plus_sec) + + ifeq ($(CONFIG_PM_VERBOSE),y) + CFLAGS_pm_bus.o += -DDEBUG diff --git a/packages/linux/patches/linux-2.6.38-000_crosscompile.patch b/packages/linux/patches/linux-2.6.38-000_crosscompile.patch new file mode 100644 index 0000000000..b4fc575828 --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-000_crosscompile.patch @@ -0,0 +1,22 @@ +--- linux-2.6.24-rc2.orig/arch/x86/boot/tools/build.c 2007-10-06 12:26:14.000000000 +0200 ++++ linux-2.6.24-rc2/arch/x86/boot/tools/build.c 2007-10-06 12:27:36.000000000 +0200 +@@ -29,7 +29,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -42,6 +41,11 @@ + #define DEFAULT_MAJOR_ROOT 0 + #define DEFAULT_MINOR_ROOT 0 + ++#undef major ++#define major(dev) ((int)(((dev) >> 8) & 0xff)) ++#undef minor ++#define minor(dev) ((int)((dev) & 0xff)) ++ + /* Minimal number of setup sectors */ + #define SETUP_SECT_MIN 5 + #define SETUP_SECT_MAX 64 diff --git a/packages/linux/patches/linux-2.6.38-002_bash_only_feature.patch b/packages/linux/patches/linux-2.6.38-002_bash_only_feature.patch new file mode 100644 index 0000000000..a1028d15aa --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-002_bash_only_feature.patch @@ -0,0 +1,15 @@ +Index: linux-2.6.16/scripts/gen_initramfs_list.sh +=================================================================== +--- linux-2.6.16.orig/scripts/gen_initramfs_list.sh 2006-03-20 18:41:34.000000000 +0100 ++++ linux-2.6.16/scripts/gen_initramfs_list.sh 2006-03-20 18:42:40.000000000 +0100 +@@ -56,9 +56,7 @@ + + parse() { + local location="$1" +- local name="${location/${srcdir}//}" +- # change '//' into '/' +- name="${name//\/\///}" ++ local name="$(echo "$location" | sed -e 's%$srcdir%%' -e 's%//*%/%g')" + local mode="$2" + local uid="$3" + local gid="$4" diff --git a/packages/linux/patches/linux-2.6.38-003-no_dev_console.patch b/packages/linux/patches/linux-2.6.38-003-no_dev_console.patch new file mode 100644 index 0000000000..9b5e51437d --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-003-no_dev_console.patch @@ -0,0 +1,20 @@ +diff -Naur linux-2.6.34-rc7/init/main.c linux-2.6.34-rc7.patch/init/main.c +--- linux-2.6.34-rc7/init/main.c 2010-05-10 03:36:28.000000000 +0200 ++++ linux-2.6.34-rc7.patch/init/main.c 2010-05-15 12:28:34.767241760 +0200 +@@ -886,8 +886,14 @@ + do_basic_setup(); + + /* Open the /dev/console on the rootfs, this should never fail */ +- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) +- printk(KERN_WARNING "Warning: unable to open an initial console.\n"); ++ char *console = "/dev_console"; ++ ++ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) { ++ sys_mknod(console, S_IFCHR|0600, (TTYAUX_MAJOR<<8)|1); ++ if (sys_open(console, O_RDWR, 0) < 0) ++ printk(KERN_WARNING "Warning: unable to open an initial console.\n"); ++ sys_unlink(console); ++ } + + (void) sys_dup(0); + (void) sys_dup(0); diff --git a/packages/linux/patches/linux-2.6.38-004_lower_undefined_mode_timeout.patch b/packages/linux/patches/linux-2.6.38-004_lower_undefined_mode_timeout.patch new file mode 100644 index 0000000000..a0aca61d23 --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-004_lower_undefined_mode_timeout.patch @@ -0,0 +1,24 @@ +diff -Naur linux-2.6.23-rc9.orig/arch/i386/boot/tty.c linux-2.6.23-rc9/arch/i386/boot/tty.c +--- linux-2.6.23-rc9.orig/arch/x86/boot/tty.c 2007-10-06 12:26:14.000000000 +0200 ++++ linux-2.6.23-rc9/arch/x86/boot/tty.c 2007-10-06 12:37:47.000000000 +0200 +@@ -92,7 +92,7 @@ + + int getchar_timeout(void) + { +- int cnt = 30; ++ int cnt = 3; + int t0, t1; + + t0 = gettime(); +diff -Naur linux-2.6.23-rc9.orig/arch/i386/boot/video.c linux-2.6.23-rc9/arch/i386/boot/video.c +--- linux-2.6.23-rc9.orig/arch/x86/boot/video.c 2007-10-06 12:26:14.000000000 +0200 ++++ linux-2.6.23-rc9/arch/x86/boot/video.c 2007-10-06 12:36:05.000000000 +0200 +@@ -329,7 +329,7 @@ + unsigned int sel; + + puts("Press to see video modes available, " +- " to continue, or wait 30 sec\n"); ++ " to continue, or wait 3 sec\n"); + + kbd_flush(); + while (1) { diff --git a/packages/linux/patches/linux-2.6.38-005_kconfig_no_timestamp.patch b/packages/linux/patches/linux-2.6.38-005_kconfig_no_timestamp.patch new file mode 100644 index 0000000000..332e553831 --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-005_kconfig_no_timestamp.patch @@ -0,0 +1,13 @@ +Index: linux-2.6.16/scripts/kconfig/confdata.c +=================================================================== +--- linux-2.6.16.orig/scripts/kconfig/confdata.c 2006-03-20 06:53:29.000000000 +0100 ++++ linux-2.6.16/scripts/kconfig/confdata.c 2006-03-20 18:47:06.000000000 +0100 +@@ -340,7 +340,7 @@ + int type, l; + const char *str; + time_t now; +- int use_timestamp = 1; ++ int use_timestamp = 0; + char *env; + + dirname[0] = 0; diff --git a/packages/linux/patches/linux-2.6.38-006_enable_utf8.patch b/packages/linux/patches/linux-2.6.38-006_enable_utf8.patch new file mode 100644 index 0000000000..bee1cf3da8 --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-006_enable_utf8.patch @@ -0,0 +1,25 @@ +diff -Naur linux-2.6.31-rc4.orig/fs/fat/inode.c linux-2.6.31-rc4/fs/fat/inode.c +--- linux-2.6.31-rc4.orig/fs/fat/inode.c 2009-07-25 12:47:41.000000000 +0200 ++++ linux-2.6.31-rc4/fs/fat/inode.c 2009-07-25 13:38:18.000000000 +0200 +@@ -979,7 +979,8 @@ + } + opts->name_check = 'n'; + opts->quiet = opts->showexec = opts->sys_immutable = opts->dotsOK = 0; +- opts->utf8 = opts->unicode_xlate = 0; ++ opts->utf8 = 1; ++ opts->unicode_xlate = 0; + opts->numtail = 1; + opts->usefree = opts->nocase = 0; + opts->tz_utc = 0; +diff -Naur linux-2.6.31-rc4.orig/fs/isofs/inode.c linux-2.6.31-rc4/fs/isofs/inode.c +--- linux-2.6.31-rc4.orig/fs/isofs/inode.c 2009-07-25 12:47:41.000000000 +0200 ++++ linux-2.6.31-rc4/fs/isofs/inode.c 2009-07-25 13:38:49.000000000 +0200 +@@ -377,7 +377,7 @@ + popt->gid = 0; + popt->uid = 0; + popt->iocharset = NULL; +- popt->utf8 = 0; ++ popt->utf8 = 1; + popt->overriderockperm = 0; + popt->session=-1; + popt->sbsector=-1; diff --git a/packages/linux/patches/linux-2.6.38-007_die_floppy_die.patch b/packages/linux/patches/linux-2.6.38-007_die_floppy_die.patch new file mode 100644 index 0000000000..76db312182 --- /dev/null +++ b/packages/linux/patches/linux-2.6.38-007_die_floppy_die.patch @@ -0,0 +1,30 @@ +From 4ff58b642f80dedb20533978123d89b5ac9b1ed5 Mon Sep 17 00:00:00 2001 +From: Kyle McMartin +Date: Tue, 30 Mar 2010 00:04:29 -0400 +Subject: die-floppy-die + +Kill the floppy.ko pnp modalias. We were surviving just fine without +autoloading floppy drivers, tyvm. + +Please feel free to register all complaints in the wastepaper bin. +--- + drivers/block/floppy.c | 3 +-- + 1 files changed, 1 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 90c4038..f4a0b90 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -4619,8 +4619,7 @@ static const struct pnp_device_id floppy_pnpids[] = { + {"PNP0700", 0}, + {} + }; +- +-MODULE_DEVICE_TABLE(pnp, floppy_pnpids); ++/* MODULE_DEVICE_TABLE(pnp, floppy_pnpids); */ + + #else + +-- +1.7.0.1 + diff --git a/packages/linux/patches/linux-2.6.38-rc8-008-hda_intel_prealloc_4mb_dmabuffer.patch b/packages/linux/patches/linux-2.6.38-008-hda_intel_prealloc_4mb_dmabuffer.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-008-hda_intel_prealloc_4mb_dmabuffer.patch rename to packages/linux/patches/linux-2.6.38-008-hda_intel_prealloc_4mb_dmabuffer.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-009_disable_i8042_check_on_apple_mac.patch b/packages/linux/patches/linux-2.6.38-009_disable_i8042_check_on_apple_mac.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-009_disable_i8042_check_on_apple_mac.patch rename to packages/linux/patches/linux-2.6.38-009_disable_i8042_check_on_apple_mac.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-050_add_appleir_usb_driver.patch b/packages/linux/patches/linux-2.6.38-050_add_appleir_usb_driver.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-050_add_appleir_usb_driver.patch rename to packages/linux/patches/linux-2.6.38-050_add_appleir_usb_driver.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-051_add_ite-cir_driver-0.1.patch b/packages/linux/patches/linux-2.6.38-051_add_ite-cir_driver-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-051_add_ite-cir_driver-0.1.patch rename to packages/linux/patches/linux-2.6.38-051_add_ite-cir_driver-0.1.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-052-aureal_remote_quirk-0.1.patch b/packages/linux/patches/linux-2.6.38-052-aureal_remote_quirk-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-052-aureal_remote_quirk-0.1.patch rename to packages/linux/patches/linux-2.6.38-052-aureal_remote_quirk-0.1.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-053_ati-remote_all_keys_and_keychange-0.1.patch b/packages/linux/patches/linux-2.6.38-053_ati-remote_all_keys_and_keychange-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-053_ati-remote_all_keys_and_keychange-0.1.patch rename to packages/linux/patches/linux-2.6.38-053_ati-remote_all_keys_and_keychange-0.1.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch b/packages/linux/patches/linux-2.6.38-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch rename to packages/linux/patches/linux-2.6.38-062-Pioneer_DVR-216D_failed_xfermode-0.1.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-110-drm_nouveau_upstream-20110312.patch b/packages/linux/patches/linux-2.6.38-110-drm_nouveau_upstream-20110312.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-110-drm_nouveau_upstream-20110312.patch rename to packages/linux/patches/linux-2.6.38-110-drm_nouveau_upstream-20110312.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-716_mm-zero_swappiness.patch b/packages/linux/patches/linux-2.6.38-716_mm-zero_swappiness.patch similarity index 100% rename from packages/linux/patches/linux-2.6.38-rc8-716_mm-zero_swappiness.patch rename to packages/linux/patches/linux-2.6.38-716_mm-zero_swappiness.patch diff --git a/packages/linux/patches/linux-2.6.38-rc8-054_fix_nuvoton_wakeup-0.1.patch b/packages/linux/patches/linux-2.6.38-rc8-054_fix_nuvoton_wakeup-0.1.patch deleted file mode 100644 index 32e2eb545f..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-054_fix_nuvoton_wakeup-0.1.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur linux-2.6.38-rc6/drivers/media/rc/nuvoton-cir.h linux-2.6.38-rc6.patch/drivers/media/rc/nuvoton-cir.h ---- linux-2.6.38-rc6/drivers/media/rc/nuvoton-cir.h 2011-02-22 02:25:52.000000000 +0100 -+++ linux-2.6.38-rc6.patch/drivers/media/rc/nuvoton-cir.h 2011-02-28 14:26:20.385871213 +0100 -@@ -306,7 +306,7 @@ - #define CIR_WAKE_IRFIFOSTS_RX_FULL 0x10 - - /* CIR Wake FIFO buffer is 67 bytes long */ --#define CIR_WAKE_FIFO_LEN 67 -+#define CIR_WAKE_FIFO_LEN 65 - /* CIR Wake byte comparison tolerance */ - #define CIR_WAKE_CMP_TOLERANCE 5 - diff --git a/packages/linux/patches/linux-2.6.38-rc8-300-linux_omap_dss2_20110309.patch b/packages/linux/patches/linux-2.6.38-rc8-300-linux_omap_dss2_20110309.patch deleted file mode 100644 index 6ccc3f801e..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-300-linux_omap_dss2_20110309.patch +++ /dev/null @@ -1,29939 +0,0 @@ -diff -Naur linux-2.6.38-rc7/arch/arm/configs/omap2plus_defconfig linux-2.6.38-rc7-linux-omap-dss2/arch/arm/configs/omap2plus_defconfig ---- linux-2.6.38-rc7/arch/arm/configs/omap2plus_defconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/configs/omap2plus_defconfig 2011-03-09 13:19:09.493514052 +0100 -@@ -58,6 +58,7 @@ - CONFIG_NO_HZ=y - CONFIG_HIGH_RES_TIMERS=y - CONFIG_SMP=y -+CONFIG_NR_CPUS=2 - # CONFIG_LOCAL_TIMERS is not set - CONFIG_AEABI=y - CONFIG_LEDS=y -@@ -192,6 +193,17 @@ - CONFIG_FB_MODE_HELPERS=y - CONFIG_FB_TILEBLITTING=y - CONFIG_FB_OMAP_LCD_VGA=y -+CONFIG_OMAP2_DSS=m -+CONFIG_OMAP2_DSS_RFBI=y -+CONFIG_OMAP2_DSS_SDI=y -+CONFIG_OMAP2_DSS_DSI=y -+CONFIG_FB_OMAP2=m -+CONFIG_PANEL_GENERIC_DPI=m -+CONFIG_PANEL_SHARP_LS037V7DW01=m -+CONFIG_PANEL_NEC_NL8048HL11_01B=m -+CONFIG_PANEL_TAAL=m -+CONFIG_PANEL_TPO_TD043MTEA1=m -+CONFIG_PANEL_ACX565AKM=m - CONFIG_BACKLIGHT_LCD_SUPPORT=y - CONFIG_LCD_CLASS_DEVICE=y - CONFIG_LCD_PLATFORM=y -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-ams-delta.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-ams-delta.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-ams-delta.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-ams-delta.c 2011-03-09 13:19:09.778508271 +0100 -@@ -165,7 +165,7 @@ - } - }; - --static struct omap_lcd_config ams_delta_lcd_config __initdata = { -+static struct omap_lcd_config ams_delta_lcd_config = { - .ctrl_name = "internal", - }; - -@@ -175,7 +175,7 @@ - .pins[0] = 2, - }; - --static struct omap_board_config_kernel ams_delta_config[] = { -+static struct omap_board_config_kernel ams_delta_config[] __initdata = { - { OMAP_TAG_LCD, &ams_delta_lcd_config }, - }; - -@@ -208,14 +208,14 @@ - .keymap_size = ARRAY_SIZE(ams_delta_keymap), - }; - --static struct omap_kp_platform_data ams_delta_kp_data = { -+static struct omap_kp_platform_data ams_delta_kp_data __initdata = { - .rows = 8, - .cols = 8, - .keymap_data = &ams_delta_keymap_data, - .delay = 9, - }; - --static struct platform_device ams_delta_kp_device = { -+static struct platform_device ams_delta_kp_device __initdata = { - .name = "omap-keypad", - .id = -1, - .dev = { -@@ -225,12 +225,12 @@ - .resource = ams_delta_kp_resources, - }; - --static struct platform_device ams_delta_lcd_device = { -+static struct platform_device ams_delta_lcd_device __initdata = { - .name = "lcd_ams_delta", - .id = -1, - }; - --static struct platform_device ams_delta_led_device = { -+static struct platform_device ams_delta_led_device __initdata = { - .name = "ams-delta-led", - .id = -1 - }; -@@ -259,7 +259,7 @@ - #define ams_delta_camera_power NULL - #endif - --static struct soc_camera_link __initdata ams_delta_iclink = { -+static struct soc_camera_link ams_delta_iclink = { - .bus_id = 0, /* OMAP1 SoC camera bus */ - .i2c_adapter_id = 1, - .board_info = &ams_delta_camera_board_info[0], -@@ -267,7 +267,7 @@ - .power = ams_delta_camera_power, - }; - --static struct platform_device ams_delta_camera_device = { -+static struct platform_device ams_delta_camera_device __initdata = { - .name = "soc-camera-pdrv", - .id = 0, - .dev = { -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-fsample.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-fsample.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-fsample.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-fsample.c 2011-03-09 13:19:09.779508251 +0100 -@@ -287,11 +287,11 @@ - &lcd_device, - }; - --static struct omap_lcd_config fsample_lcd_config __initdata = { -+static struct omap_lcd_config fsample_lcd_config = { - .ctrl_name = "internal", - }; - --static struct omap_board_config_kernel fsample_config[] = { -+static struct omap_board_config_kernel fsample_config[] __initdata = { - { OMAP_TAG_LCD, &fsample_lcd_config }, - }; - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-h2.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-h2.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-h2.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-h2.c 2011-03-09 13:19:09.779508251 +0100 -@@ -202,7 +202,7 @@ - - static const char *h2_part_probes[] = { "cmdlinepart", NULL }; - --struct platform_nand_data h2_nand_platdata = { -+static struct platform_nand_data h2_nand_platdata = { - .chip = { - .nr_chips = 1, - .chip_offset = 0, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-h3.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-h3.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-h3.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-h3.c 2011-03-09 13:19:09.780508231 +0100 -@@ -204,7 +204,7 @@ - - static const char *part_probes[] = { "cmdlinepart", NULL }; - --struct platform_nand_data nand_platdata = { -+static struct platform_nand_data nand_platdata = { - .chip = { - .nr_chips = 1, - .chip_offset = 0, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-htcherald.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-htcherald.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-htcherald.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-htcherald.c 2011-03-09 13:19:09.780508231 +0100 -@@ -331,7 +331,7 @@ - }, - }; - --struct htcpld_chip_platform_data htcpld_chips[] = { -+static struct htcpld_chip_platform_data htcpld_chips[] = { - [0] = { - .addr = 0x03, - .reset = 0x04, -@@ -366,7 +366,7 @@ - }, - }; - --struct htcpld_core_platform_data htcpld_pfdata = { -+static struct htcpld_core_platform_data htcpld_pfdata = { - .int_reset_gpio_hi = HTCPLD_GPIO_INT_RESET_HI, - .int_reset_gpio_lo = HTCPLD_GPIO_INT_RESET_LO, - .i2c_adapter_id = 1, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-innovator.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-innovator.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-innovator.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-innovator.c 2011-03-09 13:19:09.781508211 +0100 -@@ -365,7 +365,7 @@ - - static struct omap_mmc_platform_data *mmc_data[OMAP16XX_NR_MMC]; - --void __init innovator_mmc_init(void) -+static void __init innovator_mmc_init(void) - { - mmc_data[0] = &mmc1_data; - omap1_init_mmc(mmc_data, OMAP15XX_NR_MMC); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-nokia770.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-nokia770.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-nokia770.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-nokia770.c 2011-03-09 13:19:09.781508211 +0100 -@@ -115,7 +115,7 @@ - .shutdown = mipid_shutdown, - }; - --static void mipid_dev_init(void) -+static void __init mipid_dev_init(void) - { - const struct omap_lcd_config *conf; - -@@ -126,7 +126,7 @@ - } - } - --static void ads7846_dev_init(void) -+static void __init ads7846_dev_init(void) - { - if (gpio_request(ADS7846_PENDOWN_GPIO, "ADS7846 pendown") < 0) - printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); -@@ -170,7 +170,7 @@ - .te_connected = 1, - }; - --static void hwa742_dev_init(void) -+static void __init hwa742_dev_init(void) - { - clk_add_alias("hwa_sys_ck", NULL, "bclk", NULL); - omapfb_set_ctrl_platform_data(&nokia770_hwa742_platform_data); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-palmte.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-palmte.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-palmte.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-palmte.c 2011-03-09 13:19:09.781508211 +0100 -@@ -230,19 +230,6 @@ - }, - }; - --static void palmte_headphones_detect(void *data, int state) --{ -- if (state) { -- /* Headphones connected, disable speaker */ -- gpio_set_value(PALMTE_SPEAKER_GPIO, 0); -- printk(KERN_INFO "PM: speaker off\n"); -- } else { -- /* Headphones unplugged, re-enable speaker */ -- gpio_set_value(PALMTE_SPEAKER_GPIO, 1); -- printk(KERN_INFO "PM: speaker on\n"); -- } --} -- - static void __init palmte_misc_gpio_setup(void) - { - /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */ -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/board-voiceblue.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-voiceblue.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/board-voiceblue.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/board-voiceblue.c 2011-03-09 13:19:09.783508169 +0100 -@@ -26,10 +26,12 @@ - #include - - #include -+#include - #include - #include - #include - -+#include - #include - #include - #include -@@ -163,52 +165,6 @@ - omap_init_irq(); - } - --static void __init voiceblue_init(void) --{ -- /* mux pins for uarts */ -- omap_cfg_reg(UART1_TX); -- omap_cfg_reg(UART1_RTS); -- omap_cfg_reg(UART2_TX); -- omap_cfg_reg(UART2_RTS); -- omap_cfg_reg(UART3_TX); -- omap_cfg_reg(UART3_RX); -- -- /* Watchdog */ -- gpio_request(0, "Watchdog"); -- /* smc91x reset */ -- gpio_request(7, "SMC91x reset"); -- gpio_direction_output(7, 1); -- udelay(2); /* wait at least 100ns */ -- gpio_set_value(7, 0); -- mdelay(50); /* 50ms until PHY ready */ -- /* smc91x interrupt pin */ -- gpio_request(8, "SMC91x irq"); -- /* 16C554 reset*/ -- gpio_request(6, "16C554 reset"); -- gpio_direction_output(6, 0); -- /* 16C554 interrupt pins */ -- gpio_request(12, "16C554 irq"); -- gpio_request(13, "16C554 irq"); -- gpio_request(14, "16C554 irq"); -- gpio_request(15, "16C554 irq"); -- set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING); -- set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); -- set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); -- set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING); -- -- platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); -- omap_board_config = voiceblue_config; -- omap_board_config_size = ARRAY_SIZE(voiceblue_config); -- omap_serial_init(); -- omap1_usb_init(&voiceblue_usb_config); -- omap_register_i2c_bus(1, 100, NULL, 0); -- -- /* There is a good chance board is going up, so enable power LED -- * (it is connected through invertor) */ -- omap_writeb(0x00, OMAP_LPG1_LCR); -- omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ --} -- - static void __init voiceblue_map_io(void) - { - omap1_map_common_io(); -@@ -275,8 +231,17 @@ - gpio_set_value(0, wdt_gpio_state); - } - --void voiceblue_reset(void) -+static void voiceblue_reset(char mode, const char *cmd) - { -+ /* -+ * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 -+ * "Global Software Reset Affects Traffic Controller Frequency". -+ */ -+ if (cpu_is_omap5912()) { -+ omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL); -+ omap_writew(0x8, ARM_RSTCT1); -+ } -+ - set_bit(MACHINE_REBOOT, &machine_state); - voiceblue_wdt_enable(); - while (1) ; -@@ -286,6 +251,54 @@ - EXPORT_SYMBOL(voiceblue_wdt_disable); - EXPORT_SYMBOL(voiceblue_wdt_ping); - -+static void __init voiceblue_init(void) -+{ -+ /* mux pins for uarts */ -+ omap_cfg_reg(UART1_TX); -+ omap_cfg_reg(UART1_RTS); -+ omap_cfg_reg(UART2_TX); -+ omap_cfg_reg(UART2_RTS); -+ omap_cfg_reg(UART3_TX); -+ omap_cfg_reg(UART3_RX); -+ -+ /* Watchdog */ -+ gpio_request(0, "Watchdog"); -+ /* smc91x reset */ -+ gpio_request(7, "SMC91x reset"); -+ gpio_direction_output(7, 1); -+ udelay(2); /* wait at least 100ns */ -+ gpio_set_value(7, 0); -+ mdelay(50); /* 50ms until PHY ready */ -+ /* smc91x interrupt pin */ -+ gpio_request(8, "SMC91x irq"); -+ /* 16C554 reset*/ -+ gpio_request(6, "16C554 reset"); -+ gpio_direction_output(6, 0); -+ /* 16C554 interrupt pins */ -+ gpio_request(12, "16C554 irq"); -+ gpio_request(13, "16C554 irq"); -+ gpio_request(14, "16C554 irq"); -+ gpio_request(15, "16C554 irq"); -+ set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING); -+ set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); -+ set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); -+ set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING); -+ -+ platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); -+ omap_board_config = voiceblue_config; -+ omap_board_config_size = ARRAY_SIZE(voiceblue_config); -+ omap_serial_init(); -+ omap1_usb_init(&voiceblue_usb_config); -+ omap_register_i2c_bus(1, 100, NULL, 0); -+ -+ /* There is a good chance board is going up, so enable power LED -+ * (it is connected through invertor) */ -+ omap_writeb(0x00, OMAP_LPG1_LCR); -+ omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ -+ -+ arch_reset = voiceblue_reset; -+} -+ - MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") - /* Maintainer: Ladislav Michl */ - .boot_params = 0x10000100, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/Makefile linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/Makefile ---- linux-2.6.38-rc7/arch/arm/mach-omap1/Makefile 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/Makefile 2011-03-09 13:19:09.778508271 +0100 -@@ -4,7 +4,7 @@ - - # Common support - obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o --obj-y += clock.o clock_data.o opp_data.o -+obj-y += clock.o clock_data.o opp_data.o reset.o - - obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/mcbsp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/mcbsp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/mcbsp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/mcbsp.c 2011-03-09 13:19:09.789508048 +0100 -@@ -10,6 +10,7 @@ - * - * Multichannel mode not supported. - */ -+#include - #include - #include - #include -@@ -78,100 +79,288 @@ - }; - - #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) -+struct resource omap7xx_mcbsp_res[][6] = { -+ { -+ { -+ .start = OMAP7XX_MCBSP1_BASE, -+ .end = OMAP7XX_MCBSP1_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_7XX_McBSP1RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_7XX_McBSP1TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP1_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP1_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+ { -+ { -+ .start = OMAP7XX_MCBSP2_BASE, -+ .end = OMAP7XX_MCBSP2_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_7XX_McBSP2RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_7XX_McBSP2TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP3_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP3_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+}; -+ - static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = { - { -- .phys_base = OMAP7XX_MCBSP1_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP1_TX, -- .rx_irq = INT_7XX_McBSP1RX, -- .tx_irq = INT_7XX_McBSP1TX, - .ops = &omap1_mcbsp_ops, - }, - { -- .phys_base = OMAP7XX_MCBSP2_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP3_TX, -- .rx_irq = INT_7XX_McBSP2RX, -- .tx_irq = INT_7XX_McBSP2TX, - .ops = &omap1_mcbsp_ops, - }, - }; --#define OMAP7XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap7xx_mcbsp_pdata) --#define OMAP7XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1) -+#define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1]) -+#define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res) - #else -+#define omap7xx_mcbsp_res NULL - #define omap7xx_mcbsp_pdata NULL --#define OMAP7XX_MCBSP_PDATA_SZ 0 --#define OMAP7XX_MCBSP_REG_NUM 0 -+#define OMAP7XX_MCBSP_RES_SZ 0 -+#define OMAP7XX_MCBSP_COUNT 0 - #endif - - #ifdef CONFIG_ARCH_OMAP15XX -+struct resource omap15xx_mcbsp_res[][6] = { -+ { -+ { -+ .start = OMAP1510_MCBSP1_BASE, -+ .end = OMAP1510_MCBSP1_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_McBSP1RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_McBSP1TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP1_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP1_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+ { -+ { -+ .start = OMAP1510_MCBSP2_BASE, -+ .end = OMAP1510_MCBSP2_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_1510_SPI_RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_1510_SPI_TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP2_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP2_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+ { -+ { -+ .start = OMAP1510_MCBSP3_BASE, -+ .end = OMAP1510_MCBSP3_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_McBSP3RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_McBSP3TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP3_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP3_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+}; -+ - static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { - { -- .phys_base = OMAP1510_MCBSP1_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP1_TX, -- .rx_irq = INT_McBSP1RX, -- .tx_irq = INT_McBSP1TX, - .ops = &omap1_mcbsp_ops, - }, - { -- .phys_base = OMAP1510_MCBSP2_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP2_TX, -- .rx_irq = INT_1510_SPI_RX, -- .tx_irq = INT_1510_SPI_TX, - .ops = &omap1_mcbsp_ops, - }, - { -- .phys_base = OMAP1510_MCBSP3_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP3_TX, -- .rx_irq = INT_McBSP3RX, -- .tx_irq = INT_McBSP3TX, - .ops = &omap1_mcbsp_ops, - }, - }; --#define OMAP15XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap15xx_mcbsp_pdata) --#define OMAP15XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1) -+#define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1]) -+#define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res) - #else -+#define omap15xx_mcbsp_res NULL - #define omap15xx_mcbsp_pdata NULL --#define OMAP15XX_MCBSP_PDATA_SZ 0 --#define OMAP15XX_MCBSP_REG_NUM 0 -+#define OMAP15XX_MCBSP_RES_SZ 0 -+#define OMAP15XX_MCBSP_COUNT 0 - #endif - - #ifdef CONFIG_ARCH_OMAP16XX -+struct resource omap16xx_mcbsp_res[][6] = { -+ { -+ { -+ .start = OMAP1610_MCBSP1_BASE, -+ .end = OMAP1610_MCBSP1_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_McBSP1RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_McBSP1TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP1_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP1_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+ { -+ { -+ .start = OMAP1610_MCBSP2_BASE, -+ .end = OMAP1610_MCBSP2_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_1610_McBSP2_RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_1610_McBSP2_TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP2_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP2_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+ { -+ { -+ .start = OMAP1610_MCBSP3_BASE, -+ .end = OMAP1610_MCBSP3_BASE + SZ_256, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .name = "rx", -+ .start = INT_McBSP3RX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "tx", -+ .start = INT_McBSP3TX, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .name = "rx", -+ .start = OMAP_DMA_MCBSP3_RX, -+ .flags = IORESOURCE_DMA, -+ }, -+ { -+ .name = "tx", -+ .start = OMAP_DMA_MCBSP3_TX, -+ .flags = IORESOURCE_DMA, -+ }, -+ }, -+}; -+ - static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { - { -- .phys_base = OMAP1610_MCBSP1_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP1_TX, -- .rx_irq = INT_McBSP1RX, -- .tx_irq = INT_McBSP1TX, - .ops = &omap1_mcbsp_ops, - }, - { -- .phys_base = OMAP1610_MCBSP2_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP2_TX, -- .rx_irq = INT_1610_McBSP2_RX, -- .tx_irq = INT_1610_McBSP2_TX, - .ops = &omap1_mcbsp_ops, - }, - { -- .phys_base = OMAP1610_MCBSP3_BASE, -- .dma_rx_sync = OMAP_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP_DMA_MCBSP3_TX, -- .rx_irq = INT_McBSP3RX, -- .tx_irq = INT_McBSP3TX, - .ops = &omap1_mcbsp_ops, - }, - }; --#define OMAP16XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap16xx_mcbsp_pdata) --#define OMAP16XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_XCERH / sizeof(u16) + 1) -+#define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1]) -+#define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res) - #else -+#define omap16xx_mcbsp_res NULL - #define omap16xx_mcbsp_pdata NULL --#define OMAP16XX_MCBSP_PDATA_SZ 0 --#define OMAP16XX_MCBSP_REG_NUM 0 -+#define OMAP16XX_MCBSP_RES_SZ 0 -+#define OMAP16XX_MCBSP_COUNT 0 - #endif - - static int __init omap1_mcbsp_init(void) -@@ -179,16 +368,12 @@ - if (!cpu_class_is_omap1()) - return -ENODEV; - -- if (cpu_is_omap7xx()) { -- omap_mcbsp_count = OMAP7XX_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP7XX_MCBSP_REG_NUM * sizeof(u16); -- } else if (cpu_is_omap15xx()) { -- omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP15XX_MCBSP_REG_NUM * sizeof(u16); -- } else if (cpu_is_omap16xx()) { -- omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP16XX_MCBSP_REG_NUM * sizeof(u16); -- } -+ if (cpu_is_omap7xx()) -+ omap_mcbsp_count = OMAP7XX_MCBSP_COUNT; -+ else if (cpu_is_omap15xx()) -+ omap_mcbsp_count = OMAP15XX_MCBSP_COUNT; -+ else if (cpu_is_omap16xx()) -+ omap_mcbsp_count = OMAP16XX_MCBSP_COUNT; - - mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), - GFP_KERNEL); -@@ -196,16 +381,22 @@ - return -ENOMEM; - - if (cpu_is_omap7xx()) -- omap_mcbsp_register_board_cfg(omap7xx_mcbsp_pdata, -- OMAP7XX_MCBSP_PDATA_SZ); -+ omap_mcbsp_register_board_cfg(omap7xx_mcbsp_res[0], -+ OMAP7XX_MCBSP_RES_SZ, -+ omap7xx_mcbsp_pdata, -+ OMAP7XX_MCBSP_COUNT); - - if (cpu_is_omap15xx()) -- omap_mcbsp_register_board_cfg(omap15xx_mcbsp_pdata, -- OMAP15XX_MCBSP_PDATA_SZ); -+ omap_mcbsp_register_board_cfg(omap15xx_mcbsp_res[0], -+ OMAP15XX_MCBSP_RES_SZ, -+ omap15xx_mcbsp_pdata, -+ OMAP15XX_MCBSP_COUNT); - - if (cpu_is_omap16xx()) -- omap_mcbsp_register_board_cfg(omap16xx_mcbsp_pdata, -- OMAP16XX_MCBSP_PDATA_SZ); -+ omap_mcbsp_register_board_cfg(omap16xx_mcbsp_res[0], -+ OMAP16XX_MCBSP_RES_SZ, -+ omap16xx_mcbsp_pdata, -+ OMAP16XX_MCBSP_COUNT); - - return omap_mcbsp_init(); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap1/reset.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/reset.c ---- linux-2.6.38-rc7/arch/arm/mach-omap1/reset.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap1/reset.c 2011-03-09 13:19:09.791508008 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * OMAP1 reset support -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+ -+void omap1_arch_reset(char mode, const char *cmd) -+{ -+ /* -+ * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 -+ * "Global Software Reset Affects Traffic Controller Frequency". -+ */ -+ if (cpu_is_omap5912()) { -+ omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), DPLL_CTL); -+ omap_writew(0x8, ARM_RSTCT1); -+ } -+ -+ omap_writew(1, ARM_RSTCT1); -+} -+ -+void (*arch_reset)(char, const char *) = omap1_arch_reset; -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-2430sdp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-2430sdp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-2430sdp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-2430sdp.c 2011-03-09 13:19:09.793507967 +0100 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -139,15 +140,31 @@ - {OMAP_TAG_LCD, &sdp2430_lcd_config}, - }; - --static void __init omap_2430sdp_init_irq(void) -+static void __init omap_2430sdp_init_early(void) - { -- omap_board_config = sdp2430_config; -- omap_board_config_size = ARRAY_SIZE(sdp2430_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - -+static struct regulator_consumer_supply sdp2430_vmmc1_supplies[] = { -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -+}; -+ -+/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -+static struct regulator_init_data sdp2430_vmmc1 = { -+ .constraints = { -+ .min_uV = 1850000, -+ .max_uV = 3150000, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE -+ | REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = ARRAY_SIZE(sdp2430_vmmc1_supplies), -+ .consumer_supplies = &sdp2430_vmmc1_supplies[0], -+}; -+ - static struct twl4030_gpio_platform_data sdp2430_gpio_data = { - .gpio_base = OMAP_MAX_GPIO_LINES, - .irq_base = TWL4030_GPIO_IRQ_BASE, -@@ -160,6 +177,7 @@ - - /* platform_data for children goes here */ - .gpio = &sdp2430_gpio_data, -+ .vmmc1 = &sdp2430_vmmc1, - }; - - static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = { -@@ -226,6 +244,9 @@ - - omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC); - -+ omap_board_config = sdp2430_config; -+ omap_board_config_size = ARRAY_SIZE(sdp2430_config); -+ - omap2430_i2c_init(); - - platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices)); -@@ -253,9 +274,10 @@ - MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board") - /* Maintainer: Syed Khasim - Texas Instruments Inc */ - .boot_params = 0x80000100, -- .map_io = omap_2430sdp_map_io, - .reserve = omap_reserve, -- .init_irq = omap_2430sdp_init_irq, -+ .map_io = omap_2430sdp_map_io, -+ .init_early = omap_2430sdp_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_2430sdp_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-3430sdp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-3430sdp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-3430sdp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-3430sdp.c 2011-03-09 13:19:09.793507967 +0100 -@@ -307,34 +307,13 @@ - .default_device = &sdp3430_lcd_device, - }; - --static struct platform_device sdp3430_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &sdp3430_dss_data, -- }, --}; -- --static struct regulator_consumer_supply sdp3430_vdda_dac_supply = { -- .supply = "vdda_dac", -- .dev = &sdp3430_dss_device.dev, --}; -- --static struct platform_device *sdp3430_devices[] __initdata = { -- &sdp3430_dss_device, --}; -- - static struct omap_board_config_kernel sdp3430_config[] __initdata = { - }; - --static void __init omap_3430sdp_init_irq(void) -+static void __init omap_3430sdp_init_early(void) - { -- omap_board_config = sdp3430_config; -- omap_board_config_size = ARRAY_SIZE(sdp3430_config); -- omap3_pm_init_cpuidle(omap3_cpuidle_params_table); - omap2_init_common_infrastructure(); - omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL); -- omap_init_irq(); - } - - static int sdp3430_batt_table[] = { -@@ -370,18 +349,6 @@ - {} /* Terminator */ - }; - --static struct regulator_consumer_supply sdp3430_vmmc1_supply = { -- .supply = "vmmc", --}; -- --static struct regulator_consumer_supply sdp3430_vsim_supply = { -- .supply = "vmmc_aux", --}; -- --static struct regulator_consumer_supply sdp3430_vmmc2_supply = { -- .supply = "vmmc", --}; -- - static int sdp3430_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) - { -@@ -392,13 +359,6 @@ - mmc[1].gpio_cd = gpio + 1; - omap2_hsmmc_init(mmc); - -- /* link regulators to MMC adapters ... we "know" the -- * regulators will be set up only *after* we return. -- */ -- sdp3430_vmmc1_supply.dev = mmc[0].dev; -- sdp3430_vsim_supply.dev = mmc[0].dev; -- sdp3430_vmmc2_supply.dev = mmc[1].dev; -- - /* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */ - gpio_request(gpio + 7, "sub_lcd_en_bkl"); - gpio_direction_output(gpio + 7, 0); -@@ -427,6 +387,35 @@ - .irq_line = 1, - }; - -+/* regulator consumer mappings */ -+ -+/* ads7846 on SPI */ -+static struct regulator_consumer_supply sdp3430_vaux3_supplies[] = { -+ REGULATOR_SUPPLY("vcc", "spi1.0"), -+}; -+ -+static struct regulator_consumer_supply sdp3430_vdda_dac_supplies[] = { -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"), -+}; -+ -+/* VPLL2 for digital video outputs */ -+static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; -+ -+static struct regulator_consumer_supply sdp3430_vmmc1_supplies[] = { -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"), -+}; -+ -+static struct regulator_consumer_supply sdp3430_vsim_supplies[] = { -+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.0"), -+}; -+ -+static struct regulator_consumer_supply sdp3430_vmmc2_supplies[] = { -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), -+}; -+ - /* - * Apply all the fixed voltages since most versions of U-Boot - * don't bother with that initialization. -@@ -469,6 +458,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vaux3_supplies), -+ .consumer_supplies = sdp3430_vaux3_supplies, - }; - - /* VAUX4 for OMAP VDD_CSI2 (camera) */ -@@ -495,8 +486,8 @@ - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &sdp3430_vmmc1_supply, -+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc1_supplies), -+ .consumer_supplies = sdp3430_vmmc1_supplies, - }; - - /* VMMC2 for MMC2 card */ -@@ -510,8 +501,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &sdp3430_vmmc2_supply, -+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vmmc2_supplies), -+ .consumer_supplies = sdp3430_vmmc2_supplies, - }; - - /* VSIM for OMAP VDD_MMC1A (i/o for DAT4..DAT7) */ -@@ -525,8 +516,8 @@ - | REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &sdp3430_vsim_supply, -+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vsim_supplies), -+ .consumer_supplies = sdp3430_vsim_supplies, - }; - - /* VDAC for DSS driving S-Video */ -@@ -540,16 +531,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &sdp3430_vdda_dac_supply, --}; -- --/* VPLL2 for digital video outputs */ --static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = { -- { -- .supply = "vdds_dsi", -- .dev = &sdp3430_dss_device.dev, -- } -+ .num_consumer_supplies = ARRAY_SIZE(sdp3430_vdda_dac_supplies), -+ .consumer_supplies = sdp3430_vdda_dac_supplies, - }; - - static struct regulator_init_data sdp3430_vpll2 = { -@@ -567,9 +550,7 @@ - .consumer_supplies = sdp3430_vpll2_supplies, - }; - --static struct twl4030_codec_audio_data sdp3430_audio = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data sdp3430_audio; - - static struct twl4030_codec_data sdp3430_codec = { - .audio_mclk = 26000000, -@@ -800,8 +781,11 @@ - static void __init omap_3430sdp_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -+ omap_board_config = sdp3430_config; -+ omap_board_config_size = ARRAY_SIZE(sdp3430_config); -+ omap3_pm_init_cpuidle(omap3_cpuidle_params_table); - omap3430_i2c_init(); -- platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices)); -+ omap_display_init(&sdp3430_dss_data); - if (omap_rev() > OMAP3430_REV_ES1_0) - ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2; - else -@@ -813,7 +797,7 @@ - omap_serial_init(); - usb_musb_init(&musb_board_data); - board_smc91x_init(); -- board_flash_init(sdp_flash_partitions, chip_sel_3430); -+ board_flash_init(sdp_flash_partitions, chip_sel_3430, 0); - sdp3430_display_init(); - enable_board_wakeup_source(); - usb_ehci_init(&ehci_pdata); -@@ -822,9 +806,10 @@ - MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board") - /* Maintainer: Syed Khasim - Texas Instruments Inc */ - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap_3430sdp_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap_3430sdp_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_3430sdp_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-3630sdp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-3630sdp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-3630sdp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-3630sdp.c 2011-03-09 13:19:09.793507967 +0100 -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -69,14 +70,11 @@ - static struct omap_board_config_kernel sdp_config[] __initdata = { - }; - --static void __init omap_sdp_init_irq(void) -+static void __init omap_sdp_init_early(void) - { -- omap_board_config = sdp_config; -- omap_board_config_size = ARRAY_SIZE(sdp_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params, - h8mbx00u0mer0em_sdrc_params); -- omap_init_irq(); - } - - #ifdef CONFIG_OMAP_MUX -@@ -206,19 +204,22 @@ - static void __init omap_sdp_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBP); -+ omap_board_config = sdp_config; -+ omap_board_config_size = ARRAY_SIZE(sdp_config); - zoom_peripherals_init(); - zoom_display_init(); - board_smc91x_init(); -- board_flash_init(sdp_flash_partitions, chip_sel_sdp); -+ board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16); - enable_board_wakeup_source(); - usb_ehci_init(&ehci_pdata); - } - - MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap_sdp_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap_sdp_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_sdp_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-4430sdp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-4430sdp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-4430sdp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-4430sdp.c 2011-03-09 13:19:09.794507946 +0100 -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - #include "mux.h" - #include "hsmmc.h" -@@ -44,10 +45,93 @@ - #define ETH_KS8851_IRQ 34 - #define ETH_KS8851_POWER_ON 48 - #define ETH_KS8851_QUART 138 --#define OMAP4SDP_MDM_PWR_EN_GPIO 157 - #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 - #define OMAP4_SFH7741_ENABLE_GPIO 188 - -+static const int sdp4430_keymap[] = { -+ KEY(0, 0, KEY_E), -+ KEY(0, 1, KEY_R), -+ KEY(0, 2, KEY_T), -+ KEY(0, 3, KEY_HOME), -+ KEY(0, 4, KEY_F5), -+ KEY(0, 5, KEY_UNKNOWN), -+ KEY(0, 6, KEY_I), -+ KEY(0, 7, KEY_LEFTSHIFT), -+ -+ KEY(1, 0, KEY_D), -+ KEY(1, 1, KEY_F), -+ KEY(1, 2, KEY_G), -+ KEY(1, 3, KEY_SEND), -+ KEY(1, 4, KEY_F6), -+ KEY(1, 5, KEY_UNKNOWN), -+ KEY(1, 6, KEY_K), -+ KEY(1, 7, KEY_ENTER), -+ -+ KEY(2, 0, KEY_X), -+ KEY(2, 1, KEY_C), -+ KEY(2, 2, KEY_V), -+ KEY(2, 3, KEY_END), -+ KEY(2, 4, KEY_F7), -+ KEY(2, 5, KEY_UNKNOWN), -+ KEY(2, 6, KEY_DOT), -+ KEY(2, 7, KEY_CAPSLOCK), -+ -+ KEY(3, 0, KEY_Z), -+ KEY(3, 1, KEY_KPPLUS), -+ KEY(3, 2, KEY_B), -+ KEY(3, 3, KEY_F1), -+ KEY(3, 4, KEY_F8), -+ KEY(3, 5, KEY_UNKNOWN), -+ KEY(3, 6, KEY_O), -+ KEY(3, 7, KEY_SPACE), -+ -+ KEY(4, 0, KEY_W), -+ KEY(4, 1, KEY_Y), -+ KEY(4, 2, KEY_U), -+ KEY(4, 3, KEY_F2), -+ KEY(4, 4, KEY_VOLUMEUP), -+ KEY(4, 5, KEY_UNKNOWN), -+ KEY(4, 6, KEY_L), -+ KEY(4, 7, KEY_LEFT), -+ -+ KEY(5, 0, KEY_S), -+ KEY(5, 1, KEY_H), -+ KEY(5, 2, KEY_J), -+ KEY(5, 3, KEY_F3), -+ KEY(5, 4, KEY_F9), -+ KEY(5, 5, KEY_VOLUMEDOWN), -+ KEY(5, 6, KEY_M), -+ KEY(5, 7, KEY_RIGHT), -+ -+ KEY(6, 0, KEY_Q), -+ KEY(6, 1, KEY_A), -+ KEY(6, 2, KEY_N), -+ KEY(6, 3, KEY_BACK), -+ KEY(6, 4, KEY_BACKSPACE), -+ KEY(6, 5, KEY_UNKNOWN), -+ KEY(6, 6, KEY_P), -+ KEY(6, 7, KEY_UP), -+ -+ KEY(7, 0, KEY_PROG1), -+ KEY(7, 1, KEY_PROG2), -+ KEY(7, 2, KEY_PROG3), -+ KEY(7, 3, KEY_PROG4), -+ KEY(7, 4, KEY_F4), -+ KEY(7, 5, KEY_UNKNOWN), -+ KEY(7, 6, KEY_OK), -+ KEY(7, 7, KEY_DOWN), -+}; -+ -+static struct matrix_keymap_data sdp4430_keymap_data = { -+ .keymap = sdp4430_keymap, -+ .keymap_size = ARRAY_SIZE(sdp4430_keymap), -+}; -+ -+static struct omap4_keypad_platform_data sdp4430_keypad_data = { -+ .keymap_data = &sdp4430_keymap_data, -+ .rows = 8, -+ .cols = 8, -+}; - static struct gpio_led sdp4430_gpio_leds[] = { - { - .name = "omap4:green:debug0", -@@ -239,28 +323,15 @@ - { OMAP_TAG_LCD, &sdp4430_lcd_config }, - }; - --static void __init omap_4430sdp_init_irq(void) -+static void __init omap_4430sdp_init_early(void) - { -- omap_board_config = sdp4430_config; -- omap_board_config_size = ARRAY_SIZE(sdp4430_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); - #ifdef CONFIG_OMAP_32K_TIMER - omap2_gp_clockevent_set_gptimer(1); - #endif -- gic_init_irq(); - } - --static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { -- .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, -- .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, -- .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, -- .phy_reset = false, -- .reset_gpio_port[0] = -EINVAL, -- .reset_gpio_port[1] = -EINVAL, -- .reset_gpio_port[2] = -EINVAL, --}; -- - static struct omap_musb_board_data musb_board_data = { - .interface_type = MUSB_INTERFACE_UTMI, - .mode = MUSB_OTG, -@@ -276,11 +347,6 @@ - - static struct omap2_hsmmc_info mmc[] = { - { -- .mmc = 1, -- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, -- .gpio_wp = -EINVAL, -- }, -- { - .mmc = 2, - .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, - .gpio_cd = -EINVAL, -@@ -288,19 +354,24 @@ - .nonremovable = true, - .ocr_mask = MMC_VDD_29_30, - }, -+ { -+ .mmc = 1, -+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, -+ .gpio_wp = -EINVAL, -+ }, - {} /* Terminator */ - }; - - static struct regulator_consumer_supply sdp4430_vaux_supply[] = { - { - .supply = "vmmc", -- .dev_name = "mmci-omap-hs.1", -+ .dev_name = "omap_hsmmc.1", - }, - }; - static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { - { - .supply = "vmmc", -- .dev_name = "mmci-omap-hs.0", -+ .dev_name = "omap_hsmmc.0", - }, - }; - -@@ -434,7 +505,6 @@ - .constraints = { - .min_uV = 2100000, - .max_uV = 2100000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -446,7 +516,6 @@ - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -458,7 +527,6 @@ - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -570,20 +638,15 @@ - package = OMAP_PACKAGE_CBL; - omap4_mux_init(board_mux, package); - -+ omap_board_config = sdp4430_config; -+ omap_board_config_size = ARRAY_SIZE(sdp4430_config); -+ - omap4_i2c_init(); - omap_sfh7741prox_init(); - platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); - omap_serial_init(); - omap4_twl6030_hsmmc_init(mmc); - -- /* Power on the ULPI PHY */ -- status = gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); -- if (status) -- pr_err("%s: Could not get USBB1 PHY GPIO\n", __func__); -- else -- gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); -- -- usb_ehci_init(&ehci_pdata); - usb_musb_init(&musb_board_data); - - status = omap_ethernet_init(); -@@ -594,6 +657,10 @@ - spi_register_board_info(sdp4430_spi_board_info, - ARRAY_SIZE(sdp4430_spi_board_info)); - } -+ -+ status = omap4_keyboard_init(&sdp4430_keypad_data); -+ if (status) -+ pr_err("Keypad initialization failed: %d\n", status); - } - - static void __init omap_4430sdp_map_io(void) -@@ -605,9 +672,10 @@ - MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") - /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */ - .boot_params = 0x80000100, -- .map_io = omap_4430sdp_map_io, - .reserve = omap_reserve, -- .init_irq = omap_4430sdp_init_irq, -+ .map_io = omap_4430sdp_map_io, -+ .init_early = omap_4430sdp_init_early, -+ .init_irq = gic_init_irq, - .init_machine = omap_4430sdp_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-am3517crane.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-am3517crane.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-am3517crane.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-am3517crane.c 2011-03-09 13:19:09.794507946 +0100 -@@ -49,14 +49,10 @@ - #define board_mux NULL - #endif - --static void __init am3517_crane_init_irq(void) -+static void __init am3517_crane_init_early(void) - { -- omap_board_config = am3517_crane_config; -- omap_board_config_size = ARRAY_SIZE(am3517_crane_config); -- - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { -@@ -77,6 +73,9 @@ - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap_serial_init(); - -+ omap_board_config = am3517_crane_config; -+ omap_board_config_size = ARRAY_SIZE(am3517_crane_config); -+ - /* Configure GPIO for EHCI port */ - if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) { - pr_err("Can not configure mux for GPIO_USB_NRESET %d\n", -@@ -108,9 +107,10 @@ - - MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = am3517_crane_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = am3517_crane_init_early, -+ .init_irq = omap_init_irq, - .init_machine = am3517_crane_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-am3517evm.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-am3517evm.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-am3517evm.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-am3517evm.c 2011-03-09 13:19:09.794507946 +0100 -@@ -378,37 +378,23 @@ - .default_device = &am3517_evm_lcd_device, - }; - --static struct platform_device am3517_evm_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &am3517_evm_dss_data, -- }, --}; -- - /* - * Board initialization - */ --static struct omap_board_config_kernel am3517_evm_config[] __initdata = { --}; -- --static struct platform_device *am3517_evm_devices[] __initdata = { -- &am3517_evm_dss_device, --}; -- --static void __init am3517_evm_init_irq(void) -+static void __init am3517_evm_init_early(void) - { -- omap_board_config = am3517_evm_config; -- omap_board_config_size = ARRAY_SIZE(am3517_evm_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static struct omap_musb_board_data musb_board_data = { - .interface_type = MUSB_INTERFACE_ULPI, - .mode = MUSB_OTG, - .power = 500, -+ .set_phy_power = am35x_musb_phy_power, -+ .clear_irq = am35x_musb_clear_irq, -+ .set_mode = am35x_musb_set_mode, -+ .reset = am35x_musb_reset, - }; - - static __init void am3517_evm_musb_init(void) -@@ -490,14 +476,17 @@ - platform_device_register(&am3517_hecc_device); - } - -+static struct omap_board_config_kernel am3517_evm_config[] __initdata = { -+}; -+ - static void __init am3517_evm_init(void) - { -+ omap_board_config = am3517_evm_config; -+ omap_board_config_size = ARRAY_SIZE(am3517_evm_config); - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - - am3517_evm_i2c_init(); -- platform_add_devices(am3517_evm_devices, -- ARRAY_SIZE(am3517_evm_devices)); -- -+ omap_display_init(&am3517_evm_dss_data); - omap_serial_init(); - - /* Configure GPIO for EHCI port */ -@@ -521,9 +510,10 @@ - - MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = am3517_evm_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = am3517_evm_init_early, -+ .init_irq = omap_init_irq, - .init_machine = am3517_evm_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-apollon.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-apollon.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-apollon.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-apollon.c 2011-03-09 13:19:09.794507946 +0100 -@@ -274,13 +274,10 @@ - { OMAP_TAG_LCD, &apollon_lcd_config }, - }; - --static void __init omap_apollon_init_irq(void) -+static void __init omap_apollon_init_early(void) - { -- omap_board_config = apollon_config; -- omap_board_config_size = ARRAY_SIZE(apollon_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static void __init apollon_led_init(void) -@@ -320,6 +317,8 @@ - u32 v; - - omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC); -+ omap_board_config = apollon_config; -+ omap_board_config_size = ARRAY_SIZE(apollon_config); - - apollon_init_smc91x(); - apollon_led_init(); -@@ -355,9 +354,10 @@ - MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon") - /* Maintainer: Kyungmin Park */ - .boot_params = 0x80000100, -- .map_io = omap_apollon_map_io, - .reserve = omap_reserve, -- .init_irq = omap_apollon_init_irq, -+ .map_io = omap_apollon_map_io, -+ .init_early = omap_apollon_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_apollon_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-cm-t3517.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-cm-t3517.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-cm-t3517.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-cm-t3517.c 2011-03-09 13:19:09.795507925 +0100 -@@ -254,14 +254,10 @@ - static struct omap_board_config_kernel cm_t3517_config[] __initdata = { - }; - --static void __init cm_t3517_init_irq(void) -+static void __init cm_t3517_init_early(void) - { -- omap_board_config = cm_t3517_config; -- omap_board_config_size = ARRAY_SIZE(cm_t3517_config); -- - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static struct omap_board_mux board_mux[] __initdata = { -@@ -294,6 +290,8 @@ - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - omap_serial_init(); -+ omap_board_config = cm_t3517_config; -+ omap_board_config_size = ARRAY_SIZE(cm_t3517_config); - cm_t3517_init_leds(); - cm_t3517_init_nand(); - cm_t3517_init_rtc(); -@@ -303,9 +301,10 @@ - - MACHINE_START(CM_T3517, "Compulab CM-T3517") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = cm_t3517_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = cm_t3517_init_early, -+ .init_irq = omap_init_irq, - .init_machine = cm_t3517_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-cm-t35.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-cm-t35.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-cm-t35.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-cm-t35.c 2011-03-09 13:19:09.795507925 +0100 -@@ -401,14 +401,6 @@ - .default_device = &cm_t35_dvi_device, - }; - --static struct platform_device cm_t35_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &cm_t35_dss_data, -- }, --}; -- - static struct omap2_mcspi_device_config tdo24m_mcspi_config = { - .turbo_mode = 0, - .single_channel = 1, /* 0: slave, 1: master */ -@@ -468,7 +460,7 @@ - msleep(50); - gpio_set_value(lcd_en_gpio, 1); - -- err = platform_device_register(&cm_t35_dss_device); -+ err = omap_display_init(&cm_t35_dss_data); - if (err) { - pr_err("CM-T35: failed to register DSS device\n"); - goto err_dev_reg; -@@ -495,15 +487,11 @@ - .supply = "vmmc_aux", - }; - --static struct regulator_consumer_supply cm_t35_vdac_supply = { -- .supply = "vdda_dac", -- .dev = &cm_t35_dss_device.dev, --}; -+static struct regulator_consumer_supply cm_t35_vdac_supply = -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - --static struct regulator_consumer_supply cm_t35_vdvi_supply = { -- .supply = "vdvi", -- .dev = &cm_t35_dss_device.dev, --}; -+static struct regulator_consumer_supply cm_t35_vdvi_supply = -+ REGULATOR_SUPPLY("vdvi", "omapdss"); - - /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ - static struct regulator_init_data cm_t35_vmmc1 = { -@@ -680,18 +668,11 @@ - ARRAY_SIZE(cm_t35_i2c_boardinfo)); - } - --static struct omap_board_config_kernel cm_t35_config[] __initdata = { --}; -- --static void __init cm_t35_init_irq(void) -+static void __init cm_t35_init_early(void) - { -- omap_board_config = cm_t35_config; -- omap_board_config_size = ARRAY_SIZE(cm_t35_config); -- - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -- omap_init_irq(); - } - - static struct omap_board_mux board_mux[] __initdata = { -@@ -798,8 +779,13 @@ - .power = 100, - }; - -+static struct omap_board_config_kernel cm_t35_config[] __initdata = { -+}; -+ - static void __init cm_t35_init(void) - { -+ omap_board_config = cm_t35_config; -+ omap_board_config_size = ARRAY_SIZE(cm_t35_config); - omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); - omap_serial_init(); - cm_t35_init_i2c(); -@@ -815,9 +801,10 @@ - - MACHINE_START(CM_T35, "Compulab CM-T35") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = cm_t35_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = cm_t35_init_early, -+ .init_irq = omap_init_irq, - .init_machine = cm_t35_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-devkit8000.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-devkit8000.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-devkit8000.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-devkit8000.c 2011-03-09 13:19:09.795507925 +0100 -@@ -140,7 +140,7 @@ - } - - static struct regulator_consumer_supply devkit8000_vmmc1_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); - - - /* ads7846 on SPI */ -@@ -195,16 +195,8 @@ - .default_device = &devkit8000_lcd_device, - }; - --static struct platform_device devkit8000_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &devkit8000_dss_data, -- }, --}; -- - static struct regulator_consumer_supply devkit8000_vdda_dac_supply = -- REGULATOR_SUPPLY("vdda_dac", "omapdss"); -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - - static uint32_t board_keymap[] = { - KEY(0, 0, KEY_1), -@@ -285,8 +277,10 @@ - .setup = devkit8000_twl_gpio_setup, - }; - --static struct regulator_consumer_supply devkit8000_vpll1_supply = -- REGULATOR_SUPPLY("vdds_dsi", "omapdss"); -+static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; - - /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */ - static struct regulator_init_data devkit8000_vmmc1 = { -@@ -327,8 +321,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &devkit8000_vpll1_supply, -+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies), -+ .consumer_supplies = devkit8000_vpll1_supplies, - }; - - /* VAUX4 for ads7846 and nubs */ -@@ -350,9 +344,7 @@ - .usb_mode = T2_USB_MODE_ULPI, - }; - --static struct twl4030_codec_audio_data devkit8000_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data devkit8000_audio_data; - - static struct twl4030_codec_data devkit8000_codec_data = { - .audio_mclk = 26000000, -@@ -456,11 +448,15 @@ - }; - - --static void __init devkit8000_init_irq(void) -+static void __init devkit8000_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -+} -+ -+static void __init devkit8000_init_irq(void) -+{ - omap_init_irq(); - #ifdef CONFIG_OMAP_32K_TIMER - omap2_gp_clockevent_set_gptimer(12); -@@ -575,7 +571,6 @@ - } - - static struct platform_device *devkit8000_devices[] __initdata = { -- &devkit8000_dss_device, - &leds_gpio, - &keys_gpio, - &omap_dm9000_dev, -@@ -797,6 +792,7 @@ - platform_add_devices(devkit8000_devices, - ARRAY_SIZE(devkit8000_devices)); - -+ omap_display_init(&devkit8000_dss_data); - spi_register_board_info(devkit8000_spi_board_info, - ARRAY_SIZE(devkit8000_spi_board_info)); - -@@ -813,8 +809,9 @@ - - MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -+ .map_io = omap3_map_io, -+ .init_early = devkit8000_init_early, - .init_irq = devkit8000_init_irq, - .init_machine = devkit8000_init, - .timer = &omap_timer, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-flash.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-flash.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-flash.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-flash.c 2011-03-09 13:19:09.796507904 +0100 -@@ -1,5 +1,5 @@ - /* -- * board-sdp-flash.c -+ * board-flash.c - * Modified from mach-omap2/board-3430sdp-flash.c - * - * Copyright (C) 2009 Nokia Corporation -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -73,11 +74,11 @@ - + FLASH_SIZE_SDPV1 - 1; - } - if (err < 0) { -- printk(KERN_ERR "NOR: Can't request GPMC CS\n"); -+ pr_err("NOR: Can't request GPMC CS\n"); - return; - } - if (platform_device_register(&board_nor_device) < 0) -- printk(KERN_ERR "Unable to register NOR device\n"); -+ pr_err("Unable to register NOR device\n"); - } - - #if defined(CONFIG_MTD_ONENAND_OMAP2) || \ -@@ -139,17 +140,21 @@ - }; - - void --__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) -+__init board_nand_init(struct mtd_partition *nand_parts, -+ u8 nr_parts, u8 cs, int nand_type) - { - board_nand_data.cs = cs; - board_nand_data.parts = nand_parts; -- board_nand_data.nr_parts = nr_parts; -+ board_nand_data.nr_parts = nr_parts; -+ board_nand_data.devsize = nand_type; - -+ board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; -+ board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs; - gpmc_nand_init(&board_nand_data); - } - #else - void --__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs) -+__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, int nand_type) - { - } - #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ -@@ -189,12 +194,12 @@ - } - - /** -- * sdp3430_flash_init - Identify devices connected to GPMC and register. -+ * board_flash_init - Identify devices connected to GPMC and register. - * - * @return - void. - */ - void board_flash_init(struct flash_partitions partition_info[], -- char chip_sel_board[][GPMC_CS_NUM]) -+ char chip_sel_board[][GPMC_CS_NUM], int nand_type) - { - u8 cs = 0; - u8 norcs = GPMC_CS_NUM + 1; -@@ -208,7 +213,7 @@ - */ - idx = get_gpmc0_type(); - if (idx >= MAX_SUPPORTED_GPMC_CONFIG) { -- printk(KERN_ERR "%s: Invalid chip select: %d\n", __func__, cs); -+ pr_err("%s: Invalid chip select: %d\n", __func__, cs); - return; - } - config_sel = (unsigned char *)(chip_sel_board[idx]); -@@ -232,23 +237,20 @@ - } - - if (norcs > GPMC_CS_NUM) -- printk(KERN_INFO "NOR: Unable to find configuration " -- "in GPMC\n"); -+ pr_err("NOR: Unable to find configuration in GPMC\n"); - else - board_nor_init(partition_info[0].parts, - partition_info[0].nr_parts, norcs); - - if (onenandcs > GPMC_CS_NUM) -- printk(KERN_INFO "OneNAND: Unable to find configuration " -- "in GPMC\n"); -+ pr_err("OneNAND: Unable to find configuration in GPMC\n"); - else - board_onenand_init(partition_info[1].parts, - partition_info[1].nr_parts, onenandcs); - - if (nandcs > GPMC_CS_NUM) -- printk(KERN_INFO "NAND: Unable to find configuration " -- "in GPMC\n"); -+ pr_err("NAND: Unable to find configuration in GPMC\n"); - else - board_nand_init(partition_info[2].parts, -- partition_info[2].nr_parts, nandcs); -+ partition_info[2].nr_parts, nandcs, nand_type); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-flash.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-flash.h ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-flash.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-flash.h 2011-03-09 13:19:09.796507904 +0100 -@@ -25,6 +25,6 @@ - }; - - extern void board_flash_init(struct flash_partitions [], -- char chip_sel[][GPMC_CS_NUM]); -+ char chip_sel[][GPMC_CS_NUM], int nand_type); - extern void board_nand_init(struct mtd_partition *nand_parts, -- u8 nr_parts, u8 cs); -+ u8 nr_parts, u8 cs, int nand_type); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-generic.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-generic.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-generic.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-generic.c 2011-03-09 13:19:09.796507904 +0100 -@@ -33,18 +33,17 @@ - static struct omap_board_config_kernel generic_config[] = { - }; - --static void __init omap_generic_init_irq(void) -+static void __init omap_generic_init_early(void) - { -- omap_board_config = generic_config; -- omap_board_config_size = ARRAY_SIZE(generic_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static void __init omap_generic_init(void) - { - omap_serial_init(); -+ omap_board_config = generic_config; -+ omap_board_config_size = ARRAY_SIZE(generic_config); - } - - static void __init omap_generic_map_io(void) -@@ -68,9 +67,10 @@ - MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") - /* Maintainer: Paul Mundt */ - .boot_params = 0x80000100, -- .map_io = omap_generic_map_io, - .reserve = omap_reserve, -- .init_irq = omap_generic_init_irq, -+ .map_io = omap_generic_map_io, -+ .init_early = omap_generic_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_generic_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-h4.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-h4.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-h4.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-h4.c 2011-03-09 13:19:09.796507904 +0100 -@@ -290,12 +290,14 @@ - { OMAP_TAG_LCD, &h4_lcd_config }, - }; - --static void __init omap_h4_init_irq(void) -+static void __init omap_h4_init_early(void) - { -- omap_board_config = h4_config; -- omap_board_config_size = ARRAY_SIZE(h4_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -+} -+ -+static void __init omap_h4_init_irq(void) -+{ - omap_init_irq(); - h4_init_flash(); - } -@@ -330,6 +332,9 @@ - { - omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF); - -+ omap_board_config = h4_config; -+ omap_board_config_size = ARRAY_SIZE(h4_config); -+ - /* - * Make sure the serial ports are muxed on at this point. - * You have to mux them off in device drivers later on -@@ -378,8 +383,9 @@ - MACHINE_START(OMAP_H4, "OMAP2420 H4 board") - /* Maintainer: Paul Mundt */ - .boot_params = 0x80000100, -- .map_io = omap_h4_map_io, - .reserve = omap_reserve, -+ .map_io = omap_h4_map_io, -+ .init_early = omap_h4_init_early, - .init_irq = omap_h4_init_irq, - .init_machine = omap_h4_init, - .timer = &omap_timer, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-igep0020.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-igep0020.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-igep0020.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-igep0020.c 2011-03-09 13:19:09.796507904 +0100 -@@ -250,7 +250,7 @@ - #endif - - static struct regulator_consumer_supply igep2_vmmc1_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); - - /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ - static struct regulator_init_data igep2_vmmc1 = { -@@ -268,7 +268,7 @@ - }; - - static struct regulator_consumer_supply igep2_vio_supply = -- REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"); - - static struct regulator_init_data igep2_vio = { - .constraints = { -@@ -286,7 +286,7 @@ - }; - - static struct regulator_consumer_supply igep2_vmmc2_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); - - static struct regulator_init_data igep2_vmmc2 = { - .constraints = { -@@ -485,17 +485,9 @@ - .default_device = &igep2_dvi_device, - }; - --static struct platform_device igep2_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &igep2_dss_data, -- }, --}; -- --static struct regulator_consumer_supply igep2_vpll2_supply = { -- .supply = "vdds_dsi", -- .dev = &igep2_dss_device.dev, -+static struct regulator_consumer_supply igep2_vpll2_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), - }; - - static struct regulator_init_data igep2_vpll2 = { -@@ -509,8 +501,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &igep2_vpll2_supply, -+ .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies), -+ .consumer_supplies = igep2_vpll2_supplies, - }; - - static void __init igep2_display_init(void) -@@ -521,21 +513,17 @@ - } - - static struct platform_device *igep2_devices[] __initdata = { -- &igep2_dss_device, - &igep2_vwlan_device, - }; - --static void __init igep2_init_irq(void) -+static void __init igep2_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(m65kxxxxam_sdrc_params, - m65kxxxxam_sdrc_params); -- omap_init_irq(); - } - --static struct twl4030_codec_audio_data igep2_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data igep2_audio_data; - - static struct twl4030_codec_data igep2_codec_data = { - .audio_mclk = 26000000, -@@ -697,6 +685,7 @@ - /* Register I2C busses and drivers */ - igep2_i2c_init(); - platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices)); -+ omap_display_init(&igep2_dss_data); - omap_serial_init(); - usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); -@@ -716,9 +705,10 @@ - - MACHINE_START(IGEP0020, "IGEP v2 board") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = igep2_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = igep2_init_early, -+ .init_irq = omap_init_irq, - .init_machine = igep2_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-igep0030.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-igep0030.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-igep0030.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-igep0030.c 2011-03-09 13:19:09.797507884 +0100 -@@ -142,7 +142,7 @@ - #endif - - static struct regulator_consumer_supply igep3_vmmc1_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); - - /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ - static struct regulator_init_data igep3_vmmc1 = { -@@ -160,7 +160,7 @@ - }; - - static struct regulator_consumer_supply igep3_vio_supply = -- REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"); - - static struct regulator_init_data igep3_vio = { - .constraints = { -@@ -178,7 +178,7 @@ - }; - - static struct regulator_consumer_supply igep3_vmmc2_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); - - static struct regulator_init_data igep3_vmmc2 = { - .constraints = { -@@ -331,12 +331,11 @@ - &igep3_vwlan_device, - }; - --static void __init igep3_init_irq(void) -+static void __init igep3_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(m65kxxxxam_sdrc_params, - m65kxxxxam_sdrc_params); -- omap_init_irq(); - } - - static struct twl4030_platform_data igep3_twl4030_pdata = { -@@ -452,7 +451,8 @@ - .boot_params = 0x80000100, - .reserve = omap_reserve, - .map_io = omap3_map_io, -- .init_irq = igep3_init_irq, -+ .init_early = igep3_init_early, -+ .init_irq = omap_init_irq, - .init_machine = igep3_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-ldp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-ldp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-ldp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-ldp.c 2011-03-09 13:19:09.797507884 +0100 -@@ -288,13 +288,10 @@ - { OMAP_TAG_LCD, &ldp_lcd_config }, - }; - --static void __init omap_ldp_init_irq(void) -+static void __init omap_ldp_init_early(void) - { -- omap_board_config = ldp_config; -- omap_board_config_size = ARRAY_SIZE(ldp_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - static struct twl4030_usb_data ldp_usb_data = { -@@ -330,6 +327,26 @@ - .consumer_supplies = &ldp_vmmc1_supply, - }; - -+/* ads7846 on SPI */ -+static struct regulator_consumer_supply ldp_vaux1_supplies[] = { -+ REGULATOR_SUPPLY("vcc", "spi1.0"), -+}; -+ -+/* VAUX1 */ -+static struct regulator_init_data ldp_vaux1 = { -+ .constraints = { -+ .min_uV = 3000000, -+ .max_uV = 3000000, -+ .apply_uV = true, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = ARRAY_SIZE(ldp_vaux1_supplies), -+ .consumer_supplies = ldp_vaux1_supplies, -+}; -+ - static struct twl4030_platform_data ldp_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, -@@ -338,6 +355,7 @@ - .madc = &ldp_madc_data, - .usb = &ldp_usb_data, - .vmmc1 = &ldp_vmmc1, -+ .vaux1 = &ldp_vaux1, - .gpio = &ldp_gpio_data, - .keypad = &ldp_kp_twl4030_data, - }; -@@ -423,6 +441,8 @@ - static void __init omap_ldp_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -+ omap_board_config = ldp_config; -+ omap_board_config_size = ARRAY_SIZE(ldp_config); - ldp_init_smsc911x(); - omap_i2c_init(); - platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices)); -@@ -434,7 +454,7 @@ - omap_serial_init(); - usb_musb_init(&musb_board_data); - board_nand_init(ldp_nand_partitions, -- ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS); -+ ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0); - - omap2_hsmmc_init(mmc); - /* link regulators to MMC adapters */ -@@ -443,9 +463,10 @@ - - MACHINE_START(OMAP_LDP, "OMAP LDP board") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap_ldp_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap_ldp_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_ldp_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-n8x0.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-n8x0.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-n8x0.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-n8x0.c 2011-03-09 13:19:09.797507884 +0100 -@@ -536,7 +536,7 @@ - } - - mmc_data[0] = &mmc1_data; -- omap2_init_mmc(mmc_data, OMAP24XX_NR_MMC); -+ omap242x_init_mmc(mmc_data); - } - #else - -@@ -628,11 +628,10 @@ - omap242x_map_common_io(); - } - --static void __init n8x0_init_irq(void) -+static void __init n8x0_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - #ifdef CONFIG_OMAP_MUX -@@ -703,27 +702,30 @@ - - MACHINE_START(NOKIA_N800, "Nokia N800") - .boot_params = 0x80000100, -- .map_io = n8x0_map_io, - .reserve = omap_reserve, -- .init_irq = n8x0_init_irq, -+ .map_io = n8x0_map_io, -+ .init_early = n8x0_init_early, -+ .init_irq = omap_init_irq, - .init_machine = n8x0_init_machine, - .timer = &omap_timer, - MACHINE_END - - MACHINE_START(NOKIA_N810, "Nokia N810") - .boot_params = 0x80000100, -- .map_io = n8x0_map_io, - .reserve = omap_reserve, -- .init_irq = n8x0_init_irq, -+ .map_io = n8x0_map_io, -+ .init_early = n8x0_init_early, -+ .init_irq = omap_init_irq, - .init_machine = n8x0_init_machine, - .timer = &omap_timer, - MACHINE_END - - MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX") - .boot_params = 0x80000100, -- .map_io = n8x0_map_io, - .reserve = omap_reserve, -- .init_irq = n8x0_init_irq, -+ .map_io = n8x0_map_io, -+ .init_early = n8x0_init_early, -+ .init_irq = omap_init_irq, - .init_machine = n8x0_init_machine, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3beagle.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3beagle.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3beagle.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3beagle.c 2011-03-09 13:19:09.797507884 +0100 -@@ -228,19 +228,13 @@ - .default_device = &beagle_dvi_device, - }; - --static struct platform_device beagle_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &beagle_dss_data, -- }, --}; -- - static struct regulator_consumer_supply beagle_vdac_supply = -- REGULATOR_SUPPLY("vdda_dac", "omapdss"); -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - --static struct regulator_consumer_supply beagle_vdvi_supply = -- REGULATOR_SUPPLY("vdds_dsi", "omapdss"); -+static struct regulator_consumer_supply beagle_vdvi_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; - - static void __init beagle_display_init(void) - { -@@ -427,17 +421,15 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &beagle_vdvi_supply, -+ .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies), -+ .consumer_supplies = beagle_vdvi_supplies, - }; - - static struct twl4030_usb_data beagle_usb_data = { - .usb_mode = T2_USB_MODE_ULPI, - }; - --static struct twl4030_codec_audio_data beagle_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data beagle_audio_data; - - static struct twl4030_codec_data beagle_codec_data = { - .audio_mclk = 26000000, -@@ -536,11 +528,15 @@ - }, - }; - --static void __init omap3_beagle_init_irq(void) -+static void __init omap3_beagle_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -+} -+ -+static void __init omap3_beagle_init_irq(void) -+{ - omap_init_irq(); - #ifdef CONFIG_OMAP_32K_TIMER - omap2_gp_clockevent_set_gptimer(12); -@@ -550,7 +546,6 @@ - static struct platform_device *omap3_beagle_devices[] __initdata = { - &leds_gpio, - &keys_gpio, -- &beagle_dss_device, - }; - - static void __init omap3beagle_flash_init(void) -@@ -617,6 +612,7 @@ - omap3_beagle_i2c_init(); - platform_add_devices(omap3_beagle_devices, - ARRAY_SIZE(omap3_beagle_devices)); -+ omap_display_init(&beagle_dss_data); - omap_serial_init(); - - omap_mux_init_gpio(170, OMAP_PIN_INPUT); -@@ -638,8 +634,9 @@ - MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board") - /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */ - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -+ .map_io = omap3_map_io, -+ .init_early = omap3_beagle_init_early, - .init_irq = omap3_beagle_init_irq, - .init_machine = omap3_beagle_init, - .timer = &omap_timer, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3evm.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3evm.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3evm.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3evm.c 2011-03-09 13:19:09.798507865 +0100 -@@ -30,6 +30,8 @@ - #include - #include - -+#include -+#include - #include - #include - -@@ -58,6 +60,13 @@ - #define OMAP3EVM_ETHR_ID_REV 0x50 - #define OMAP3EVM_ETHR_GPIO_IRQ 176 - #define OMAP3EVM_SMSC911X_CS 5 -+/* -+ * Eth Reset signal -+ * 64 = Generation 1 (<=RevD) -+ * 7 = Generation 2 (>=RevE) -+ */ -+#define OMAP3EVM_GEN1_ETHR_GPIO_RST 64 -+#define OMAP3EVM_GEN2_ETHR_GPIO_RST 7 - - static u8 omap3_evm_version; - -@@ -124,10 +133,15 @@ - - static inline void __init omap3evm_init_smsc911x(void) - { -- int eth_cs; -+ int eth_cs, eth_rst; - struct clk *l3ck; - unsigned int rate; - -+ if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1) -+ eth_rst = OMAP3EVM_GEN1_ETHR_GPIO_RST; -+ else -+ eth_rst = OMAP3EVM_GEN2_ETHR_GPIO_RST; -+ - eth_cs = OMAP3EVM_SMSC911X_CS; - - l3ck = clk_get(NULL, "l3_ck"); -@@ -136,6 +150,27 @@ - else - rate = clk_get_rate(l3ck); - -+ /* Configure ethernet controller reset gpio */ -+ if (cpu_is_omap3430()) { -+ if (gpio_request(eth_rst, "SMSC911x gpio") < 0) { -+ pr_err(KERN_ERR "Failed to request %d for smsc911x\n", -+ eth_rst); -+ return; -+ } -+ -+ if (gpio_direction_output(eth_rst, 1) < 0) { -+ pr_err(KERN_ERR "Failed to set direction of %d for" \ -+ " smsc911x\n", eth_rst); -+ return; -+ } -+ /* reset pulse to ethernet controller*/ -+ usleep_range(150, 220); -+ gpio_set_value(eth_rst, 0); -+ usleep_range(150, 220); -+ gpio_set_value(eth_rst, 1); -+ usleep_range(1, 2); -+ } -+ - if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) { - printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", - OMAP3EVM_ETHR_GPIO_IRQ); -@@ -235,9 +270,9 @@ - gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 0); - - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) -- gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); -+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); - else -- gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); -+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); - - lcd_enabled = 1; - return 0; -@@ -248,9 +283,9 @@ - gpio_set_value(OMAP3EVM_LCD_PANEL_ENVDD, 1); - - if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) -- gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); -+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 1); - else -- gpio_set_value(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); -+ gpio_set_value_cansleep(OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO, 0); - - lcd_enabled = 0; - } -@@ -289,7 +324,7 @@ - return -EINVAL; - } - -- gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 1); -+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 1); - - dvi_enabled = 1; - return 0; -@@ -297,7 +332,7 @@ - - static void omap3_evm_disable_dvi(struct omap_dss_device *dssdev) - { -- gpio_set_value(OMAP3EVM_DVI_PANEL_EN_GPIO, 0); -+ gpio_set_value_cansleep(OMAP3EVM_DVI_PANEL_EN_GPIO, 0); - - dvi_enabled = 0; - } -@@ -328,14 +363,6 @@ - .default_device = &omap3_evm_lcd_device, - }; - --static struct platform_device omap3_evm_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &omap3_evm_dss_data, -- }, --}; -- - static struct regulator_consumer_supply omap3evm_vmmc1_supply = { - .supply = "vmmc", - }; -@@ -381,6 +408,16 @@ - .gpio_cd = -EINVAL, - .gpio_wp = 63, - }, -+#ifdef CONFIG_WL12XX_PLATFORM_DATA -+ { -+ .name = "wl1271", -+ .mmc = 2, -+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, -+ .gpio_wp = -EINVAL, -+ .gpio_cd = -EINVAL, -+ .nonremovable = true, -+ }, -+#endif - {} /* Terminator */ - }; - -@@ -411,6 +448,8 @@ - static int omap3evm_twl_gpio_setup(struct device *dev, - unsigned gpio, unsigned ngpio) - { -+ int r; -+ - /* gpio + 0 is "mmc0_cd" (input/IRQ) */ - omap_mux_init_gpio(63, OMAP_PIN_INPUT); - mmc[0].gpio_cd = gpio + 0; -@@ -426,8 +465,12 @@ - */ - - /* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */ -- gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); -- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); -+ r = gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL"); -+ if (!r) -+ r = gpio_direction_output(gpio + TWL4030_GPIO_MAX, -+ (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) ? 1 : 0); -+ if (r) -+ printk(KERN_ERR "failed to get/set lcd_bkl gpio\n"); - - /* gpio + 7 == DVI Enable */ - gpio_request(gpio + 7, "EN_DVI"); -@@ -491,19 +534,15 @@ - .irq_line = 1, - }; - --static struct twl4030_codec_audio_data omap3evm_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data omap3evm_audio_data; - - static struct twl4030_codec_data omap3evm_codec_data = { - .audio_mclk = 26000000, - .audio = &omap3evm_audio_data, - }; - --static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = { -- .supply = "vdda_dac", -- .dev = &omap3_evm_dss_device.dev, --}; -+static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - - /* VDAC for DSS driving S-Video */ - static struct regulator_init_data omap3_evm_vdac = { -@@ -521,8 +560,10 @@ - }; - - /* VPLL2 for digital video outputs */ --static struct regulator_consumer_supply omap3_evm_vpll2_supply = -- REGULATOR_SUPPLY("vdds_dsi", "omapdss"); -+static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; - - static struct regulator_init_data omap3_evm_vpll2 = { - .constraints = { -@@ -534,10 +575,70 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -+ .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies), -+ .consumer_supplies = omap3_evm_vpll2_supplies, -+}; -+ -+/* ads7846 on SPI */ -+static struct regulator_consumer_supply omap3evm_vio_supply = -+ REGULATOR_SUPPLY("vcc", "spi1.0"); -+ -+/* VIO for ads7846 */ -+static struct regulator_init_data omap3evm_vio = { -+ .constraints = { -+ .min_uV = 1800000, -+ .max_uV = 1800000, -+ .apply_uV = true, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, - .num_consumer_supplies = 1, -- .consumer_supplies = &omap3_evm_vpll2_supply, -+ .consumer_supplies = &omap3evm_vio_supply, - }; - -+#ifdef CONFIG_WL12XX_PLATFORM_DATA -+ -+#define OMAP3EVM_WLAN_PMENA_GPIO (150) -+#define OMAP3EVM_WLAN_IRQ_GPIO (149) -+ -+static struct regulator_consumer_supply omap3evm_vmmc2_supply = -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); -+ -+/* VMMC2 for driving the WL12xx module */ -+static struct regulator_init_data omap3evm_vmmc2 = { -+ .constraints = { -+ .valid_ops_mask = REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &omap3evm_vmmc2_supply, -+}; -+ -+static struct fixed_voltage_config omap3evm_vwlan = { -+ .supply_name = "vwl1271", -+ .microvolts = 1800000, /* 1.80V */ -+ .gpio = OMAP3EVM_WLAN_PMENA_GPIO, -+ .startup_delay = 70000, /* 70ms */ -+ .enable_high = 1, -+ .enabled_at_boot = 0, -+ .init_data = &omap3evm_vmmc2, -+}; -+ -+static struct platform_device omap3evm_wlan_regulator = { -+ .name = "reg-fixed-voltage", -+ .id = 1, -+ .dev = { -+ .platform_data = &omap3evm_vwlan, -+ }, -+}; -+ -+struct wl12xx_platform_data omap3evm_wlan_data __initdata = { -+ .irq = OMAP_GPIO_IRQ(OMAP3EVM_WLAN_IRQ_GPIO), -+ .board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */ -+}; -+#endif -+ - static struct twl4030_platform_data omap3evm_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, -@@ -550,6 +651,7 @@ - .codec = &omap3evm_codec_data, - .vdac = &omap3_evm_vdac, - .vpll2 = &omap3_evm_vpll2, -+ .vio = &omap3evm_vio, - }; - - static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = { -@@ -625,19 +727,12 @@ - static struct omap_board_config_kernel omap3_evm_config[] __initdata = { - }; - --static void __init omap3_evm_init_irq(void) -+static void __init omap3_evm_init_early(void) - { -- omap_board_config = omap3_evm_config; -- omap_board_config_size = ARRAY_SIZE(omap3_evm_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL); -- omap_init_irq(); - } - --static struct platform_device *omap3_evm_devices[] __initdata = { -- &omap3_evm_dss_device, --}; -- - static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = { - - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, -@@ -652,14 +747,76 @@ - }; - - #ifdef CONFIG_OMAP_MUX --static struct omap_board_mux board_mux[] __initdata = { -+static struct omap_board_mux omap35x_board_mux[] __initdata = { -+ OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | -+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | -+ OMAP_PIN_OFF_WAKEUPENABLE), -+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | -+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | -+ OMAP_PIN_OFF_WAKEUPENABLE), -+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | -+ OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(GPMC_WAIT2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | -+ OMAP_PIN_OFF_NONE), -+#ifdef CONFIG_WL12XX_PLATFORM_DATA -+ /* WLAN IRQ - GPIO 149 */ -+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), -+ -+ /* WLAN POWER ENABLE - GPIO 150 */ -+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), -+ -+ /* MMC2 SDIO pin muxes for WL12xx */ -+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+#endif -+ { .reg_offset = OMAP_MUX_TERMINATOR }, -+}; -+ -+static struct omap_board_mux omap36x_board_mux[] __initdata = { - OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP | - OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | - OMAP_PIN_OFF_WAKEUPENABLE), - OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP | -- OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW), -+ OMAP_PIN_OFF_INPUT_PULLUP | OMAP_PIN_OFF_OUTPUT_LOW | -+ OMAP_PIN_OFF_WAKEUPENABLE), -+ /* AM/DM37x EVM: DSS data bus muxed with sys_boot */ -+ OMAP3_MUX(DSS_DATA18, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(DSS_DATA19, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(DSS_DATA21, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(DSS_DATA22, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(DSS_DATA23, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT0, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT1, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT3, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT4, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT5, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+ OMAP3_MUX(SYS_BOOT6, OMAP_MUX_MODE3 | OMAP_PIN_OFF_NONE), -+#ifdef CONFIG_WL12XX_PLATFORM_DATA -+ /* WLAN IRQ - GPIO 149 */ -+ OMAP3_MUX(UART1_RTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), -+ -+ /* WLAN POWER ENABLE - GPIO 150 */ -+ OMAP3_MUX(UART1_CTS, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), -+ -+ /* MMC2 SDIO pin muxes for WL12xx */ -+ OMAP3_MUX(SDMMC2_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP3_MUX(SDMMC2_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+#endif -+ - { .reg_offset = OMAP_MUX_TERMINATOR }, - }; -+#else -+#define omap35x_board_mux NULL -+#define omap36x_board_mux NULL - #endif - - static struct omap_musb_board_data musb_board_data = { -@@ -671,11 +828,18 @@ - static void __init omap3_evm_init(void) - { - omap3_evm_get_revision(); -- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -+ -+ if (cpu_is_omap3630()) -+ omap3_mux_init(omap36x_board_mux, OMAP_PACKAGE_CBB); -+ else -+ omap3_mux_init(omap35x_board_mux, OMAP_PACKAGE_CBB); -+ -+ omap_board_config = omap3_evm_config; -+ omap_board_config_size = ARRAY_SIZE(omap3_evm_config); - - omap3_evm_i2c_init(); - -- platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices)); -+ omap_display_init(&omap3_evm_dss_data); - - spi_register_board_info(omap3evm_spi_board_info, - ARRAY_SIZE(omap3evm_spi_board_info)); -@@ -715,14 +879,22 @@ - ads7846_dev_init(); - omap3evm_init_smsc911x(); - omap3_evm_display_init(); -+ -+#ifdef CONFIG_WL12XX_PLATFORM_DATA -+ /* WL12xx WLAN Init */ -+ if (wl12xx_set_platform_data(&omap3evm_wlan_data)) -+ pr_err("error setting wl12xx data\n"); -+ platform_device_register(&omap3evm_wlan_regulator); -+#endif - } - - MACHINE_START(OMAP3EVM, "OMAP3 EVM") - /* Maintainer: Syed Mohammed Khasim - Texas Instruments */ - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap3_evm_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap3_evm_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap3_evm_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3logic.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3logic.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3logic.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3logic.c 2011-03-09 13:19:09.798507865 +0100 -@@ -195,11 +195,10 @@ - gpmc_smsc911x_init(&board_smsc911x_data); - } - --static void __init omap3logic_init_irq(void) -+static void __init omap3logic_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- omap_init_irq(); - } - - #ifdef CONFIG_OMAP_MUX -@@ -225,7 +224,8 @@ - MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board") - .boot_params = 0x80000100, - .map_io = omap3_map_io, -- .init_irq = omap3logic_init_irq, -+ .init_early = omap3logic_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap3logic_init, - .timer = &omap_timer, - MACHINE_END -@@ -233,7 +233,8 @@ - MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board") - .boot_params = 0x80000100, - .map_io = omap3_map_io, -- .init_irq = omap3logic_init_irq, -+ .init_early = omap3logic_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap3logic_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3pandora.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3pandora.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3pandora.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3pandora.c 2011-03-09 13:19:09.798507865 +0100 -@@ -253,14 +253,6 @@ - .default_device = &pandora_lcd_device, - }; - --static struct platform_device pandora_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &pandora_dss_data, -- }, --}; -- - static void pandora_wl1251_init_card(struct mmc_card *card) - { - /* -@@ -341,20 +333,21 @@ - }; - - static struct regulator_consumer_supply pandora_vmmc1_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); - - static struct regulator_consumer_supply pandora_vmmc2_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); - - static struct regulator_consumer_supply pandora_vmmc3_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.2"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.2"); - - static struct regulator_consumer_supply pandora_vdda_dac_supply = -- REGULATOR_SUPPLY("vdda_dac", "omapdss"); -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - - static struct regulator_consumer_supply pandora_vdds_supplies[] = { - REGULATOR_SUPPLY("vdds_sdi", "omapdss"), - REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), - }; - - static struct regulator_consumer_supply pandora_vcc_lcd_supply = -@@ -524,9 +517,7 @@ - .usb_mode = T2_USB_MODE_ULPI, - }; - --static struct twl4030_codec_audio_data omap3pandora_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data omap3pandora_audio_data; - - static struct twl4030_codec_data omap3pandora_codec_data = { - .audio_mclk = 26000000, -@@ -634,12 +625,11 @@ - } - }; - --static void __init omap3pandora_init_irq(void) -+static void __init omap3pandora_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -- omap_init_irq(); - } - - static void __init pandora_wl1251_init(void) -@@ -677,7 +667,6 @@ - static struct platform_device *omap3pandora_devices[] __initdata = { - &pandora_leds_gpio, - &pandora_keys_gpio, -- &pandora_dss_device, - &pandora_vwlan_device, - }; - -@@ -712,6 +701,7 @@ - pandora_wl1251_init(); - platform_add_devices(omap3pandora_devices, - ARRAY_SIZE(omap3pandora_devices)); -+ omap_display_init(&pandora_dss_data); - omap_serial_init(); - spi_register_board_info(omap3pandora_spi_board_info, - ARRAY_SIZE(omap3pandora_spi_board_info)); -@@ -727,9 +717,10 @@ - - MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap3pandora_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap3pandora_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap3pandora_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3stalker.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3stalker.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3stalker.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3stalker.c 2011-03-09 13:19:09.799507845 +0100 -@@ -240,14 +240,6 @@ - .default_device = &omap3_stalker_dvi_device, - }; - --static struct platform_device omap3_stalker_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &omap3_stalker_dss_data, -- }, --}; -- - static struct regulator_consumer_supply omap3stalker_vmmc1_supply = { - .supply = "vmmc", - }; -@@ -439,19 +431,15 @@ - .irq_line = 1, - }; - --static struct twl4030_codec_audio_data omap3stalker_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data omap3stalker_audio_data; - - static struct twl4030_codec_data omap3stalker_codec_data = { - .audio_mclk = 26000000, - .audio = &omap3stalker_audio_data, - }; - --static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = { -- .supply = "vdda_dac", -- .dev = &omap3_stalker_dss_device.dev, --}; -+static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - - /* VDAC for DSS driving S-Video */ - static struct regulator_init_data omap3_stalker_vdac = { -@@ -469,9 +457,9 @@ - }; - - /* VPLL2 for digital video outputs */ --static struct regulator_consumer_supply omap3_stalker_vpll2_supply = { -- .supply = "vdds_dsi", -- .dev = &omap3_stalker_lcd_device.dev, -+static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), - }; - - static struct regulator_init_data omap3_stalker_vpll2 = { -@@ -485,8 +473,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &omap3_stalker_vpll2_supply, -+ .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies), -+ .consumer_supplies = omap3_stalker_vpll2_supplies, - }; - - static struct twl4030_platform_data omap3stalker_twldata = { -@@ -591,12 +579,14 @@ - static struct omap_board_config_kernel omap3_stalker_config[] __initdata = { - }; - --static void __init omap3_stalker_init_irq(void) -+static void __init omap3_stalker_init_early(void) - { -- omap_board_config = omap3_stalker_config; -- omap_board_config_size = ARRAY_SIZE(omap3_stalker_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL); -+} -+ -+static void __init omap3_stalker_init_irq(void) -+{ - omap_init_irq(); - #ifdef CONFIG_OMAP_32K_TIMER - omap2_gp_clockevent_set_gptimer(12); -@@ -604,7 +594,6 @@ - } - - static struct platform_device *omap3_stalker_devices[] __initdata = { -- &omap3_stalker_dss_device, - &keys_gpio, - }; - -@@ -638,12 +627,15 @@ - static void __init omap3_stalker_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CUS); -+ omap_board_config = omap3_stalker_config; -+ omap_board_config_size = ARRAY_SIZE(omap3_stalker_config); - - omap3_stalker_i2c_init(); - - platform_add_devices(omap3_stalker_devices, - ARRAY_SIZE(omap3_stalker_devices)); - -+ omap_display_init(&omap3_stalker_dss_data); - spi_register_board_info(omap3stalker_spi_board_info, - ARRAY_SIZE(omap3stalker_spi_board_info)); - -@@ -666,6 +658,7 @@ - /* Maintainer: Jason Lam -lzg@ema-tech.com */ - .boot_params = 0x80000100, - .map_io = omap3_map_io, -+ .init_early = omap3_stalker_init_early, - .init_irq = omap3_stalker_init_irq, - .init_machine = omap3_stalker_init, - .timer = &omap_timer, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3touchbook.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3touchbook.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap3touchbook.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap3touchbook.c 2011-03-09 13:19:09.799507845 +0100 -@@ -252,9 +252,7 @@ - .usb_mode = T2_USB_MODE_ULPI, - }; - --static struct twl4030_codec_audio_data touchbook_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data touchbook_audio_data; - - static struct twl4030_codec_data touchbook_codec_data = { - .audio_mclk = 26000000, -@@ -415,14 +413,15 @@ - }; - #endif - --static void __init omap3_touchbook_init_irq(void) -+static void __init omap3_touchbook_init_early(void) - { -- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -- omap_board_config = omap3_touchbook_config; -- omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -+} -+ -+static void __init omap3_touchbook_init_irq(void) -+{ - omap_init_irq(); - #ifdef CONFIG_OMAP_32K_TIMER - omap2_gp_clockevent_set_gptimer(12); -@@ -510,6 +509,10 @@ - - static void __init omap3_touchbook_init(void) - { -+ omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -+ omap_board_config = omap3_touchbook_config; -+ omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config); -+ - pm_power_off = omap3_touchbook_poweroff; - - omap3_touchbook_i2c_init(); -@@ -538,8 +541,9 @@ - MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board") - /* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */ - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -+ .map_io = omap3_map_io, -+ .init_early = omap3_touchbook_init_early, - .init_irq = omap3_touchbook_init_irq, - .init_machine = omap3_touchbook_init, - .timer = &omap_timer, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap4panda.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap4panda.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-omap4panda.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-omap4panda.c 2011-03-09 13:19:09.799507845 +0100 -@@ -26,6 +26,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -45,6 +47,18 @@ - - #define GPIO_HUB_POWER 1 - #define GPIO_HUB_NRESET 62 -+#define GPIO_WIFI_PMENA 43 -+#define GPIO_WIFI_IRQ 53 -+ -+/* wl127x BT, FM, GPS connectivity chip */ -+static int wl1271_gpios[] = {46, -1, -1}; -+static struct platform_device wl1271_device = { -+ .name = "kim", -+ .id = -1, -+ .dev = { -+ .platform_data = &wl1271_gpios, -+ }, -+}; - - static struct gpio_led gpio_leds[] = { - { -@@ -74,13 +88,13 @@ - - static struct platform_device *panda_devices[] __initdata = { - &leds_gpio, -+ &wl1271_device, - }; - --static void __init omap4_panda_init_irq(void) -+static void __init omap4_panda_init_early(void) - { - omap2_init_common_infrastructure(); - omap2_init_common_devices(NULL, NULL); -- gic_init_irq(); - } - - static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { -@@ -162,16 +176,62 @@ - .gpio_wp = -EINVAL, - .gpio_cd = -EINVAL, - }, -+ { -+ .name = "wl1271", -+ .mmc = 5, -+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, -+ .gpio_wp = -EINVAL, -+ .gpio_cd = -EINVAL, -+ .ocr_mask = MMC_VDD_165_195, -+ .nonremovable = true, -+ }, - {} /* Terminator */ - }; - - static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = { - { - .supply = "vmmc", -- .dev_name = "mmci-omap-hs.0", -+ .dev_name = "omap_hsmmc.0", -+ }, -+}; -+ -+static struct regulator_consumer_supply omap4_panda_vmmc5_supply = { -+ .supply = "vmmc", -+ .dev_name = "omap_hsmmc.4", -+}; -+ -+static struct regulator_init_data panda_vmmc5 = { -+ .constraints = { -+ .valid_ops_mask = REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &omap4_panda_vmmc5_supply, -+}; -+ -+static struct fixed_voltage_config panda_vwlan = { -+ .supply_name = "vwl1271", -+ .microvolts = 1800000, /* 1.8V */ -+ .gpio = GPIO_WIFI_PMENA, -+ .startup_delay = 70000, /* 70msec */ -+ .enable_high = 1, -+ .enabled_at_boot = 0, -+ .init_data = &panda_vmmc5, -+}; -+ -+static struct platform_device omap_vwlan_device = { -+ .name = "reg-fixed-voltage", -+ .id = 1, -+ .dev = { -+ .platform_data = &panda_vwlan, - }, - }; - -+struct wl12xx_platform_data omap_panda_wlan_data __initdata = { -+ .irq = OMAP_GPIO_IRQ(GPIO_WIFI_IRQ), -+ /* PANDA ref clock is 38.4 MHz */ -+ .board_ref_clock = 2, -+}; -+ - static int omap4_twl6030_hsmmc_late_init(struct device *dev) - { - int ret = 0; -@@ -305,7 +365,6 @@ - .constraints = { - .min_uV = 2100000, - .max_uV = 2100000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -317,7 +376,6 @@ - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -329,7 +387,6 @@ - .constraints = { - .min_uV = 1800000, - .max_uV = 1800000, -- .apply_uV = true, - .valid_modes_mask = REGULATOR_MODE_NORMAL - | REGULATOR_MODE_STANDBY, - .valid_ops_mask = REGULATOR_CHANGE_MODE -@@ -391,6 +448,19 @@ - - #ifdef CONFIG_OMAP_MUX - static struct omap_board_mux board_mux[] __initdata = { -+ /* WLAN IRQ - GPIO 53 */ -+ OMAP4_MUX(GPMC_NCS3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT), -+ /* WLAN POWER ENABLE - GPIO 43 */ -+ OMAP4_MUX(GPMC_A19, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT), -+ /* WLAN SDIO: MMC5 CMD */ -+ OMAP4_MUX(SDMMC5_CMD, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ /* WLAN SDIO: MMC5 CLK */ -+ OMAP4_MUX(SDMMC5_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ /* WLAN SDIO: MMC5 DAT[0-3] */ -+ OMAP4_MUX(SDMMC5_DAT0, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP4_MUX(SDMMC5_DAT1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP4_MUX(SDMMC5_DAT2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), -+ OMAP4_MUX(SDMMC5_DAT3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP), - { .reg_offset = OMAP_MUX_TERMINATOR }, - }; - #else -@@ -405,8 +475,12 @@ - package = OMAP_PACKAGE_CBL; - omap4_mux_init(board_mux, package); - -+ if (wl12xx_set_platform_data(&omap_panda_wlan_data)) -+ pr_err("error setting wl12xx data\n"); -+ - omap4_panda_i2c_init(); - platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices)); -+ platform_device_register(&omap_vwlan_device); - omap_serial_init(); - omap4_twl6030_hsmmc_init(mmc); - omap4_ehci_init(); -@@ -424,7 +498,8 @@ - .boot_params = 0x80000100, - .reserve = omap_reserve, - .map_io = omap4_panda_map_io, -- .init_irq = omap4_panda_init_irq, -+ .init_early = omap4_panda_init_early, -+ .init_irq = gic_init_irq, - .init_machine = omap4_panda_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-overo.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-overo.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-overo.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-overo.c 2011-03-09 13:19:09.799507845 +0100 -@@ -28,6 +28,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -41,10 +43,14 @@ - - #include - #include -+#include -+#include - #include - #include - #include - #include -+#include -+#include - #include - - #include "mux.h" -@@ -68,8 +74,6 @@ - #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ - defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - --#include --#include - #include - - static struct omap2_mcspi_device_config ads7846_mcspi_config = { -@@ -94,16 +98,32 @@ - .keep_vref_on = 1, - }; - --static struct spi_board_info overo_spi_board_info[] __initdata = { -- { -- .modalias = "ads7846", -- .bus_num = 1, -- .chip_select = 0, -- .max_speed_hz = 1500000, -- .controller_data = &ads7846_mcspi_config, -- .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), -- .platform_data = &ads7846_config, -- } -+/* fixed regulator for ads7846 */ -+static struct regulator_consumer_supply ads7846_supply = -+ REGULATOR_SUPPLY("vcc", "spi1.0"); -+ -+static struct regulator_init_data vads7846_regulator = { -+ .constraints = { -+ .valid_ops_mask = REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &ads7846_supply, -+}; -+ -+static struct fixed_voltage_config vads7846 = { -+ .supply_name = "vads7846", -+ .microvolts = 3300000, /* 3.3V */ -+ .gpio = -EINVAL, -+ .startup_delay = 0, -+ .init_data = &vads7846_regulator, -+}; -+ -+static struct platform_device vads7846_device = { -+ .name = "reg-fixed-voltage", -+ .id = 1, -+ .dev = { -+ .platform_data = &vads7846, -+ }, - }; - - static void __init overo_ads7846_init(void) -@@ -116,8 +136,7 @@ - return; - } - -- spi_register_board_info(overo_spi_board_info, -- ARRAY_SIZE(overo_spi_board_info)); -+ platform_device_register(&vads7846_device); - } - - #else -@@ -233,6 +252,137 @@ - static inline void __init overo_init_smsc911x(void) { return; } - #endif - -+/* DSS */ -+static int lcd_enabled; -+static int dvi_enabled; -+ -+#define OVERO_GPIO_LCD_EN 144 -+#define OVERO_GPIO_LCD_BL 145 -+ -+static void __init overo_display_init(void) -+{ -+ if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) && -+ (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0)) -+ gpio_export(OVERO_GPIO_LCD_EN, 0); -+ else -+ printk(KERN_ERR "could not obtain gpio for " -+ "OVERO_GPIO_LCD_EN\n"); -+ -+ if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) && -+ (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0)) -+ gpio_export(OVERO_GPIO_LCD_BL, 0); -+ else -+ printk(KERN_ERR "could not obtain gpio for " -+ "OVERO_GPIO_LCD_BL\n"); -+} -+ -+static int overo_panel_enable_dvi(struct omap_dss_device *dssdev) -+{ -+ if (lcd_enabled) { -+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n"); -+ return -EINVAL; -+ } -+ dvi_enabled = 1; -+ -+ return 0; -+} -+ -+static void overo_panel_disable_dvi(struct omap_dss_device *dssdev) -+{ -+ dvi_enabled = 0; -+} -+ -+static struct panel_generic_dpi_data dvi_panel = { -+ .name = "generic", -+ .platform_enable = overo_panel_enable_dvi, -+ .platform_disable = overo_panel_disable_dvi, -+}; -+ -+static struct omap_dss_device overo_dvi_device = { -+ .name = "dvi", -+ .type = OMAP_DISPLAY_TYPE_DPI, -+ .driver_name = "generic_dpi_panel", -+ .data = &dvi_panel, -+ .phy.dpi.data_lines = 24, -+}; -+ -+static struct omap_dss_device overo_tv_device = { -+ .name = "tv", -+ .driver_name = "venc", -+ .type = OMAP_DISPLAY_TYPE_VENC, -+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO, -+}; -+ -+static int overo_panel_enable_lcd(struct omap_dss_device *dssdev) -+{ -+ if (dvi_enabled) { -+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n"); -+ return -EINVAL; -+ } -+ -+ gpio_set_value(OVERO_GPIO_LCD_EN, 1); -+ gpio_set_value(OVERO_GPIO_LCD_BL, 1); -+ lcd_enabled = 1; -+ return 0; -+} -+ -+static void overo_panel_disable_lcd(struct omap_dss_device *dssdev) -+{ -+ gpio_set_value(OVERO_GPIO_LCD_EN, 0); -+ gpio_set_value(OVERO_GPIO_LCD_BL, 0); -+ lcd_enabled = 0; -+} -+ -+static struct panel_generic_dpi_data lcd43_panel = { -+ .name = "samsung_lte430wq_f0c", -+ .platform_enable = overo_panel_enable_lcd, -+ .platform_disable = overo_panel_disable_lcd, -+}; -+ -+static struct omap_dss_device overo_lcd43_device = { -+ .name = "lcd43", -+ .type = OMAP_DISPLAY_TYPE_DPI, -+ .driver_name = "generic_dpi_panel", -+ .data = &lcd43_panel, -+ .phy.dpi.data_lines = 24, -+}; -+ -+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ -+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) -+static struct omap_dss_device overo_lcd35_device = { -+ .type = OMAP_DISPLAY_TYPE_DPI, -+ .name = "lcd35", -+ .driver_name = "lgphilips_lb035q02_panel", -+ .phy.dpi.data_lines = 24, -+ .platform_enable = overo_panel_enable_lcd, -+ .platform_disable = overo_panel_disable_lcd, -+}; -+#endif -+ -+static struct omap_dss_device *overo_dss_devices[] = { -+ &overo_dvi_device, -+ &overo_tv_device, -+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ -+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) -+ &overo_lcd35_device, -+#endif -+ &overo_lcd43_device, -+}; -+ -+static struct omap_dss_board_info overo_dss_data = { -+ .num_devices = ARRAY_SIZE(overo_dss_devices), -+ .devices = overo_dss_devices, -+ .default_device = &overo_dvi_device, -+}; -+ -+static struct regulator_consumer_supply overo_vdda_dac_supply = -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); -+ -+static struct regulator_consumer_supply overo_vdds_dsi_supply[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; -+ - static struct mtd_partition overo_nand_partitions[] = { - { - .name = "xloader", -@@ -358,17 +508,42 @@ - .consumer_supplies = &overo_vmmc1_supply, - }; - --static struct twl4030_codec_audio_data overo_audio_data = { -- .audio_mclk = 26000000, -+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */ -+static struct regulator_init_data overo_vdac = { -+ .constraints = { -+ .min_uV = 1800000, -+ .max_uV = 1800000, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = 1, -+ .consumer_supplies = &overo_vdda_dac_supply, - }; - -+/* VPLL2 for digital video outputs */ -+static struct regulator_init_data overo_vpll2 = { -+ .constraints = { -+ .name = "VDVI", -+ .min_uV = 1800000, -+ .max_uV = 1800000, -+ .valid_modes_mask = REGULATOR_MODE_NORMAL -+ | REGULATOR_MODE_STANDBY, -+ .valid_ops_mask = REGULATOR_CHANGE_MODE -+ | REGULATOR_CHANGE_STATUS, -+ }, -+ .num_consumer_supplies = ARRAY_SIZE(overo_vdds_dsi_supply), -+ .consumer_supplies = overo_vdds_dsi_supply, -+}; -+ -+static struct twl4030_codec_audio_data overo_audio_data; -+ - static struct twl4030_codec_data overo_codec_data = { - .audio_mclk = 26000000, - .audio = &overo_audio_data, - }; - --/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */ -- - static struct twl4030_platform_data overo_twldata = { - .irq_base = TWL4030_IRQ_BASE, - .irq_end = TWL4030_IRQ_END, -@@ -376,6 +551,8 @@ - .usb = &overo_usb_data, - .codec = &overo_codec_data, - .vmmc1 = &overo_vmmc1, -+ .vdac = &overo_vdac, -+ .vpll2 = &overo_vpll2, - }; - - static struct i2c_board_info __initdata overo_i2c_boardinfo[] = { -@@ -396,33 +573,46 @@ - return 0; - } - --static struct platform_device overo_lcd_device = { -- .name = "overo_lcd", -- .id = -1, --}; -- --static struct omap_lcd_config overo_lcd_config __initdata = { -- .ctrl_name = "internal", -+static struct spi_board_info overo_spi_board_info[] __initdata = { -+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ -+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -+ { -+ .modalias = "ads7846", -+ .bus_num = 1, -+ .chip_select = 0, -+ .max_speed_hz = 1500000, -+ .controller_data = &ads7846_mcspi_config, -+ .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN), -+ .platform_data = &ads7846_config, -+ }, -+#endif -+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \ -+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE) -+ { -+ .modalias = "lgphilips_lb035q02_panel-spi", -+ .bus_num = 1, -+ .chip_select = 1, -+ .max_speed_hz = 500000, -+ .mode = SPI_MODE_3, -+ }, -+#endif - }; - --static struct omap_board_config_kernel overo_config[] __initdata = { -- { OMAP_TAG_LCD, &overo_lcd_config }, --}; -+static int __init overo_spi_init(void) -+{ -+ overo_ads7846_init(); -+ spi_register_board_info(overo_spi_board_info, -+ ARRAY_SIZE(overo_spi_board_info)); -+ return 0; -+} - --static void __init overo_init_irq(void) -+static void __init overo_init_early(void) - { -- omap_board_config = overo_config; -- omap_board_config_size = ARRAY_SIZE(overo_config); - omap2_init_common_infrastructure(); - omap2_init_common_devices(mt46h32m32lf6_sdrc_params, - mt46h32m32lf6_sdrc_params); -- omap_init_irq(); - } - --static struct platform_device *overo_devices[] __initdata = { -- &overo_lcd_device, --}; -- - static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { - .port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN, - .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY, -@@ -450,13 +640,14 @@ - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); - overo_i2c_init(); -- platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices)); -+ omap_display_init(&overo_dss_data); - omap_serial_init(); - overo_flash_init(); - usb_musb_init(&musb_board_data); - usb_ehci_init(&ehci_pdata); -- overo_ads7846_init(); -+ overo_spi_init(); - overo_init_smsc911x(); -+ overo_display_init(); - - /* Ensure SDRC pins are mux'd for self-refresh */ - omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT); -@@ -501,9 +692,10 @@ - - MACHINE_START(OVERO, "Gumstix Overo") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = overo_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = overo_init_early, -+ .init_irq = omap_init_irq, - .init_machine = overo_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-rm680.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rm680.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-rm680.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rm680.c 2011-03-09 13:19:09.800507825 +0100 -@@ -33,7 +33,7 @@ - #include "sdram-nokia.h" - - static struct regulator_consumer_supply rm680_vemmc_consumers[] = { -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"), -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), - }; - - /* Fixed regulator for internal eMMC */ -@@ -138,14 +138,13 @@ - omap2_hsmmc_init(mmc); - } - --static void __init rm680_init_irq(void) -+static void __init rm680_init_early(void) - { - struct omap_sdrc_params *sdrc_params; - - omap2_init_common_infrastructure(); - sdrc_params = nokia_get_sdram_timings(); - omap2_init_common_devices(sdrc_params, sdrc_params); -- omap_init_irq(); - } - - #ifdef CONFIG_OMAP_MUX -@@ -176,9 +175,10 @@ - - MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") - .boot_params = 0x80000100, -- .map_io = rm680_map_io, - .reserve = omap_reserve, -- .init_irq = rm680_init_irq, -+ .map_io = rm680_map_io, -+ .init_early = rm680_init_early, -+ .init_irq = omap_init_irq, - .init_machine = rm680_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51.c 2011-03-09 13:19:09.800507825 +0100 -@@ -98,17 +98,13 @@ - { OMAP_TAG_LCD, &rx51_lcd_config }, - }; - --static void __init rx51_init_irq(void) -+static void __init rx51_init_early(void) - { - struct omap_sdrc_params *sdrc_params; - -- omap_board_config = rx51_config; -- omap_board_config_size = ARRAY_SIZE(rx51_config); -- omap3_pm_init_cpuidle(rx51_cpuidle_params); - omap2_init_common_infrastructure(); - sdrc_params = nokia_get_sdram_timings(); - omap2_init_common_devices(sdrc_params, sdrc_params); -- omap_init_irq(); - } - - extern void __init rx51_peripherals_init(void); -@@ -128,6 +124,9 @@ - static void __init rx51_init(void) - { - omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); -+ omap_board_config = rx51_config; -+ omap_board_config_size = ARRAY_SIZE(rx51_config); -+ omap3_pm_init_cpuidle(rx51_cpuidle_params); - omap_serial_init(); - usb_musb_init(&musb_board_data); - rx51_peripherals_init(); -@@ -149,9 +148,10 @@ - MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") - /* Maintainer: Lauri Leukkunen */ - .boot_params = 0x80000100, -- .map_io = rx51_map_io, - .reserve = omap_reserve, -- .init_irq = rx51_init_irq, -+ .map_io = rx51_map_io, -+ .init_early = rx51_init_early, -+ .init_irq = omap_init_irq, - .init_machine = rx51_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51-peripherals.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51-peripherals.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51-peripherals.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51-peripherals.c 2011-03-09 13:19:09.800507825 +0100 -@@ -36,6 +36,8 @@ - - #include - #include -+#include -+#include - - #include <../drivers/staging/iio/light/tsl2563.h> - -@@ -47,6 +49,8 @@ - - #define RX51_WL1251_POWER_GPIO 87 - #define RX51_WL1251_IRQ_GPIO 42 -+#define RX51_FMTX_RESET_GPIO 163 -+#define RX51_FMTX_IRQ 53 - - /* list all spi devices here */ - enum { -@@ -331,13 +335,13 @@ - }; - - static struct regulator_consumer_supply rx51_vmmc1_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"); - - static struct regulator_consumer_supply rx51_vaux3_supply = -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"); - - static struct regulator_consumer_supply rx51_vsim_supply = -- REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1"); -+ REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1"); - - static struct regulator_consumer_supply rx51_vmmc2_supplies[] = { - /* tlv320aic3x analog supplies */ -@@ -348,7 +352,7 @@ - /* tpa6130a2 */ - REGULATOR_SUPPLY("Vdd", "2-0060"), - /* Keep vmmc as last item. It is not iterated for newer boards */ -- REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"), -+ REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"), - }; - - static struct regulator_consumer_supply rx51_vio_supplies[] = { -@@ -357,14 +361,18 @@ - REGULATOR_SUPPLY("DVDD", "2-0018"), - REGULATOR_SUPPLY("IOVDD", "2-0019"), - REGULATOR_SUPPLY("DVDD", "2-0019"), -+ /* Si4713 IO supply */ -+ REGULATOR_SUPPLY("vio", "2-0063"), - }; - - static struct regulator_consumer_supply rx51_vaux1_consumers[] = { - REGULATOR_SUPPLY("vdds_sdi", "omapdss"), -+ /* Si4713 supply */ -+ REGULATOR_SUPPLY("vdd", "2-0063"), - }; - - static struct regulator_consumer_supply rx51_vdac_supply[] = { -- REGULATOR_SUPPLY("vdda_dac", "omapdss"), -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"), - }; - - static struct regulator_init_data rx51_vaux1 = { -@@ -511,6 +519,41 @@ - .consumer_supplies = rx51_vio_supplies, - }; - -+static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = { -+ .gpio_reset = RX51_FMTX_RESET_GPIO, -+}; -+ -+static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = { -+ I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH), -+ .platform_data = &rx51_si4713_i2c_data, -+}; -+ -+static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = { -+ .i2c_bus = 2, -+ .subdev_board_info = &rx51_si4713_board_info, -+}; -+ -+static struct platform_device rx51_si4713_dev __initdata_or_module = { -+ .name = "radio-si4713", -+ .id = -1, -+ .dev = { -+ .platform_data = &rx51_si4713_data, -+ }, -+}; -+ -+static __init void rx51_init_si4713(void) -+{ -+ int err; -+ -+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq"); -+ if (err) { -+ printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err); -+ return; -+ } -+ rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ); -+ platform_device_register(&rx51_si4713_dev); -+} -+ - static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n) - { - /* FIXME this gpio setup is just a placeholder for now */ -@@ -699,6 +742,14 @@ - .resource_config = twl4030_rconfig, - }; - -+struct twl4030_codec_vibra_data rx51_vibra_data __initdata = { -+ .coexist = 0, -+}; -+ -+struct twl4030_codec_data rx51_codec_data __initdata = { -+ .audio_mclk = 26000000, -+ .vibra = &rx51_vibra_data, -+}; - - static struct twl4030_platform_data rx51_twldata __initdata = { - .irq_base = TWL4030_IRQ_BASE, -@@ -710,6 +761,7 @@ - .madc = &rx51_madc_data, - .usb = &rx51_usb_data, - .power = &rx51_t2scripts_data, -+ .codec = &rx51_codec_data, - - .vaux1 = &rx51_vaux1, - .vaux2 = &rx51_vaux2, -@@ -921,6 +973,7 @@ - board_smc91x_init(); - rx51_add_gpio_keys(); - rx51_init_wl1251(); -+ rx51_init_si4713(); - spi_register_board_info(rx51_peripherals_spi_board_info, - ARRAY_SIZE(rx51_peripherals_spi_board_info)); - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51-video.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51-video.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-rx51-video.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-rx51-video.c 2011-03-09 13:19:09.800507825 +0100 -@@ -66,18 +66,6 @@ - .default_device = &rx51_lcd_device, - }; - --struct platform_device rx51_display_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &rx51_dss_board_info, -- }, --}; -- --static struct platform_device *rx51_video_devices[] __initdata = { -- &rx51_display_device, --}; -- - static int __init rx51_video_init(void) - { - if (!machine_is_nokia_rx51()) -@@ -95,8 +83,7 @@ - - gpio_direction_output(RX51_LCD_RESET_GPIO, 1); - -- platform_add_devices(rx51_video_devices, -- ARRAY_SIZE(rx51_video_devices)); -+ omap_display_init(&rx51_dss_board_info); - return 0; - } - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-ti8168evm.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-ti8168evm.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-ti8168evm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-ti8168evm.c 2011-03-09 13:19:09.800507825 +0100 -@@ -0,0 +1,62 @@ -+/* -+ * Code for TI8168 EVM. -+ * -+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static struct omap_board_config_kernel ti8168_evm_config[] __initdata = { -+}; -+ -+static void __init ti8168_init_early(void) -+{ -+ omap2_init_common_infrastructure(); -+ omap2_init_common_devices(NULL, NULL); -+} -+ -+static void __init ti8168_evm_init_irq(void) -+{ -+ omap_init_irq(); -+} -+ -+static void __init ti8168_evm_init(void) -+{ -+ omap_serial_init(); -+ omap_board_config = ti8168_evm_config; -+ omap_board_config_size = ARRAY_SIZE(ti8168_evm_config); -+} -+ -+static void __init ti8168_evm_map_io(void) -+{ -+ omap2_set_globals_ti816x(); -+ omapti816x_map_common_io(); -+} -+ -+MACHINE_START(TI8168EVM, "ti8168evm") -+ /* Maintainer: Texas Instruments */ -+ .boot_params = 0x80000100, -+ .map_io = ti8168_evm_map_io, -+ .init_early = ti8168_init_early, -+ .init_irq = ti8168_evm_init_irq, -+ .timer = &omap_timer, -+ .init_machine = ti8168_evm_init, -+MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom.c 2011-03-09 13:19:09.801507805 +0100 -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -33,7 +34,7 @@ - - #define ZOOM3_EHCI_RESET_GPIO 64 - --static void __init omap_zoom_init_irq(void) -+static void __init omap_zoom_init_early(void) - { - omap2_init_common_infrastructure(); - if (machine_is_omap_zoom2()) -@@ -42,8 +43,6 @@ - else if (machine_is_omap_zoom3()) - omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params, - h8mbx00u0mer0em_sdrc_params); -- -- omap_init_irq(); - } - - #ifdef CONFIG_OMAP_MUX -@@ -126,8 +125,8 @@ - usb_ehci_init(&ehci_pdata); - } - -- board_nand_init(zoom_nand_partitions, -- ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS); -+ board_nand_init(zoom_nand_partitions, ARRAY_SIZE(zoom_nand_partitions), -+ ZOOM_NAND_CS, NAND_BUSWIDTH_16); - zoom_debugboard_init(); - zoom_peripherals_init(); - zoom_display_init(); -@@ -135,18 +134,20 @@ - - MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap_zoom_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap_zoom_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_zoom_init, - .timer = &omap_timer, - MACHINE_END - - MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board") - .boot_params = 0x80000100, -- .map_io = omap3_map_io, - .reserve = omap_reserve, -- .init_irq = omap_zoom_init_irq, -+ .map_io = omap3_map_io, -+ .init_early = omap_zoom_init_early, -+ .init_irq = omap_init_irq, - .init_machine = omap_zoom_init, - .timer = &omap_timer, - MACHINE_END -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom-display.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom-display.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom-display.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom-display.c 2011-03-09 13:19:09.801507805 +0100 -@@ -130,14 +130,6 @@ - .default_device = &zoom_lcd_device, - }; - --static struct platform_device zoom_dss_device = { -- .name = "omapdss", -- .id = -1, -- .dev = { -- .platform_data = &zoom_dss_data, -- }, --}; -- - static struct omap2_mcspi_device_config dss_lcd_mcspi_config = { - .turbo_mode = 1, - .single_channel = 1, /* 0: slave, 1: master */ -@@ -153,14 +145,9 @@ - }, - }; - --static struct platform_device *zoom_display_devices[] __initdata = { -- &zoom_dss_device, --}; -- - void __init zoom_display_init(void) - { -- platform_add_devices(zoom_display_devices, -- ARRAY_SIZE(zoom_display_devices)); -+ omap_display_init(&zoom_dss_data); - spi_register_board_info(nec_8048_spi_board_info, - ARRAY_SIZE(nec_8048_spi_board_info)); - zoom_lcd_panel_init(); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom-peripherals.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom-peripherals.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/board-zoom-peripherals.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/board-zoom-peripherals.c 2011-03-09 13:19:09.801507805 +0100 -@@ -118,7 +118,7 @@ - - static struct regulator_consumer_supply zoom_vmmc3_supply = { - .supply = "vmmc", -- .dev_name = "mmci-omap-hs.2", -+ .dev_name = "omap_hsmmc.2", - }; - - /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ -@@ -226,11 +226,13 @@ - {} /* Terminator */ - }; - --static struct regulator_consumer_supply zoom_vpll2_supply = -- REGULATOR_SUPPLY("vdds_dsi", "omapdss"); -+static struct regulator_consumer_supply zoom_vpll2_supplies[] = { -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss"), -+ REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"), -+}; - - static struct regulator_consumer_supply zoom_vdda_dac_supply = -- REGULATOR_SUPPLY("vdda_dac", "omapdss"); -+ REGULATOR_SUPPLY("vdda_dac", "omapdss_venc"); - - static struct regulator_init_data zoom_vpll2 = { - .constraints = { -@@ -241,8 +243,8 @@ - .valid_ops_mask = REGULATOR_CHANGE_MODE - | REGULATOR_CHANGE_STATUS, - }, -- .num_consumer_supplies = 1, -- .consumer_supplies = &zoom_vpll2_supply, -+ .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies), -+ .consumer_supplies = zoom_vpll2_supplies, - }; - - static struct regulator_init_data zoom_vdac = { -@@ -322,9 +324,7 @@ - .irq_line = 1, - }; - --static struct twl4030_codec_audio_data zoom_audio_data = { -- .audio_mclk = 26000000, --}; -+static struct twl4030_codec_audio_data zoom_audio_data; - - static struct twl4030_codec_data zoom_codec_data = { - .audio_mclk = 26000000, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clkt_clksel.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clkt_clksel.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clkt_clksel.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clkt_clksel.c 2011-03-09 13:19:09.802507785 +0100 -@@ -97,7 +97,7 @@ - u32 *field_val) - { - const struct clksel *clks; -- const struct clksel_rate *clkr, *max_clkr; -+ const struct clksel_rate *clkr, *max_clkr = NULL; - u8 max_div = 0; - - clks = _get_clksel_by_parent(clk, src_clk); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clock2420_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2420_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clock2420_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2420_data.c 2011-03-09 13:19:09.804507743 +0100 -@@ -1786,10 +1786,10 @@ - CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X), - CLK(NULL, "gfx_ick", &gfx_ick, CK_242X), - /* DSS domain clocks */ -- CLK("omapdss", "ick", &dss_ick, CK_242X), -- CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X), -- CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X), -- CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X), -+ CLK("omapdss_dss", "ick", &dss_ick, CK_242X), -+ CLK("omapdss_dss", "fck", &dss1_fck, CK_242X), -+ CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_242X), -+ CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_242X), - /* L3 domain clocks */ - CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X), - CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X), -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clock2430_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2430_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clock2430_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2430_data.c 2011-03-09 13:19:09.804507743 +0100 -@@ -1890,10 +1890,10 @@ - CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), - CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), - /* DSS domain clocks */ -- CLK("omapdss", "ick", &dss_ick, CK_243X), -- CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X), -- CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X), -- CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X), -+ CLK("omapdss_dss", "ick", &dss_ick, CK_243X), -+ CLK("omapdss_dss", "fck", &dss1_fck, CK_243X), -+ CLK("omapdss_dss", "sys_clk", &dss2_fck, CK_243X), -+ CLK("omapdss_dss", "tv_clk", &dss_54m_fck, CK_243X), - /* L3 domain clocks */ - CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X), - CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X), -@@ -1984,15 +1984,15 @@ - CLK(NULL, "pka_ick", &pka_ick, CK_243X), - CLK(NULL, "usb_fck", &usb_fck, CK_243X), - CLK("musb-omap2430", "ick", &usbhs_ick, CK_243X), -- CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X), -- CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X), -- CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X), -- CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_243X), -+ CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_243X), -+ CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_243X), -+ CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_243X), -+ CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_243X), - CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X), - CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X), - CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), -- CLK("mmci-omap-hs.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X), -- CLK("mmci-omap-hs.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X), -+ CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X), -+ CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X), - }; - - /* -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clock2xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2xxx.h ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clock2xxx.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock2xxx.h 2011-03-09 13:19:09.805507722 +0100 -@@ -20,13 +20,13 @@ - u32 omap2xxx_get_sysclkdiv(void); - void omap2xxx_clk_prepare_for_reboot(void); - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - int omap2420_clk_init(void); - #else - #define omap2420_clk_init() 0 - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - int omap2430_clk_init(void); - #else - #define omap2430_clk_init() 0 -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clock3xxx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock3xxx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clock3xxx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock3xxx_data.c 2011-03-09 13:19:09.807507681 +0100 -@@ -3290,10 +3290,10 @@ - CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX), - CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX), - CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX), -- CLK("mmci-omap-hs.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_3XXX), -+ CLK("omap_hsmmc.2", "fck", &mmchs3_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("omap_hsmmc.1", "fck", &mmchs2_fck, CK_3XXX), - CLK(NULL, "mspro_fck", &mspro_fck, CK_34XX | CK_36XX), -- CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_3XXX), -+ CLK("omap_hsmmc.0", "fck", &mmchs1_fck, CK_3XXX), - CLK("omap_i2c.3", "fck", &i2c3_fck, CK_3XXX), - CLK("omap_i2c.2", "fck", &i2c2_fck, CK_3XXX), - CLK("omap_i2c.1", "fck", &i2c1_fck, CK_3XXX), -@@ -3323,13 +3323,13 @@ - CLK(NULL, "core_l4_ick", &core_l4_ick, CK_3XXX), - CLK(NULL, "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK("ehci-omap.0", "usbtll_ick", &usbtll_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("mmci-omap-hs.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("omap_hsmmc.2", "ick", &mmchs3_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "icr_ick", &icr_ick, CK_34XX | CK_36XX), - CLK("omap-aes", "ick", &aes2_ick, CK_34XX | CK_36XX), - CLK("omap-sham", "ick", &sha12_ick, CK_34XX | CK_36XX), - CLK(NULL, "des2_ick", &des2_ick, CK_34XX | CK_36XX), -- CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_3XXX), -- CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_3XXX), -+ CLK("omap_hsmmc.1", "ick", &mmchs2_ick, CK_3XXX), -+ CLK("omap_hsmmc.0", "ick", &mmchs1_ick, CK_3XXX), - CLK(NULL, "mspro_ick", &mspro_ick, CK_34XX | CK_36XX), - CLK("omap_hdq.0", "ick", &hdq_ick, CK_3XXX), - CLK("omap2_mcspi.4", "ick", &mcspi4_ick, CK_3XXX), -@@ -3357,13 +3357,13 @@ - CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX), - CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX), - CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX), -- CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1), -- CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -- CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX), -- CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX), -- CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX), -- CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1), -- CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1), -+ CLK("omapdss_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), -+ CLK("omapdss_dss", "tv_clk", &dss_tv_fck, CK_3XXX), -+ CLK("omapdss_dss", "video_clk", &dss_96m_fck, CK_3XXX), -+ CLK("omapdss_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX), -+ CLK("omapdss_dss", "ick", &dss_ick_3430es1, CK_3430ES1), -+ CLK("omapdss_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), - CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX), - CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX), - CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX), -@@ -3471,6 +3471,9 @@ - } else if (cpu_is_omap3630()) { - cpu_mask = (RATE_IN_34XX | RATE_IN_36XX); - cpu_clkflg = CK_36XX; -+ } else if (cpu_is_ti816x()) { -+ cpu_mask = RATE_IN_TI816X; -+ cpu_clkflg = CK_TI816X; - } else if (cpu_is_omap34xx()) { - if (omap_rev() == OMAP3430_REV_ES1_0) { - cpu_mask = RATE_IN_3430ES1; -@@ -3550,7 +3553,7 @@ - /* - * Lock DPLL5 and put it in autoidle. - */ -- if (omap_rev() >= OMAP3430_REV_ES2_0) -+ if (!cpu_is_ti816x() && (omap_rev() >= OMAP3430_REV_ES2_0)) - omap3_clk_lock_dpll5(); - - /* Avoid sleeping during omap3_core_dpll_m2_set_rate() */ -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clock44xx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock44xx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clock44xx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clock44xx_data.c 2011-03-09 13:19:09.808507662 +0100 -@@ -3106,11 +3106,16 @@ - CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X), - CLK(NULL, "dmic_fck", &dmic_fck, CK_443X), - CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), -- CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X), -- CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X), -- CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X), -- CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X), -- CLK(NULL, "dss_fck", &dss_fck, CK_443X), -+ CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X), -+ CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X), -+ CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X), -+ CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X), -+ CLK("omapdss_dss", "fck", &dss_fck, CK_443X), -+ /* -+ * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility -+ * with OMAP2/3. -+ */ -+ CLK("omapdss_dss", "ick", &dummy_ck, CK_443X), - CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), - CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), - CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), -@@ -3158,11 +3163,11 @@ - CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_443X), - CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_443X), - CLK("omap2_mcspi.4", "fck", &mcspi4_fck, CK_443X), -- CLK("mmci-omap-hs.0", "fck", &mmc1_fck, CK_443X), -- CLK("mmci-omap-hs.1", "fck", &mmc2_fck, CK_443X), -- CLK("mmci-omap-hs.2", "fck", &mmc3_fck, CK_443X), -- CLK("mmci-omap-hs.3", "fck", &mmc4_fck, CK_443X), -- CLK("mmci-omap-hs.4", "fck", &mmc5_fck, CK_443X), -+ CLK("omap_hsmmc.0", "fck", &mmc1_fck, CK_443X), -+ CLK("omap_hsmmc.1", "fck", &mmc2_fck, CK_443X), -+ CLK("omap_hsmmc.2", "fck", &mmc3_fck, CK_443X), -+ CLK("omap_hsmmc.3", "fck", &mmc4_fck, CK_443X), -+ CLK("omap_hsmmc.4", "fck", &mmc5_fck, CK_443X), - CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), - CLK(NULL, "ocp2scp_usb_phy_ick", &ocp2scp_usb_phy_ick, CK_443X), - CLK(NULL, "ocp_wp_noc_ick", &ocp_wp_noc_ick, CK_443X), -@@ -3245,11 +3250,11 @@ - CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X), - CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X), - CLK("omap_i2c.4", "ick", &dummy_ck, CK_443X), -- CLK("mmci-omap-hs.0", "ick", &dummy_ck, CK_443X), -- CLK("mmci-omap-hs.1", "ick", &dummy_ck, CK_443X), -- CLK("mmci-omap-hs.2", "ick", &dummy_ck, CK_443X), -- CLK("mmci-omap-hs.3", "ick", &dummy_ck, CK_443X), -- CLK("mmci-omap-hs.4", "ick", &dummy_ck, CK_443X), -+ CLK("omap_hsmmc.0", "ick", &dummy_ck, CK_443X), -+ CLK("omap_hsmmc.1", "ick", &dummy_ck, CK_443X), -+ CLK("omap_hsmmc.2", "ick", &dummy_ck, CK_443X), -+ CLK("omap_hsmmc.3", "ick", &dummy_ck, CK_443X), -+ CLK("omap_hsmmc.4", "ick", &dummy_ck, CK_443X), - CLK("omap-mcbsp.1", "ick", &dummy_ck, CK_443X), - CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X), - CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X), -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c 2011-03-09 13:19:09.809507642 +0100 -@@ -171,7 +171,7 @@ - - /* 2430-specific possible wakeup dependencies */ - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - - /* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */ - static struct clkdm_dep mdm_2430_wkdeps[] = { -@@ -194,7 +194,7 @@ - { NULL }, - }; - --#endif /* CONFIG_ARCH_OMAP2430 */ -+#endif /* CONFIG_SOC_OMAP2430 */ - - - /* OMAP3-specific possible dependencies */ -@@ -450,7 +450,7 @@ - * 2420-only clockdomains - */ - --#if defined(CONFIG_ARCH_OMAP2420) -+#if defined(CONFIG_SOC_OMAP2420) - - static struct clockdomain mpu_2420_clkdm = { - .name = "mpu_clkdm", -@@ -514,14 +514,14 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), - }; - --#endif /* CONFIG_ARCH_OMAP2420 */ -+#endif /* CONFIG_SOC_OMAP2420 */ - - - /* - * 2430-only clockdomains - */ - --#if defined(CONFIG_ARCH_OMAP2430) -+#if defined(CONFIG_SOC_OMAP2430) - - static struct clockdomain mpu_2430_clkdm = { - .name = "mpu_clkdm", -@@ -600,7 +600,7 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --#endif /* CONFIG_ARCH_OMAP2430 */ -+#endif /* CONFIG_SOC_OMAP2430 */ - - - /* -@@ -811,7 +811,7 @@ - &cm_clkdm, - &prm_clkdm, - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - &mpu_2420_clkdm, - &iva1_2420_clkdm, - &dsp_2420_clkdm, -@@ -821,7 +821,7 @@ - &dss_2420_clkdm, - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - &mpu_2430_clkdm, - &mdm_clkdm, - &dsp_2430_clkdm, -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/common.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/common.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/common.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/common.c 2011-03-09 13:19:09.813507562 +0100 -@@ -40,7 +40,7 @@ - - #endif - --#if defined(CONFIG_ARCH_OMAP2420) -+#if defined(CONFIG_SOC_OMAP2420) - - static struct omap_globals omap242x_globals = { - .class = OMAP242X_CLASS, -@@ -61,7 +61,7 @@ - } - #endif - --#if defined(CONFIG_ARCH_OMAP2430) -+#if defined(CONFIG_SOC_OMAP2430) - - static struct omap_globals omap243x_globals = { - .class = OMAP243X_CLASS, -@@ -108,6 +108,27 @@ - omap2_set_globals_3xxx(); - omap34xx_map_common_io(); - } -+ -+/* -+ * Adjust TAP register base such that omap3_check_revision accesses the correct -+ * TI816X register for checking device ID (it adds 0x204 to tap base while -+ * TI816X DEVICE ID register is at offset 0x600 from control base). -+ */ -+#define TI816X_TAP_BASE (TI816X_CTRL_BASE + \ -+ TI816X_CONTROL_DEVICE_ID - 0x204) -+ -+static struct omap_globals ti816x_globals = { -+ .class = OMAP343X_CLASS, -+ .tap = OMAP2_L4_IO_ADDRESS(TI816X_TAP_BASE), -+ .ctrl = TI816X_CTRL_BASE, -+ .prm = TI816X_PRCM_BASE, -+ .cm = TI816X_PRCM_BASE, -+}; -+ -+void __init omap2_set_globals_ti816x(void) -+{ -+ __omap2_set_globals(&ti816x_globals); -+} - #endif - - #if defined(CONFIG_ARCH_OMAP4) -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/control.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/control.h ---- linux-2.6.38-rc7/arch/arm/mach-omap2/control.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/control.h 2011-03-09 13:19:09.813507562 +0100 -@@ -52,6 +52,9 @@ - #define OMAP343X_CONTROL_PADCONFS_WKUP 0xa00 - #define OMAP343X_CONTROL_GENERAL_WKUP 0xa60 - -+/* TI816X spefic control submodules */ -+#define TI816X_CONTROL_DEVCONF 0x600 -+ - /* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */ - - #define OMAP2_CONTROL_SYSCONFIG (OMAP2_CONTROL_INTERFACE + 0x10) -@@ -241,6 +244,9 @@ - #define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250 - #define OMAP3_PADCONF_SAD2D_IDLEACK 0x254 - -+/* TI816X CONTROL_DEVCONF register offsets */ -+#define TI816X_CONTROL_DEVICE_ID (TI816X_CONTROL_DEVCONF + 0x000) -+ - /* - * REVISIT: This list of registers is not comprehensive - there are more - * that should be added. -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/devices.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/devices.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/devices.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/devices.c 2011-03-09 13:19:09.814507541 +0100 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -30,6 +31,7 @@ - #include - #include - #include -+#include - - #include "mux.h" - #include "control.h" -@@ -141,96 +143,70 @@ - } - #endif - --#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) -- --#define MBOX_REG_SIZE 0x120 -- --#ifdef CONFIG_ARCH_OMAP2 --static struct resource omap2_mbox_resources[] = { -+struct omap_device_pm_latency omap_keyboard_latency[] = { - { -- .start = OMAP24XX_MAILBOX_BASE, -- .end = OMAP24XX_MAILBOX_BASE + MBOX_REG_SIZE - 1, -- .flags = IORESOURCE_MEM, -- }, -- { -- .start = INT_24XX_MAIL_U0_MPU, -- .flags = IORESOURCE_IRQ, -- .name = "dsp", -- }, -- { -- .start = INT_24XX_MAIL_U3_MPU, -- .flags = IORESOURCE_IRQ, -- .name = "iva", -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, - }; --static int omap2_mbox_resources_sz = ARRAY_SIZE(omap2_mbox_resources); --#else --#define omap2_mbox_resources NULL --#define omap2_mbox_resources_sz 0 --#endif - --#ifdef CONFIG_ARCH_OMAP3 --static struct resource omap3_mbox_resources[] = { -- { -- .start = OMAP34XX_MAILBOX_BASE, -- .end = OMAP34XX_MAILBOX_BASE + MBOX_REG_SIZE - 1, -- .flags = IORESOURCE_MEM, -- }, -- { -- .start = INT_24XX_MAIL_U0_MPU, -- .flags = IORESOURCE_IRQ, -- .name = "dsp", -- }, --}; --static int omap3_mbox_resources_sz = ARRAY_SIZE(omap3_mbox_resources); --#else --#define omap3_mbox_resources NULL --#define omap3_mbox_resources_sz 0 --#endif -+int __init omap4_keyboard_init(struct omap4_keypad_platform_data -+ *sdp4430_keypad_data) -+{ -+ struct omap_device *od; -+ struct omap_hwmod *oh; -+ struct omap4_keypad_platform_data *keypad_data; -+ unsigned int id = -1; -+ char *oh_name = "kbd"; -+ char *name = "omap4-keypad"; - --#ifdef CONFIG_ARCH_OMAP4 -+ oh = omap_hwmod_lookup(oh_name); -+ if (!oh) { -+ pr_err("Could not look up %s\n", oh_name); -+ return -ENODEV; -+ } - --#define OMAP4_MBOX_REG_SIZE 0x130 --static struct resource omap4_mbox_resources[] = { -- { -- .start = OMAP44XX_MAILBOX_BASE, -- .end = OMAP44XX_MAILBOX_BASE + -- OMAP4_MBOX_REG_SIZE - 1, -- .flags = IORESOURCE_MEM, -- }, -- { -- .start = OMAP44XX_IRQ_MAIL_U0, -- .flags = IORESOURCE_IRQ, -- .name = "mbox", -- }, --}; --static int omap4_mbox_resources_sz = ARRAY_SIZE(omap4_mbox_resources); --#else --#define omap4_mbox_resources NULL --#define omap4_mbox_resources_sz 0 --#endif -+ keypad_data = sdp4430_keypad_data; - --static struct platform_device mbox_device = { -- .name = "omap-mailbox", -- .id = -1, -+ od = omap_device_build(name, id, oh, keypad_data, -+ sizeof(struct omap4_keypad_platform_data), -+ omap_keyboard_latency, -+ ARRAY_SIZE(omap_keyboard_latency), 0); -+ -+ if (IS_ERR(od)) { -+ WARN(1, "Cant build omap_device for %s:%s.\n", -+ name, oh->name); -+ return PTR_ERR(od); -+ } -+ -+ return 0; -+} -+ -+#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE) -+static struct omap_device_pm_latency mbox_latencies[] = { -+ [0] = { -+ .activate_func = omap_device_enable_hwmods, -+ .deactivate_func = omap_device_idle_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -+ }, - }; - - static inline void omap_init_mbox(void) - { -- if (cpu_is_omap24xx()) { -- mbox_device.resource = omap2_mbox_resources; -- mbox_device.num_resources = omap2_mbox_resources_sz; -- } else if (cpu_is_omap34xx()) { -- mbox_device.resource = omap3_mbox_resources; -- mbox_device.num_resources = omap3_mbox_resources_sz; -- } else if (cpu_is_omap44xx()) { -- mbox_device.resource = omap4_mbox_resources; -- mbox_device.num_resources = omap4_mbox_resources_sz; -- } else { -- pr_err("%s: platform not supported\n", __func__); -+ struct omap_hwmod *oh; -+ struct omap_device *od; -+ -+ oh = omap_hwmod_lookup("mailbox"); -+ if (!oh) { -+ pr_err("%s: unable to find hwmod\n", __func__); - return; - } -- platform_device_register(&mbox_device); -+ -+ od = omap_device_build("omap-mailbox", -1, oh, NULL, 0, -+ mbox_latencies, ARRAY_SIZE(mbox_latencies), 0); -+ WARN(IS_ERR(od), "%s: could not build device, err %ld\n", -+ __func__, PTR_ERR(od)); - } - #else - static inline void omap_init_mbox(void) { } -@@ -279,163 +255,55 @@ - - #include - --#define OMAP2_MCSPI1_BASE 0x48098000 --#define OMAP2_MCSPI2_BASE 0x4809a000 --#define OMAP2_MCSPI3_BASE 0x480b8000 --#define OMAP2_MCSPI4_BASE 0x480ba000 -- --#define OMAP4_MCSPI1_BASE 0x48098100 --#define OMAP4_MCSPI2_BASE 0x4809a100 --#define OMAP4_MCSPI3_BASE 0x480b8100 --#define OMAP4_MCSPI4_BASE 0x480ba100 -- --static struct omap2_mcspi_platform_config omap2_mcspi1_config = { -- .num_cs = 4, --}; -- --static struct resource omap2_mcspi1_resources[] = { -- { -- .start = OMAP2_MCSPI1_BASE, -- .end = OMAP2_MCSPI1_BASE + 0xff, -- .flags = IORESOURCE_MEM, -- }, --}; -- --static struct platform_device omap2_mcspi1 = { -- .name = "omap2_mcspi", -- .id = 1, -- .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), -- .resource = omap2_mcspi1_resources, -- .dev = { -- .platform_data = &omap2_mcspi1_config, -- }, --}; -- --static struct omap2_mcspi_platform_config omap2_mcspi2_config = { -- .num_cs = 2, --}; -- --static struct resource omap2_mcspi2_resources[] = { -- { -- .start = OMAP2_MCSPI2_BASE, -- .end = OMAP2_MCSPI2_BASE + 0xff, -- .flags = IORESOURCE_MEM, -- }, --}; -- --static struct platform_device omap2_mcspi2 = { -- .name = "omap2_mcspi", -- .id = 2, -- .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), -- .resource = omap2_mcspi2_resources, -- .dev = { -- .platform_data = &omap2_mcspi2_config, -- }, --}; -- --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ -- defined(CONFIG_ARCH_OMAP4) --static struct omap2_mcspi_platform_config omap2_mcspi3_config = { -- .num_cs = 2, --}; -- --static struct resource omap2_mcspi3_resources[] = { -- { -- .start = OMAP2_MCSPI3_BASE, -- .end = OMAP2_MCSPI3_BASE + 0xff, -- .flags = IORESOURCE_MEM, -- }, --}; -- --static struct platform_device omap2_mcspi3 = { -- .name = "omap2_mcspi", -- .id = 3, -- .num_resources = ARRAY_SIZE(omap2_mcspi3_resources), -- .resource = omap2_mcspi3_resources, -- .dev = { -- .platform_data = &omap2_mcspi3_config, -- }, --}; --#endif -- --#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) --static struct omap2_mcspi_platform_config omap2_mcspi4_config = { -- .num_cs = 1, --}; -- --static struct resource omap2_mcspi4_resources[] = { -- { -- .start = OMAP2_MCSPI4_BASE, -- .end = OMAP2_MCSPI4_BASE + 0xff, -- .flags = IORESOURCE_MEM, -- }, --}; -- --static struct platform_device omap2_mcspi4 = { -- .name = "omap2_mcspi", -- .id = 4, -- .num_resources = ARRAY_SIZE(omap2_mcspi4_resources), -- .resource = omap2_mcspi4_resources, -- .dev = { -- .platform_data = &omap2_mcspi4_config, -+struct omap_device_pm_latency omap_mcspi_latency[] = { -+ [0] = { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, - }; --#endif - --#ifdef CONFIG_ARCH_OMAP4 --static inline void omap4_mcspi_fixup(void) --{ -- omap2_mcspi1_resources[0].start = OMAP4_MCSPI1_BASE; -- omap2_mcspi1_resources[0].end = OMAP4_MCSPI1_BASE + 0xff; -- omap2_mcspi2_resources[0].start = OMAP4_MCSPI2_BASE; -- omap2_mcspi2_resources[0].end = OMAP4_MCSPI2_BASE + 0xff; -- omap2_mcspi3_resources[0].start = OMAP4_MCSPI3_BASE; -- omap2_mcspi3_resources[0].end = OMAP4_MCSPI3_BASE + 0xff; -- omap2_mcspi4_resources[0].start = OMAP4_MCSPI4_BASE; -- omap2_mcspi4_resources[0].end = OMAP4_MCSPI4_BASE + 0xff; --} --#else --static inline void omap4_mcspi_fixup(void) --{ --} --#endif -- --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ -- defined(CONFIG_ARCH_OMAP4) --static inline void omap2_mcspi3_init(void) --{ -- platform_device_register(&omap2_mcspi3); --} --#else --static inline void omap2_mcspi3_init(void) -+static int omap_mcspi_init(struct omap_hwmod *oh, void *unused) - { --} --#endif -+ struct omap_device *od; -+ char *name = "omap2_mcspi"; -+ struct omap2_mcspi_platform_config *pdata; -+ static int spi_num; -+ struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; -+ -+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); -+ if (!pdata) { -+ pr_err("Memory allocation for McSPI device failed\n"); -+ return -ENOMEM; -+ } -+ -+ pdata->num_cs = mcspi_attrib->num_chipselect; -+ switch (oh->class->rev) { -+ case OMAP2_MCSPI_REV: -+ case OMAP3_MCSPI_REV: -+ pdata->regs_offset = 0; -+ break; -+ case OMAP4_MCSPI_REV: -+ pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; -+ break; -+ default: -+ pr_err("Invalid McSPI Revision value\n"); -+ return -EINVAL; -+ } - --#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) --static inline void omap2_mcspi4_init(void) --{ -- platform_device_register(&omap2_mcspi4); --} --#else --static inline void omap2_mcspi4_init(void) --{ -+ spi_num++; -+ od = omap_device_build(name, spi_num, oh, pdata, -+ sizeof(*pdata), omap_mcspi_latency, -+ ARRAY_SIZE(omap_mcspi_latency), 0); -+ WARN(IS_ERR(od), "Cant build omap_device for %s:%s\n", -+ name, oh->name); -+ kfree(pdata); -+ return 0; - } --#endif - - static void omap_init_mcspi(void) - { -- if (cpu_is_omap44xx()) -- omap4_mcspi_fixup(); -- -- platform_device_register(&omap2_mcspi1); -- platform_device_register(&omap2_mcspi2); -- -- if (cpu_is_omap2430() || cpu_is_omap343x() || cpu_is_omap44xx()) -- omap2_mcspi3_init(); -- -- if (cpu_is_omap343x() || cpu_is_omap44xx()) -- omap2_mcspi4_init(); -+ omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); - } - - #else -@@ -610,117 +478,10 @@ - - /*-------------------------------------------------------------------------*/ - --#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -- --#define MMCHS_SYSCONFIG 0x0010 --#define MMCHS_SYSCONFIG_SWRESET (1 << 1) --#define MMCHS_SYSSTATUS 0x0014 --#define MMCHS_SYSSTATUS_RESETDONE (1 << 0) -- --static struct platform_device dummy_pdev = { -- .dev = { -- .bus = &platform_bus_type, -- }, --}; -+#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) - --/** -- * omap_hsmmc_reset() - Full reset of each HS-MMC controller -- * -- * Ensure that each MMC controller is fully reset. Controllers -- * left in an unknown state (by bootloader) may prevent retention -- * or OFF-mode. This is especially important in cases where the -- * MMC driver is not enabled, _or_ built as a module. -- * -- * In order for reset to work, interface, functional and debounce -- * clocks must be enabled. The debounce clock comes from func_32k_clk -- * and is not under SW control, so we only enable i- and f-clocks. -- **/ --static void __init omap_hsmmc_reset(void) --{ -- u32 i, nr_controllers; -- struct clk *iclk, *fclk; -- -- if (cpu_is_omap242x()) -- return; -- -- nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC : -- (cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC); -- -- for (i = 0; i < nr_controllers; i++) { -- u32 v, base = 0; -- struct device *dev = &dummy_pdev.dev; -- -- switch (i) { -- case 0: -- base = OMAP2_MMC1_BASE; -- break; -- case 1: -- base = OMAP2_MMC2_BASE; -- break; -- case 2: -- base = OMAP3_MMC3_BASE; -- break; -- case 3: -- if (!cpu_is_omap44xx()) -- return; -- base = OMAP4_MMC4_BASE; -- break; -- case 4: -- if (!cpu_is_omap44xx()) -- return; -- base = OMAP4_MMC5_BASE; -- break; -- } -- -- if (cpu_is_omap44xx()) -- base += OMAP4_MMC_REG_OFFSET; -- -- dummy_pdev.id = i; -- dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i); -- iclk = clk_get(dev, "ick"); -- if (IS_ERR(iclk)) -- goto err1; -- if (clk_enable(iclk)) -- goto err2; -- -- fclk = clk_get(dev, "fck"); -- if (IS_ERR(fclk)) -- goto err3; -- if (clk_enable(fclk)) -- goto err4; -- -- omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG); -- v = omap_readl(base + MMCHS_SYSSTATUS); -- while (!(omap_readl(base + MMCHS_SYSSTATUS) & -- MMCHS_SYSSTATUS_RESETDONE)) -- cpu_relax(); -- -- clk_disable(fclk); -- clk_put(fclk); -- clk_disable(iclk); -- clk_put(iclk); -- } -- return; -- --err4: -- clk_put(fclk); --err3: -- clk_disable(iclk); --err2: -- clk_put(iclk); --err1: -- printk(KERN_WARNING "%s: Unable to enable clocks for MMC%d, " -- "cannot reset.\n", __func__, i); --} --#else --static inline void omap_hsmmc_reset(void) {} --#endif -- --#if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ -- defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) -- --static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller, -- int controller_nr) -+static inline void omap242x_mmc_mux(struct omap_mmc_platform_data -+ *mmc_controller) - { - if ((mmc_controller->slots[0].switch_pin > 0) && \ - (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) -@@ -731,163 +492,44 @@ - omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, - OMAP_PIN_INPUT_PULLUP); - -- if (cpu_is_omap2420() && controller_nr == 0) { -- omap_mux_init_signal("sdmmc_cmd", 0); -- omap_mux_init_signal("sdmmc_clki", 0); -- omap_mux_init_signal("sdmmc_clko", 0); -- omap_mux_init_signal("sdmmc_dat0", 0); -- omap_mux_init_signal("sdmmc_dat_dir0", 0); -- omap_mux_init_signal("sdmmc_cmd_dir", 0); -- if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { -- omap_mux_init_signal("sdmmc_dat1", 0); -- omap_mux_init_signal("sdmmc_dat2", 0); -- omap_mux_init_signal("sdmmc_dat3", 0); -- omap_mux_init_signal("sdmmc_dat_dir1", 0); -- omap_mux_init_signal("sdmmc_dat_dir2", 0); -- omap_mux_init_signal("sdmmc_dat_dir3", 0); -- } -- -- /* -- * Use internal loop-back in MMC/SDIO Module Input Clock -- * selection -- */ -- if (mmc_controller->slots[0].internal_clock) { -- u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -- v |= (1 << 24); -- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); -- } -- } -- -- if (cpu_is_omap34xx()) { -- if (controller_nr == 0) { -- omap_mux_init_signal("sdmmc1_clk", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_cmd", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat0", -- OMAP_PIN_INPUT_PULLUP); -- if (mmc_controller->slots[0].caps & -- (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { -- omap_mux_init_signal("sdmmc1_dat1", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat2", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat3", -- OMAP_PIN_INPUT_PULLUP); -- } -- if (mmc_controller->slots[0].caps & -- MMC_CAP_8_BIT_DATA) { -- omap_mux_init_signal("sdmmc1_dat4", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat5", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat6", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc1_dat7", -- OMAP_PIN_INPUT_PULLUP); -- } -- } -- if (controller_nr == 1) { -- /* MMC2 */ -- omap_mux_init_signal("sdmmc2_clk", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_cmd", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat0", -- OMAP_PIN_INPUT_PULLUP); -- -- /* -- * For 8 wire configurations, Lines DAT4, 5, 6 and 7 need to be muxed -- * in the board-*.c files -- */ -- if (mmc_controller->slots[0].caps & -- (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { -- omap_mux_init_signal("sdmmc2_dat1", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat2", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat3", -- OMAP_PIN_INPUT_PULLUP); -- } -- if (mmc_controller->slots[0].caps & -- MMC_CAP_8_BIT_DATA) { -- omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6", -- OMAP_PIN_INPUT_PULLUP); -- omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7", -- OMAP_PIN_INPUT_PULLUP); -- } -- } -+ omap_mux_init_signal("sdmmc_cmd", 0); -+ omap_mux_init_signal("sdmmc_clki", 0); -+ omap_mux_init_signal("sdmmc_clko", 0); -+ omap_mux_init_signal("sdmmc_dat0", 0); -+ omap_mux_init_signal("sdmmc_dat_dir0", 0); -+ omap_mux_init_signal("sdmmc_cmd_dir", 0); -+ if (mmc_controller->slots[0].caps & MMC_CAP_4_BIT_DATA) { -+ omap_mux_init_signal("sdmmc_dat1", 0); -+ omap_mux_init_signal("sdmmc_dat2", 0); -+ omap_mux_init_signal("sdmmc_dat3", 0); -+ omap_mux_init_signal("sdmmc_dat_dir1", 0); -+ omap_mux_init_signal("sdmmc_dat_dir2", 0); -+ omap_mux_init_signal("sdmmc_dat_dir3", 0); -+ } - -- /* -- * For MMC3 the pins need to be muxed in the board-*.c files -- */ -+ /* -+ * Use internal loop-back in MMC/SDIO Module Input Clock -+ * selection -+ */ -+ if (mmc_controller->slots[0].internal_clock) { -+ u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0); -+ v |= (1 << 24); -+ omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0); - } - } - --void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, -- int nr_controllers) -+void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) - { -- int i; -- char *name; -- -- for (i = 0; i < nr_controllers; i++) { -- unsigned long base, size; -- unsigned int irq = 0; -- -- if (!mmc_data[i]) -- continue; -+ char *name = "mmci-omap"; - -- omap2_mmc_mux(mmc_data[i], i); -+ if (!mmc_data[0]) { -+ pr_err("%s fails: Incomplete platform data\n", __func__); -+ return; -+ } - -- switch (i) { -- case 0: -- base = OMAP2_MMC1_BASE; -- irq = INT_24XX_MMC_IRQ; -- break; -- case 1: -- base = OMAP2_MMC2_BASE; -- irq = INT_24XX_MMC2_IRQ; -- break; -- case 2: -- if (!cpu_is_omap44xx() && !cpu_is_omap34xx()) -- return; -- base = OMAP3_MMC3_BASE; -- irq = INT_34XX_MMC3_IRQ; -- break; -- case 3: -- if (!cpu_is_omap44xx()) -- return; -- base = OMAP4_MMC4_BASE; -- irq = OMAP44XX_IRQ_MMC4; -- break; -- case 4: -- if (!cpu_is_omap44xx()) -- return; -- base = OMAP4_MMC5_BASE; -- irq = OMAP44XX_IRQ_MMC5; -- break; -- default: -- continue; -- } -- -- if (cpu_is_omap2420()) { -- size = OMAP2420_MMC_SIZE; -- name = "mmci-omap"; -- } else if (cpu_is_omap44xx()) { -- if (i < 3) -- irq += OMAP44XX_IRQ_GIC_START; -- size = OMAP4_HSMMC_SIZE; -- name = "mmci-omap-hs"; -- } else { -- size = OMAP3_HSMMC_SIZE; -- name = "mmci-omap-hs"; -- } -- omap_mmc_add(name, i, base, size, irq, mmc_data[i]); -- }; -+ omap242x_mmc_mux(mmc_data[0]); -+ omap_mmc_add(name, 0, OMAP2_MMC1_BASE, OMAP2420_MMC_SIZE, -+ INT_24XX_MMC_IRQ, mmc_data[0]); - } - - #endif -@@ -895,7 +537,7 @@ - /*-------------------------------------------------------------------------*/ - - #if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE) --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) - #define OMAP_HDQ_BASE 0x480B2000 - #endif - static struct resource omap_hdq_resources[] = { -@@ -961,7 +603,6 @@ - * please keep these calls, and their implementations above, - * in alphabetical order so they're easier to sort through. - */ -- omap_hsmmc_reset(); - omap_init_audio(); - omap_init_camera(); - omap_init_mbox(); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/display.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/display.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/display.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/display.c 2011-03-09 13:19:09.814507541 +0100 -@@ -0,0 +1,125 @@ -+/* -+ * OMAP2plus display device setup / initialization. -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ -+ * Senthilvadivu Guruswamy -+ * Sumit Semwal -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static struct platform_device omap_display_device = { -+ .name = "omapdss", -+ .id = -1, -+ .dev = { -+ .platform_data = NULL, -+ }, -+}; -+ -+static struct omap_device_pm_latency omap_dss_latency[] = { -+ [0] = { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -+ }, -+}; -+ -+/* oh_core is used for getting opt-clocks */ -+static struct omap_hwmod *oh_core; -+ -+static bool opt_clock_available(const char *clk_role) -+{ -+ int i; -+ -+ for (i = 0; i < oh_core->opt_clks_cnt; i++) { -+ if (!strcmp(oh_core->opt_clks[i].role, clk_role)) -+ return true; -+ } -+ return false; -+} -+ -+int __init omap_display_init(struct omap_dss_board_info *board_data) -+{ -+ int r = 0; -+ struct omap_hwmod *oh; -+ struct omap_device *od; -+ int i; -+ struct omap_display_platform_data pdata; -+ -+ /* -+ * omap: valid DSS hwmod names -+ * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc -+ * omap3,4: dss_dsi1 -+ * omap4: dss_dsi2, dss_hdmi -+ */ -+ char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc", -+ "dss_dsi1", "dss_dsi2", "dss_hdmi" }; -+ char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi", -+ "omapdss_venc", "omapdss_dsi1", "omapdss_dsi2", -+ "omapdss_hdmi" }; -+ int oh_count; -+ -+ memset(&pdata, 0, sizeof(pdata)); -+ -+ if (cpu_is_omap24xx()) -+ oh_count = ARRAY_SIZE(oh_name) - 3; -+ /* last 3 hwmod dev in oh_name are not available for omap2 */ -+ else if (cpu_is_omap44xx()) -+ oh_count = ARRAY_SIZE(oh_name); -+ else -+ oh_count = ARRAY_SIZE(oh_name) - 2; -+ /* last 2 hwmod dev in oh_name are not available for omap3 */ -+ -+ /* opt_clks are always associated with dss hwmod */ -+ oh_core = omap_hwmod_lookup("dss_core"); -+ if (!oh_core) { -+ pr_err("Could not look up dss_core.\n"); -+ return -ENODEV; -+ } -+ -+ pdata.board_data = board_data; -+ pdata.board_data->get_last_off_on_transaction_id = NULL; -+ pdata.opt_clock_available = opt_clock_available; -+ -+ for (i = 0; i < oh_count; i++) { -+ oh = omap_hwmod_lookup(oh_name[i]); -+ if (!oh) { -+ pr_err("Could not look up %s\n", oh_name[i]); -+ return -ENODEV; -+ } -+ -+ od = omap_device_build(dev_name[i], -1, oh, &pdata, -+ sizeof(struct omap_display_platform_data), -+ omap_dss_latency, -+ ARRAY_SIZE(omap_dss_latency), 0); -+ -+ if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n", -+ oh_name[i])) -+ return -ENODEV; -+ } -+ omap_display_device.dev.platform_data = board_data; -+ -+ r = platform_device_register(&omap_display_device); -+ if (r < 0) -+ printk(KERN_ERR "Unable to register OMAP-Display device\n"); -+ -+ return r; -+} -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc.c 2011-03-09 13:19:09.816507499 +0100 -@@ -14,6 +14,7 @@ - */ - #undef DEBUG - -+#include - #include - #include - #include -@@ -22,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -58,7 +60,6 @@ - #define GPMC_CHUNK_SHIFT 24 /* 16 MB */ - #define GPMC_SECTION_SHIFT 28 /* 128 MB */ - --#define PREFETCH_FIFOTHRESHOLD (0x40 << 8) - #define CS_NUM_SHIFT 24 - #define ENABLE_PREFETCH (0x1 << 7) - #define DMA_MPU_MODE 2 -@@ -100,6 +101,8 @@ - - static struct clk *gpmc_l3_clk; - -+static irqreturn_t gpmc_handle_irq(int irq, void *dev); -+ - static void gpmc_write_reg(int idx, u32 val) - { - __raw_writel(val, gpmc_base + idx); -@@ -497,6 +500,10 @@ - u32 regval = 0; - - switch (cmd) { -+ case GPMC_ENABLE_IRQ: -+ gpmc_write_reg(GPMC_IRQENABLE, wval); -+ break; -+ - case GPMC_SET_IRQ_STATUS: - gpmc_write_reg(GPMC_IRQSTATUS, wval); - break; -@@ -598,15 +605,19 @@ - /** - * gpmc_prefetch_enable - configures and starts prefetch transfer - * @cs: cs (chip select) number -+ * @fifo_th: fifo threshold to be used for read/ write - * @dma_mode: dma mode enable (1) or disable (0) - * @u32_count: number of bytes to be transferred - * @is_write: prefetch read(0) or write post(1) mode - */ --int gpmc_prefetch_enable(int cs, int dma_mode, -+int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, - unsigned int u32_count, int is_write) - { - -- if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { -+ if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) { -+ pr_err("gpmc: fifo threshold is not supported\n"); -+ return -1; -+ } else if (!(gpmc_read_reg(GPMC_PREFETCH_CONTROL))) { - /* Set the amount of bytes to be prefetched */ - gpmc_write_reg(GPMC_PREFETCH_CONFIG2, u32_count); - -@@ -614,7 +625,7 @@ - * enable the engine. Set which cs is has requested for. - */ - gpmc_write_reg(GPMC_PREFETCH_CONFIG1, ((cs << CS_NUM_SHIFT) | -- PREFETCH_FIFOTHRESHOLD | -+ PREFETCH_FIFOTHRESHOLD(fifo_th) | - ENABLE_PREFETCH | - (dma_mode << DMA_MPU_MODE) | - (0x1 & is_write))); -@@ -678,9 +689,10 @@ - } - } - --void __init gpmc_init(void) -+static int __init gpmc_init(void) - { -- u32 l; -+ u32 l, irq; -+ int cs, ret = -EINVAL; - char *ck = NULL; - - if (cpu_is_omap24xx()) { -@@ -698,7 +710,7 @@ - } - - if (WARN_ON(!ck)) -- return; -+ return ret; - - gpmc_l3_clk = clk_get(NULL, ck); - if (IS_ERR(gpmc_l3_clk)) { -@@ -723,6 +735,36 @@ - l |= (0x02 << 3) | (1 << 0); - gpmc_write_reg(GPMC_SYSCONFIG, l); - gpmc_mem_init(); -+ -+ /* initalize the irq_chained */ -+ irq = OMAP_GPMC_IRQ_BASE; -+ for (cs = 0; cs < GPMC_CS_NUM; cs++) { -+ set_irq_handler(irq, handle_simple_irq); -+ set_irq_flags(irq, IRQF_VALID); -+ irq++; -+ } -+ -+ ret = request_irq(INT_34XX_GPMC_IRQ, -+ gpmc_handle_irq, IRQF_SHARED, "gpmc", gpmc_base); -+ if (ret) -+ pr_err("gpmc: irq-%d could not claim: err %d\n", -+ INT_34XX_GPMC_IRQ, ret); -+ return ret; -+} -+postcore_initcall(gpmc_init); -+ -+static irqreturn_t gpmc_handle_irq(int irq, void *dev) -+{ -+ u8 cs; -+ -+ if (irq != INT_34XX_GPMC_IRQ) -+ return IRQ_HANDLED; -+ /* check cs to invoke the irq */ -+ cs = ((gpmc_read_reg(GPMC_PREFETCH_CONFIG1)) >> CS_NUM_SHIFT) & 0x7; -+ if (OMAP_GPMC_IRQ_BASE+cs <= OMAP_GPMC_IRQ_END) -+ generic_handle_irq(OMAP_GPMC_IRQ_BASE+cs); -+ -+ return IRQ_HANDLED; - } - - #ifdef CONFIG_ARCH_OMAP3 -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc-nand.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc-nand.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc-nand.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc-nand.c 2011-03-09 13:19:09.815507520 +0100 -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - - #include - -@@ -69,8 +70,10 @@ - t.wr_cycle = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->wr_cycle); - - /* Configure GPMC */ -- gpmc_cs_configure(gpmc_nand_data->cs, -- GPMC_CONFIG_DEV_SIZE, gpmc_nand_data->devsize); -+ if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16) -+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 1); -+ else -+ gpmc_cs_configure(gpmc_nand_data->cs, GPMC_CONFIG_DEV_SIZE, 0); - gpmc_cs_configure(gpmc_nand_data->cs, - GPMC_CONFIG_DEV_TYPE, GPMC_DEVICETYPE_NAND); - err = gpmc_cs_set_timings(gpmc_nand_data->cs, &t); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc-onenand.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc-onenand.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/gpmc-onenand.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/gpmc-onenand.c 2011-03-09 13:19:09.815507520 +0100 -@@ -94,7 +94,7 @@ - } - - static void set_onenand_cfg(void __iomem *onenand_base, int latency, -- int sync_read, int sync_write, int hf) -+ int sync_read, int sync_write, int hf, int vhf) - { - u32 reg; - -@@ -114,12 +114,57 @@ - reg |= ONENAND_SYS_CFG1_HF; - else - reg &= ~ONENAND_SYS_CFG1_HF; -+ if (vhf) -+ reg |= ONENAND_SYS_CFG1_VHF; -+ else -+ reg &= ~ONENAND_SYS_CFG1_VHF; - writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); - } - -+static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg, -+ void __iomem *onenand_base, bool *clk_dep) -+{ -+ u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID); -+ int freq = 0; -+ -+ if (cfg->get_freq) { -+ struct onenand_freq_info fi; -+ -+ fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID); -+ fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID); -+ fi.ver_id = ver; -+ freq = cfg->get_freq(&fi, clk_dep); -+ if (freq) -+ return freq; -+ } -+ -+ switch ((ver >> 4) & 0xf) { -+ case 0: -+ freq = 40; -+ break; -+ case 1: -+ freq = 54; -+ break; -+ case 2: -+ freq = 66; -+ break; -+ case 3: -+ freq = 83; -+ break; -+ case 4: -+ freq = 104; -+ break; -+ default: -+ freq = 54; -+ break; -+ } -+ -+ return freq; -+} -+ - static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, - void __iomem *onenand_base, -- int freq) -+ int *freq_ptr) - { - struct gpmc_timings t; - const int t_cer = 15; -@@ -130,10 +175,11 @@ - const int t_wph = 30; - int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; - int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; -- int first_time = 0, hf = 0, sync_read = 0, sync_write = 0; -+ int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0; - int err, ticks_cez; -- int cs = cfg->cs; -+ int cs = cfg->cs, freq = *freq_ptr; - u32 reg; -+ bool clk_dep = false; - - if (cfg->flags & ONENAND_SYNC_READ) { - sync_read = 1; -@@ -148,27 +194,7 @@ - err = omap2_onenand_set_async_mode(cs, onenand_base); - if (err) - return err; -- reg = readw(onenand_base + ONENAND_REG_VERSION_ID); -- switch ((reg >> 4) & 0xf) { -- case 0: -- freq = 40; -- break; -- case 1: -- freq = 54; -- break; -- case 2: -- freq = 66; -- break; -- case 3: -- freq = 83; -- break; -- case 4: -- freq = 104; -- break; -- default: -- freq = 54; -- break; -- } -+ freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep); - first_time = 1; - } - -@@ -180,7 +206,7 @@ - t_avdh = 2; - t_ach = 3; - t_aavdh = 6; -- t_rdyo = 9; -+ t_rdyo = 6; - break; - case 83: - min_gpmc_clk_period = 12000; /* 83 MHz */ -@@ -217,16 +243,36 @@ - gpmc_clk_ns = gpmc_ticks_to_ns(div); - if (gpmc_clk_ns < 15) /* >66Mhz */ - hf = 1; -- if (hf) -+ if (gpmc_clk_ns < 12) /* >83Mhz */ -+ vhf = 1; -+ if (vhf) -+ latency = 8; -+ else if (hf) - latency = 6; - else if (gpmc_clk_ns >= 25) /* 40 MHz*/ - latency = 3; - else - latency = 4; - -+ if (clk_dep) { -+ if (gpmc_clk_ns < 12) { /* >83Mhz */ -+ t_ces = 3; -+ t_avds = 4; -+ } else if (gpmc_clk_ns < 15) { /* >66Mhz */ -+ t_ces = 5; -+ t_avds = 4; -+ } else if (gpmc_clk_ns < 25) { /* >40Mhz */ -+ t_ces = 6; -+ t_avds = 5; -+ } else { -+ t_ces = 7; -+ t_avds = 7; -+ } -+ } -+ - if (first_time) - set_onenand_cfg(onenand_base, latency, -- sync_read, sync_write, hf); -+ sync_read, sync_write, hf, vhf); - - if (div == 1) { - reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2); -@@ -264,6 +310,9 @@ - /* Read */ - t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh)); - t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach)); -+ /* Force at least 1 clk between AVD High to OE Low */ -+ if (t.oe_on <= t.adv_rd_off) -+ t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1); - t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div); - t.oe_off = t.access + gpmc_round_ns_to_ticks(1); - t.cs_rd_off = t.oe_off; -@@ -317,18 +366,20 @@ - if (err) - return err; - -- set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf); -+ set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf); -+ -+ *freq_ptr = freq; - - return 0; - } - --static int gpmc_onenand_setup(void __iomem *onenand_base, int freq) -+static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) - { - struct device *dev = &gpmc_onenand_device.dev; - - /* Set sync timings in GPMC */ - if (omap2_onenand_set_sync_mode(gpmc_onenand_data, onenand_base, -- freq) < 0) { -+ freq_ptr) < 0) { - dev_err(dev, "Unable to set synchronous mode\n"); - return -EINVAL; - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/hsmmc.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/hsmmc.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/hsmmc.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/hsmmc.c 2011-03-09 13:19:09.816507499 +0100 -@@ -16,7 +16,10 @@ - #include - #include - #include -+#include -+#include - -+#include "mux.h" - #include "hsmmc.h" - #include "control.h" - -@@ -28,10 +31,6 @@ - - #define HSMMC_NAME_LEN 9 - --static struct hsmmc_controller { -- char name[HSMMC_NAME_LEN + 1]; --} hsmmc[OMAP34XX_NR_MMC]; -- - #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) - - static int hsmmc_get_context_loss(struct device *dev) -@@ -204,13 +203,284 @@ - return 0; - } - --static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata; -+static inline void omap_hsmmc_mux(struct omap_mmc_platform_data *mmc_controller, -+ int controller_nr) -+{ -+ if ((mmc_controller->slots[0].switch_pin > 0) && \ -+ (mmc_controller->slots[0].switch_pin < OMAP_MAX_GPIO_LINES)) -+ omap_mux_init_gpio(mmc_controller->slots[0].switch_pin, -+ OMAP_PIN_INPUT_PULLUP); -+ if ((mmc_controller->slots[0].gpio_wp > 0) && \ -+ (mmc_controller->slots[0].gpio_wp < OMAP_MAX_GPIO_LINES)) -+ omap_mux_init_gpio(mmc_controller->slots[0].gpio_wp, -+ OMAP_PIN_INPUT_PULLUP); -+ if (cpu_is_omap34xx()) { -+ if (controller_nr == 0) { -+ omap_mux_init_signal("sdmmc1_clk", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_cmd", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat0", -+ OMAP_PIN_INPUT_PULLUP); -+ if (mmc_controller->slots[0].caps & -+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { -+ omap_mux_init_signal("sdmmc1_dat1", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat2", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat3", -+ OMAP_PIN_INPUT_PULLUP); -+ } -+ if (mmc_controller->slots[0].caps & -+ MMC_CAP_8_BIT_DATA) { -+ omap_mux_init_signal("sdmmc1_dat4", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat5", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat6", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc1_dat7", -+ OMAP_PIN_INPUT_PULLUP); -+ } -+ } -+ if (controller_nr == 1) { -+ /* MMC2 */ -+ omap_mux_init_signal("sdmmc2_clk", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_cmd", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat0", -+ OMAP_PIN_INPUT_PULLUP); -+ -+ /* -+ * For 8 wire configurations, Lines DAT4, 5, 6 and 7 -+ * need to be muxed in the board-*.c files -+ */ -+ if (mmc_controller->slots[0].caps & -+ (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA)) { -+ omap_mux_init_signal("sdmmc2_dat1", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat2", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat3", -+ OMAP_PIN_INPUT_PULLUP); -+ } -+ if (mmc_controller->slots[0].caps & -+ MMC_CAP_8_BIT_DATA) { -+ omap_mux_init_signal("sdmmc2_dat4.sdmmc2_dat4", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat5.sdmmc2_dat5", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat6.sdmmc2_dat6", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("sdmmc2_dat7.sdmmc2_dat7", -+ OMAP_PIN_INPUT_PULLUP); -+ } -+ } -+ -+ /* -+ * For MMC3 the pins need to be muxed in the board-*.c files -+ */ -+ } -+} -+ -+static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, -+ struct omap_mmc_platform_data *mmc) -+{ -+ char *hc_name; -+ -+ hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); -+ if (!hc_name) { -+ pr_err("Cannot allocate memory for controller slot name\n"); -+ kfree(hc_name); -+ return -ENOMEM; -+ } -+ -+ if (c->name) -+ strncpy(hc_name, c->name, HSMMC_NAME_LEN); -+ else -+ snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", -+ c->mmc, 1); -+ mmc->slots[0].name = hc_name; -+ mmc->nr_slots = 1; -+ mmc->slots[0].caps = c->caps; -+ mmc->slots[0].internal_clock = !c->ext_clock; -+ mmc->dma_mask = 0xffffffff; -+ if (cpu_is_omap44xx()) -+ mmc->reg_offset = OMAP4_MMC_REG_OFFSET; -+ else -+ mmc->reg_offset = 0; -+ -+ mmc->get_context_loss_count = hsmmc_get_context_loss; -+ -+ mmc->slots[0].switch_pin = c->gpio_cd; -+ mmc->slots[0].gpio_wp = c->gpio_wp; -+ -+ mmc->slots[0].remux = c->remux; -+ mmc->slots[0].init_card = c->init_card; -+ -+ if (c->cover_only) -+ mmc->slots[0].cover = 1; -+ -+ if (c->nonremovable) -+ mmc->slots[0].nonremovable = 1; -+ -+ if (c->power_saving) -+ mmc->slots[0].power_saving = 1; -+ -+ if (c->no_off) -+ mmc->slots[0].no_off = 1; -+ -+ if (c->vcc_aux_disable_is_sleep) -+ mmc->slots[0].vcc_aux_disable_is_sleep = 1; -+ -+ /* -+ * NOTE: MMC slots should have a Vcc regulator set up. -+ * This may be from a TWL4030-family chip, another -+ * controllable regulator, or a fixed supply. -+ * -+ * temporary HACK: ocr_mask instead of fixed supply -+ */ -+ mmc->slots[0].ocr_mask = c->ocr_mask; -+ -+ if (cpu_is_omap3517() || cpu_is_omap3505()) -+ mmc->slots[0].set_power = nop_mmc_set_power; -+ else -+ mmc->slots[0].features |= HSMMC_HAS_PBIAS; -+ -+ if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) -+ mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET; -+ -+ switch (c->mmc) { -+ case 1: -+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { -+ /* on-chip level shifting via PBIAS0/PBIAS1 */ -+ if (cpu_is_omap44xx()) { -+ mmc->slots[0].before_set_reg = -+ omap4_hsmmc1_before_set_reg; -+ mmc->slots[0].after_set_reg = -+ omap4_hsmmc1_after_set_reg; -+ } else { -+ mmc->slots[0].before_set_reg = -+ omap_hsmmc1_before_set_reg; -+ mmc->slots[0].after_set_reg = -+ omap_hsmmc1_after_set_reg; -+ } -+ } -+ -+ /* OMAP3630 HSMMC1 supports only 4-bit */ -+ if (cpu_is_omap3630() && -+ (c->caps & MMC_CAP_8_BIT_DATA)) { -+ c->caps &= ~MMC_CAP_8_BIT_DATA; -+ c->caps |= MMC_CAP_4_BIT_DATA; -+ mmc->slots[0].caps = c->caps; -+ } -+ break; -+ case 2: -+ if (c->ext_clock) -+ c->transceiver = 1; -+ if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { -+ c->caps &= ~MMC_CAP_8_BIT_DATA; -+ c->caps |= MMC_CAP_4_BIT_DATA; -+ } -+ /* FALLTHROUGH */ -+ case 3: -+ if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { -+ /* off-chip level shifting, or none */ -+ mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; -+ mmc->slots[0].after_set_reg = NULL; -+ } -+ break; -+ case 4: -+ case 5: -+ mmc->slots[0].before_set_reg = NULL; -+ mmc->slots[0].after_set_reg = NULL; -+ break; -+ default: -+ pr_err("MMC%d configuration not supported!\n", c->mmc); -+ kfree(hc_name); -+ return -ENODEV; -+ } -+ return 0; -+} -+ -+static struct omap_device_pm_latency omap_hsmmc_latency[] = { -+ [0] = { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -+ }, -+ /* -+ * XXX There should also be an entry here to power off/on the -+ * MMC regulators/PBIAS cells, etc. -+ */ -+}; -+ -+#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16 -+ -+void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr) -+{ -+ struct omap_hwmod *oh; -+ struct omap_device *od; -+ struct omap_device_pm_latency *ohl; -+ char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN]; -+ struct omap_mmc_platform_data *mmc_data; -+ struct omap_mmc_dev_attr *mmc_dev_attr; -+ char *name; -+ int l; -+ int ohl_cnt = 0; -+ -+ mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL); -+ if (!mmc_data) { -+ pr_err("Cannot allocate memory for mmc device!\n"); -+ goto done; -+ } -+ -+ if (omap_hsmmc_pdata_init(hsmmcinfo, mmc_data) < 0) { -+ pr_err("%s fails!\n", __func__); -+ goto done; -+ } -+ omap_hsmmc_mux(mmc_data, (ctrl_nr - 1)); -+ -+ name = "omap_hsmmc"; -+ ohl = omap_hsmmc_latency; -+ ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency); -+ -+ l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN, -+ "mmc%d", ctrl_nr); -+ WARN(l >= MAX_OMAP_MMC_HWMOD_NAME_LEN, -+ "String buffer overflow in MMC%d device setup\n", ctrl_nr); -+ oh = omap_hwmod_lookup(oh_name); -+ if (!oh) { -+ pr_err("Could not look up %s\n", oh_name); -+ kfree(mmc_data->slots[0].name); -+ goto done; -+ } -+ -+ if (oh->dev_attr != NULL) { -+ mmc_dev_attr = oh->dev_attr; -+ mmc_data->controller_flags = mmc_dev_attr->flags; -+ } -+ -+ od = omap_device_build(name, ctrl_nr - 1, oh, mmc_data, -+ sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false); -+ if (IS_ERR(od)) { -+ WARN(1, "Cant build omap_device for %s:%s.\n", name, oh->name); -+ kfree(mmc_data->slots[0].name); -+ goto done; -+ } -+ /* -+ * return device handle to board setup code -+ * required to populate for regulator framework structure -+ */ -+ hsmmcinfo->dev = &od->pdev.dev; -+ -+done: -+ kfree(mmc_data); -+} - - void __init omap2_hsmmc_init(struct omap2_hsmmc_info *controllers) - { -- struct omap2_hsmmc_info *c; -- int nr_hsmmc = ARRAY_SIZE(hsmmc_data); -- int i; - u32 reg; - - if (!cpu_is_omap44xx()) { -@@ -236,142 +506,9 @@ - omap4_ctrl_pad_writel(reg, control_mmc1); - } - -- for (c = controllers; c->mmc; c++) { -- struct hsmmc_controller *hc = hsmmc + c->mmc - 1; -- struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; -- -- if (!c->mmc || c->mmc > nr_hsmmc) { -- pr_debug("MMC%d: no such controller\n", c->mmc); -- continue; -- } -- if (mmc) { -- pr_debug("MMC%d: already configured\n", c->mmc); -- continue; -- } -- -- mmc = kzalloc(sizeof(struct omap_mmc_platform_data), -- GFP_KERNEL); -- if (!mmc) { -- pr_err("Cannot allocate memory for mmc device!\n"); -- goto done; -- } -- -- if (c->name) -- strncpy(hc->name, c->name, HSMMC_NAME_LEN); -- else -- snprintf(hc->name, ARRAY_SIZE(hc->name), -- "mmc%islot%i", c->mmc, 1); -- mmc->slots[0].name = hc->name; -- mmc->nr_slots = 1; -- mmc->slots[0].caps = c->caps; -- mmc->slots[0].internal_clock = !c->ext_clock; -- mmc->dma_mask = 0xffffffff; -- if (cpu_is_omap44xx()) -- mmc->reg_offset = OMAP4_MMC_REG_OFFSET; -- else -- mmc->reg_offset = 0; -- -- mmc->get_context_loss_count = hsmmc_get_context_loss; -- -- mmc->slots[0].switch_pin = c->gpio_cd; -- mmc->slots[0].gpio_wp = c->gpio_wp; -- -- mmc->slots[0].remux = c->remux; -- mmc->slots[0].init_card = c->init_card; -- -- if (c->cover_only) -- mmc->slots[0].cover = 1; -- -- if (c->nonremovable) -- mmc->slots[0].nonremovable = 1; -- -- if (c->power_saving) -- mmc->slots[0].power_saving = 1; -- -- if (c->no_off) -- mmc->slots[0].no_off = 1; -- -- if (c->vcc_aux_disable_is_sleep) -- mmc->slots[0].vcc_aux_disable_is_sleep = 1; -- -- /* NOTE: MMC slots should have a Vcc regulator set up. -- * This may be from a TWL4030-family chip, another -- * controllable regulator, or a fixed supply. -- * -- * temporary HACK: ocr_mask instead of fixed supply -- */ -- mmc->slots[0].ocr_mask = c->ocr_mask; -- -- if (cpu_is_omap3517() || cpu_is_omap3505()) -- mmc->slots[0].set_power = nop_mmc_set_power; -- else -- mmc->slots[0].features |= HSMMC_HAS_PBIAS; -- -- if (cpu_is_omap44xx() && (omap_rev() > OMAP4430_REV_ES1_0)) -- mmc->slots[0].features |= HSMMC_HAS_UPDATED_RESET; -- -- switch (c->mmc) { -- case 1: -- if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { -- /* on-chip level shifting via PBIAS0/PBIAS1 */ -- if (cpu_is_omap44xx()) { -- mmc->slots[0].before_set_reg = -- omap4_hsmmc1_before_set_reg; -- mmc->slots[0].after_set_reg = -- omap4_hsmmc1_after_set_reg; -- } else { -- mmc->slots[0].before_set_reg = -- omap_hsmmc1_before_set_reg; -- mmc->slots[0].after_set_reg = -- omap_hsmmc1_after_set_reg; -- } -- } -- -- /* Omap3630 HSMMC1 supports only 4-bit */ -- if (cpu_is_omap3630() && -- (c->caps & MMC_CAP_8_BIT_DATA)) { -- c->caps &= ~MMC_CAP_8_BIT_DATA; -- c->caps |= MMC_CAP_4_BIT_DATA; -- mmc->slots[0].caps = c->caps; -- } -- break; -- case 2: -- if (c->ext_clock) -- c->transceiver = 1; -- if (c->transceiver && (c->caps & MMC_CAP_8_BIT_DATA)) { -- c->caps &= ~MMC_CAP_8_BIT_DATA; -- c->caps |= MMC_CAP_4_BIT_DATA; -- } -- /* FALLTHROUGH */ -- case 3: -- if (mmc->slots[0].features & HSMMC_HAS_PBIAS) { -- /* off-chip level shifting, or none */ -- mmc->slots[0].before_set_reg = hsmmc23_before_set_reg; -- mmc->slots[0].after_set_reg = NULL; -- } -- break; -- default: -- pr_err("MMC%d configuration not supported!\n", c->mmc); -- kfree(mmc); -- continue; -- } -- hsmmc_data[c->mmc - 1] = mmc; -- } -- -- omap2_init_mmc(hsmmc_data, OMAP34XX_NR_MMC); -- -- /* pass the device nodes back to board setup code */ -- for (c = controllers; c->mmc; c++) { -- struct omap_mmc_platform_data *mmc = hsmmc_data[c->mmc - 1]; -+ for (; controllers->mmc; controllers++) -+ omap_init_hsmmc(controllers, controllers->mmc); - -- if (!c->mmc || c->mmc > nr_hsmmc) -- continue; -- c->dev = mmc->dev; -- } -- --done: -- for (i = 0; i < nr_hsmmc; i++) -- kfree(hsmmc_data[i]); - } - - #endif -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/hwspinlock.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/hwspinlock.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/hwspinlock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/hwspinlock.c 2011-03-09 13:19:09.817507478 +0100 -@@ -0,0 +1,63 @@ -+/* -+ * OMAP hardware spinlock device initialization -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Contact: Simon Que -+ * Hari Kanigeri -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+struct omap_device_pm_latency omap_spinlock_latency[] = { -+ { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -+ } -+}; -+ -+int __init hwspinlocks_init(void) -+{ -+ int retval = 0; -+ struct omap_hwmod *oh; -+ struct omap_device *od; -+ const char *oh_name = "spinlock"; -+ const char *dev_name = "omap_hwspinlock"; -+ -+ /* -+ * Hwmod lookup will fail in case our platform doesn't support the -+ * hardware spinlock module, so it is safe to run this initcall -+ * on all omaps -+ */ -+ oh = omap_hwmod_lookup(oh_name); -+ if (oh == NULL) -+ return -EINVAL; -+ -+ od = omap_device_build(dev_name, 0, oh, NULL, 0, -+ omap_spinlock_latency, -+ ARRAY_SIZE(omap_spinlock_latency), false); -+ if (IS_ERR(od)) { -+ pr_err("Can't build omap_device for %s:%s\n", dev_name, -+ oh_name); -+ retval = PTR_ERR(od); -+ } -+ -+ return retval; -+} -+/* early board code might need to reserve specific hwspinlock instances */ -+postcore_initcall(hwspinlocks_init); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/id.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/id.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/id.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/id.c 2011-03-09 13:19:09.817507478 +0100 -@@ -6,7 +6,7 @@ - * Copyright (C) 2005 Nokia Corporation - * Written by Tony Lindgren - * -- * Copyright (C) 2009 Texas Instruments -+ * Copyright (C) 2009-11 Texas Instruments - * Added OMAP4 support - Santosh Shilimkar - * - * This program is free software; you can redistribute it and/or modify -@@ -191,12 +191,19 @@ - if (!cpu_is_omap3505() && !cpu_is_omap3517()) - omap3_features |= OMAP3_HAS_IO_WAKEUP; - -+ omap3_features |= OMAP3_HAS_SDRC; -+ - /* - * TODO: Get additional info (where applicable) - * e.g. Size of L2 cache. - */ - } - -+static void __init ti816x_check_features(void) -+{ -+ omap3_features = OMAP3_HAS_NEON; -+} -+ - static void __init omap3_check_revision(void) - { - u32 cpuid, idcode; -@@ -287,6 +294,20 @@ - omap_chip.oc |= CHIP_IS_OMAP3630ES1_2; - } - break; -+ case 0xb81e: -+ omap_chip.oc = CHIP_IS_TI816X; -+ -+ switch (rev) { -+ case 0: -+ omap_revision = TI8168_REV_ES1_0; -+ break; -+ case 1: -+ omap_revision = TI8168_REV_ES1_1; -+ break; -+ default: -+ omap_revision = TI8168_REV_ES1_1; -+ } -+ break; - default: - /* Unknown default to latest silicon rev as default*/ - omap_revision = OMAP3630_REV_ES1_2; -@@ -307,7 +328,7 @@ - */ - idcode = read_tap_reg(OMAP_TAP_IDCODE); - hawkeye = (idcode >> 12) & 0xffff; -- rev = (idcode >> 28) & 0xff; -+ rev = (idcode >> 28) & 0xf; - - /* - * Few initial ES2.0 samples IDCODE is same as ES1.0 -@@ -326,22 +347,31 @@ - omap_chip.oc |= CHIP_IS_OMAP4430ES1; - break; - case 1: -+ default: - omap_revision = OMAP4430_REV_ES2_0; - omap_chip.oc |= CHIP_IS_OMAP4430ES2; -+ } -+ break; -+ case 0xb95c: -+ switch (rev) { -+ case 3: -+ omap_revision = OMAP4430_REV_ES2_1; -+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_1; - break; -+ case 4: - default: -- omap_revision = OMAP4430_REV_ES2_0; -- omap_chip.oc |= CHIP_IS_OMAP4430ES2; -- } -- break; -+ omap_revision = OMAP4430_REV_ES2_2; -+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_2; -+ } -+ break; - default: -- /* Unknown default to latest silicon rev as default*/ -- omap_revision = OMAP4430_REV_ES2_0; -- omap_chip.oc |= CHIP_IS_OMAP4430ES2; -+ /* Unknown default to latest silicon rev as default */ -+ omap_revision = OMAP4430_REV_ES2_2; -+ omap_chip.oc |= CHIP_IS_OMAP4430ES2_2; - } - -- pr_info("OMAP%04x ES%d.0\n", -- omap_rev() >> 16, ((omap_rev() >> 12) & 0xf) + 1); -+ pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16, -+ ((omap_rev() >> 12) & 0xf), ((omap_rev() >> 8) & 0xf)); - } - - #define OMAP3_SHOW_FEATURE(feat) \ -@@ -372,6 +402,8 @@ - /* Already set in omap3_check_revision() */ - strcpy(cpu_name, "AM3505"); - } -+ } else if (cpu_is_ti816x()) { -+ strcpy(cpu_name, "TI816X"); - } else if (omap3_has_iva() && omap3_has_sgx()) { - /* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */ - strcpy(cpu_name, "OMAP3430/3530"); -@@ -386,7 +418,7 @@ - strcpy(cpu_name, "OMAP3503"); - } - -- if (cpu_is_omap3630()) { -+ if (cpu_is_omap3630() || cpu_is_ti816x()) { - switch (rev) { - case OMAP_REVBITS_00: - strcpy(cpu_rev, "1.0"); -@@ -462,7 +494,13 @@ - omap24xx_check_revision(); - } else if (cpu_is_omap34xx()) { - omap3_check_revision(); -- omap3_check_features(); -+ -+ /* TI816X doesn't have feature register */ -+ if (!cpu_is_ti816x()) -+ omap3_check_features(); -+ else -+ ti816x_check_features(); -+ - omap3_cpuinfo(); - return; - } else if (cpu_is_omap44xx()) { -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/include/mach/debug-macro.S linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/include/mach/debug-macro.S ---- linux-2.6.38-rc7/arch/arm/mach-omap2/include/mach/debug-macro.S 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/include/mach/debug-macro.S 2011-03-09 13:19:09.819507439 +0100 -@@ -69,6 +69,12 @@ - beq 34f @ configure OMAP3UART4 - cmp \rp, #OMAP4UART4 @ only on 44xx - beq 44f @ configure OMAP4UART4 -+ cmp \rp, #TI816XUART1 @ ti816x UART offsets different -+ beq 81f @ configure UART1 -+ cmp \rp, #TI816XUART2 @ ti816x UART offsets different -+ beq 82f @ configure UART2 -+ cmp \rp, #TI816XUART3 @ ti816x UART offsets different -+ beq 83f @ configure UART3 - cmp \rp, #ZOOM_UART @ only on zoom2/3 - beq 95f @ configure ZOOM_UART - -@@ -91,6 +97,12 @@ - b 98f - 44: mov \rp, #UART_OFFSET(OMAP4_UART4_BASE) - b 98f -+81: mov \rp, #UART_OFFSET(TI816X_UART1_BASE) -+ b 98f -+82: mov \rp, #UART_OFFSET(TI816X_UART2_BASE) -+ b 98f -+83: mov \rp, #UART_OFFSET(TI816X_UART3_BASE) -+ b 98f - 95: ldr \rp, =ZOOM_UART_BASE - mrc p15, 0, \rv, c1, c0 - tst \rv, #1 @ MMU enabled? -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/include/mach/entry-macro.S linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/include/mach/entry-macro.S ---- linux-2.6.38-rc7/arch/arm/mach-omap2/include/mach/entry-macro.S 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/include/mach/entry-macro.S 2011-03-09 13:19:09.819507439 +0100 -@@ -61,6 +61,14 @@ - bne 9998f - ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */ - cmp \irqnr, #0x0 -+ bne 9998f -+ -+ /* -+ * ti816x has additional IRQ pending register. Checking this -+ * register on omap2 & omap3 has no effect (read as 0). -+ */ -+ ldr \irqnr, [\base, #0xf8] /* IRQ pending reg 4 */ -+ cmp \irqnr, #0x0 - 9998: - ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET] - and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */ -@@ -133,6 +141,11 @@ - bne 9999f - ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */ - cmp \irqnr, #0x0 -+#ifdef CONFIG_SOC_OMAPTI816X -+ bne 9999f -+ ldr \irqnr, [\base, #0xf8] /* IRQ pending reg 4 */ -+ cmp \irqnr, #0x0 -+#endif - 9999: - ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET] - and \irqnr, \irqnr, #ACTIVEIRQ_MASK /* Clear spurious bits */ -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/io.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/io.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/io.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/io.c 2011-03-09 13:19:09.820507420 +0100 -@@ -30,7 +30,6 @@ - - #include - #include --#include - #include - - #include "clock2xxx.h" -@@ -66,7 +65,7 @@ - }, - }; - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - static struct map_desc omap242x_io_desc[] __initdata = { - { - .virtual = DSP_MEM_2420_VIRT, -@@ -90,7 +89,7 @@ - - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - static struct map_desc omap243x_io_desc[] __initdata = { - { - .virtual = L4_WK_243X_VIRT, -@@ -175,6 +174,18 @@ - #endif - }; - #endif -+ -+#ifdef CONFIG_SOC_OMAPTI816X -+static struct map_desc omapti816x_io_desc[] __initdata = { -+ { -+ .virtual = L4_34XX_VIRT, -+ .pfn = __phys_to_pfn(L4_34XX_PHYS), -+ .length = L4_34XX_SIZE, -+ .type = MT_DEVICE -+ }, -+}; -+#endif -+ - #ifdef CONFIG_ARCH_OMAP4 - static struct map_desc omap44xx_io_desc[] __initdata = { - { -@@ -241,7 +252,7 @@ - omap_sram_init(); - } - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - void __init omap242x_map_common_io(void) - { - iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); -@@ -250,7 +261,7 @@ - } - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - void __init omap243x_map_common_io(void) - { - iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc)); -@@ -267,6 +278,14 @@ - } - #endif - -+#ifdef CONFIG_SOC_OMAPTI816X -+void __init omapti816x_map_common_io(void) -+{ -+ iotable_init(omapti816x_io_desc, ARRAY_SIZE(omapti816x_io_desc)); -+ _omap2_map_common_io(); -+} -+#endif -+ - #ifdef CONFIG_ARCH_OMAP4 - void __init omap44xx_map_common_io(void) - { -@@ -398,15 +417,10 @@ - void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0, - struct omap_sdrc_params *sdrc_cs1) - { -- omap_serial_early_init(); -- -- omap_hwmod_late_init(); -- -- if (cpu_is_omap24xx() || cpu_is_omap34xx()) { -+ if (cpu_is_omap24xx() || omap3_has_sdrc()) { - omap2_sdrc_init(sdrc_cs0, sdrc_cs1); - _omap2_init_reprogram_sdrc(); - } -- gpmc_init(); - - omap_irq_base_init(); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/iommu2.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/iommu2.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/iommu2.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/iommu2.c 2011-03-09 13:19:09.821507400 +0100 -@@ -145,35 +145,32 @@ - - static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra) - { -- int i; - u32 stat, da; -- const char *err_msg[] = { -- "tlb miss", -- "translation fault", -- "emulation miss", -- "table walk fault", -- "multi hit fault", -- }; -+ u32 errs = 0; - - stat = iommu_read_reg(obj, MMU_IRQSTATUS); - stat &= MMU_IRQ_MASK; -- if (!stat) -+ if (!stat) { -+ *ra = 0; - return 0; -+ } - - da = iommu_read_reg(obj, MMU_FAULT_AD); - *ra = da; - -- dev_err(obj->dev, "%s:\tda:%08x ", __func__, da); -- -- for (i = 0; i < ARRAY_SIZE(err_msg); i++) { -- if (stat & (1 << i)) -- printk("%s ", err_msg[i]); -- } -- printk("\n"); -- -+ if (stat & MMU_IRQ_TLBMISS) -+ errs |= OMAP_IOMMU_ERR_TLB_MISS; -+ if (stat & MMU_IRQ_TRANSLATIONFAULT) -+ errs |= OMAP_IOMMU_ERR_TRANS_FAULT; -+ if (stat & MMU_IRQ_EMUMISS) -+ errs |= OMAP_IOMMU_ERR_EMU_MISS; -+ if (stat & MMU_IRQ_TABLEWALKFAULT) -+ errs |= OMAP_IOMMU_ERR_TBLWALK_FAULT; -+ if (stat & MMU_IRQ_MULTIHITFAULT) -+ errs |= OMAP_IOMMU_ERR_MULTIHIT_FAULT; - iommu_write_reg(obj, stat, MMU_IRQSTATUS); - -- return stat; -+ return errs; - } - - static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr) -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/irq.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/irq.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/irq.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/irq.c 2011-03-09 13:19:09.821507400 +0100 -@@ -61,8 +61,6 @@ - u32 mir[INTCPS_NR_MIR_REGS]; - }; - --static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; -- - /* INTC bank register get/set */ - - static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) -@@ -110,7 +108,7 @@ - unsigned int irq = d->irq; - int offset = irq & (~(IRQ_BITS_PER_REG - 1)); - -- if (cpu_is_omap34xx()) { -+ if (cpu_is_omap34xx() && !cpu_is_ti816x()) { - int spurious = 0; - - /* -@@ -205,6 +203,9 @@ - - BUG_ON(!base); - -+ if (cpu_is_ti816x()) -+ bank->nr_irqs = 128; -+ - /* Static mapping, never released */ - bank->base_reg = ioremap(base, SZ_4K); - if (!bank->base_reg) { -@@ -229,6 +230,8 @@ - } - - #ifdef CONFIG_ARCH_OMAP3 -+static struct omap3_intc_regs intc_context[ARRAY_SIZE(irq_banks)]; -+ - void omap_intc_save_context(void) - { - int ind = 0, i = 0; -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/Kconfig linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/Kconfig ---- linux-2.6.38-rc7/arch/arm/mach-omap2/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/Kconfig 2011-03-09 13:19:09.792507988 +0100 -@@ -53,25 +53,30 @@ - comment "OMAP Core Type" - depends on ARCH_OMAP2 - --config ARCH_OMAP2420 -+config SOC_OMAP2420 - bool "OMAP2420 support" - depends on ARCH_OMAP2 - default y - select OMAP_DM_TIMER - select ARCH_OMAP_OTG - --config ARCH_OMAP2430 -+config SOC_OMAP2430 - bool "OMAP2430 support" - depends on ARCH_OMAP2 - default y - select ARCH_OMAP_OTG - --config ARCH_OMAP3430 -+config SOC_OMAP3430 - bool "OMAP3430 support" - depends on ARCH_OMAP3 - default y - select ARCH_OMAP_OTG - -+config SOC_OMAPTI816X -+ bool "TI816X support" -+ depends on ARCH_OMAP3 -+ default y -+ - config OMAP_PACKAGE_ZAF - bool - -@@ -106,25 +111,25 @@ - - config MACH_OMAP2_TUSB6010 - bool -- depends on ARCH_OMAP2 && ARCH_OMAP2420 -+ depends on ARCH_OMAP2 && SOC_OMAP2420 - default y if MACH_NOKIA_N8X0 - - config MACH_OMAP_H4 - bool "OMAP 2420 H4 board" -- depends on ARCH_OMAP2420 -+ depends on SOC_OMAP2420 - default y - select OMAP_PACKAGE_ZAF - select OMAP_DEBUG_DEVICES - - config MACH_OMAP_APOLLON - bool "OMAP 2420 Apollon board" -- depends on ARCH_OMAP2420 -+ depends on SOC_OMAP2420 - default y - select OMAP_PACKAGE_ZAC - - config MACH_OMAP_2430SDP - bool "OMAP 2430 SDP board" -- depends on ARCH_OMAP2430 -+ depends on SOC_OMAP2430 - default y - select OMAP_PACKAGE_ZAC - -@@ -219,7 +224,7 @@ - - config MACH_NOKIA_N8X0 - bool "Nokia N800/N810" -- depends on ARCH_OMAP2420 -+ depends on SOC_OMAP2420 - default y - select OMAP_PACKAGE_ZAC - select MACH_NOKIA_N800 -@@ -294,12 +299,18 @@ - default y - select OMAP_PACKAGE_CBP - -+config MACH_TI8168EVM -+ bool "TI8168 Evaluation Module" -+ depends on SOC_OMAPTI816X -+ default y -+ - config MACH_OMAP_4430SDP - bool "OMAP 4430 SDP board" - default y - depends on ARCH_OMAP4 - select OMAP_PACKAGE_CBL - select OMAP_PACKAGE_CBS -+ select REGULATOR_FIXED_VOLTAGE - - config MACH_OMAP4_PANDA - bool "OMAP4 Panda Board" -@@ -307,6 +318,7 @@ - depends on ARCH_OMAP4 - select OMAP_PACKAGE_CBL - select OMAP_PACKAGE_CBS -+ select REGULATOR_FIXED_VOLTAGE - - config OMAP3_EMU - bool "OMAP3 debugging peripherals" -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/mailbox.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/mailbox.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/mailbox.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/mailbox.c 2011-03-09 13:19:09.821507400 +0100 -@@ -14,12 +14,11 @@ - #include - #include - #include -+#include - #include - #include - - #define MAILBOX_REVISION 0x000 --#define MAILBOX_SYSCONFIG 0x010 --#define MAILBOX_SYSSTATUS 0x014 - #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m)) - #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m)) - #define MAILBOX_MSGSTATUS(m) (0x0c0 + 4 * (m)) -@@ -33,17 +32,6 @@ - #define MAILBOX_IRQ_NEWMSG(m) (1 << (2 * (m))) - #define MAILBOX_IRQ_NOTFULL(m) (1 << (2 * (m) + 1)) - --/* SYSCONFIG: register bit definition */ --#define AUTOIDLE (1 << 0) --#define SOFTRESET (1 << 1) --#define SMARTIDLE (2 << 3) --#define OMAP4_SOFTRESET (1 << 0) --#define OMAP4_NOIDLE (1 << 2) --#define OMAP4_SMARTIDLE (2 << 2) -- --/* SYSSTATUS: register bit definition */ --#define RESETDONE (1 << 0) -- - #define MBOX_REG_SIZE 0x120 - - #define OMAP4_MBOX_REG_SIZE 0x130 -@@ -70,8 +58,6 @@ - unsigned long irqdisable; - }; - --static struct clk *mbox_ick_handle; -- - static void omap2_mbox_enable_irq(struct omap_mbox *mbox, - omap_mbox_type_t irq); - -@@ -89,53 +75,13 @@ - static int omap2_mbox_startup(struct omap_mbox *mbox) - { - u32 l; -- unsigned long timeout; - -- mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); -- if (IS_ERR(mbox_ick_handle)) { -- printk(KERN_ERR "Could not get mailboxes_ick: %ld\n", -- PTR_ERR(mbox_ick_handle)); -- return PTR_ERR(mbox_ick_handle); -- } -- clk_enable(mbox_ick_handle); -- -- if (cpu_is_omap44xx()) { -- mbox_write_reg(OMAP4_SOFTRESET, MAILBOX_SYSCONFIG); -- timeout = jiffies + msecs_to_jiffies(20); -- do { -- l = mbox_read_reg(MAILBOX_SYSCONFIG); -- if (!(l & OMAP4_SOFTRESET)) -- break; -- } while (!time_after(jiffies, timeout)); -- -- if (l & OMAP4_SOFTRESET) { -- pr_err("Can't take mailbox out of reset\n"); -- return -ENODEV; -- } -- } else { -- mbox_write_reg(SOFTRESET, MAILBOX_SYSCONFIG); -- timeout = jiffies + msecs_to_jiffies(20); -- do { -- l = mbox_read_reg(MAILBOX_SYSSTATUS); -- if (l & RESETDONE) -- break; -- } while (!time_after(jiffies, timeout)); -- -- if (!(l & RESETDONE)) { -- pr_err("Can't take mailbox out of reset\n"); -- return -ENODEV; -- } -- } -+ pm_runtime_enable(mbox->dev->parent); -+ pm_runtime_get_sync(mbox->dev->parent); - - l = mbox_read_reg(MAILBOX_REVISION); - pr_debug("omap mailbox rev %d.%d\n", (l & 0xf0) >> 4, (l & 0x0f)); - -- if (cpu_is_omap44xx()) -- l = OMAP4_SMARTIDLE; -- else -- l = SMARTIDLE | AUTOIDLE; -- mbox_write_reg(l, MAILBOX_SYSCONFIG); -- - omap2_mbox_enable_irq(mbox, IRQ_RX); - - return 0; -@@ -143,9 +89,8 @@ - - static void omap2_mbox_shutdown(struct omap_mbox *mbox) - { -- clk_disable(mbox_ick_handle); -- clk_put(mbox_ick_handle); -- mbox_ick_handle = NULL; -+ pm_runtime_put_sync(mbox->dev->parent); -+ pm_runtime_disable(mbox->dev->parent); - } - - /* Mailbox FIFO handle functions */ -@@ -310,7 +255,7 @@ - struct omap_mbox *omap3_mboxes[] = { &mbox_dsp_info, NULL }; - #endif - --#if defined(CONFIG_ARCH_OMAP2420) -+#if defined(CONFIG_SOC_OMAP2420) - /* IVA */ - static struct omap_mbox2_priv omap2_mbox_iva_priv = { - .tx_fifo = { -@@ -398,14 +343,14 @@ - else if (cpu_is_omap34xx()) { - list = omap3_mboxes; - -- list[0]->irq = platform_get_irq_byname(pdev, "dsp"); -+ list[0]->irq = platform_get_irq(pdev, 0); - } - #endif - #if defined(CONFIG_ARCH_OMAP2) - else if (cpu_is_omap2430()) { - list = omap2_mboxes; - -- list[0]->irq = platform_get_irq_byname(pdev, "dsp"); -+ list[0]->irq = platform_get_irq(pdev, 0); - } else if (cpu_is_omap2420()) { - list = omap2_mboxes; - -@@ -417,8 +362,7 @@ - else if (cpu_is_omap44xx()) { - list = omap4_mboxes; - -- list[0]->irq = list[1]->irq = -- platform_get_irq_byname(pdev, "mbox"); -+ list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0); - } - #endif - else { -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/Makefile linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/Makefile ---- linux-2.6.38-rc7/arch/arm/mach-omap2/Makefile 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/Makefile 2011-03-09 13:19:09.793507967 +0100 -@@ -31,8 +31,8 @@ - AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a$(plus_sec) - - # Functions loaded to SRAM --obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o --obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o -+obj-$(CONFIG_SOC_OMAP2420) += sram242x.o -+obj-$(CONFIG_SOC_OMAP2430) += sram243x.o - obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o - - AFLAGS_sram242x.o :=-Wa,-march=armv6 -@@ -40,8 +40,8 @@ - AFLAGS_sram34xx.o :=-Wa,-march=armv7-a - - # Pin multiplexing --obj-$(CONFIG_ARCH_OMAP2420) += mux2420.o --obj-$(CONFIG_ARCH_OMAP2430) += mux2430.o -+obj-$(CONFIG_SOC_OMAP2420) += mux2420.o -+obj-$(CONFIG_SOC_OMAP2430) += mux2430.o - obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o - obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o - -@@ -113,8 +113,8 @@ - clkt2xxx_dpllcore.o \ - clkt2xxx_virt_prcm_set.o \ - clkt2xxx_apll.o clkt2xxx_osc.o --obj-$(CONFIG_ARCH_OMAP2420) += clock2420_data.o --obj-$(CONFIG_ARCH_OMAP2430) += clock2430.o clock2430_data.o -+obj-$(CONFIG_SOC_OMAP2420) += clock2420_data.o -+obj-$(CONFIG_SOC_OMAP2430) += clock2430.o clock2430_data.o - obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o \ - clock34xx.o clkt34xx_dpll3m2.o \ - clock3517.o clock36xx.o \ -@@ -123,12 +123,12 @@ - dpll3xxx.o - - # OMAP2 clock rate set data (old "OPP" data) --obj-$(CONFIG_ARCH_OMAP2420) += opp2420_data.o --obj-$(CONFIG_ARCH_OMAP2430) += opp2430_data.o -+obj-$(CONFIG_SOC_OMAP2420) += opp2420_data.o -+obj-$(CONFIG_SOC_OMAP2430) += opp2430_data.o - - # hwmod data --obj-$(CONFIG_ARCH_OMAP2420) += omap_hwmod_2420_data.o --obj-$(CONFIG_ARCH_OMAP2430) += omap_hwmod_2430_data.o -+obj-$(CONFIG_SOC_OMAP2420) += omap_hwmod_2420_data.o -+obj-$(CONFIG_SOC_OMAP2430) += omap_hwmod_2430_data.o - obj-$(CONFIG_ARCH_OMAP3) += omap_hwmod_3xxx_data.o - obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o - -@@ -218,12 +218,14 @@ - hsmmc.o \ - omap_phy_internal.o - --obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o -+obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \ -+ omap_phy_internal.o \ - - obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o - - obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \ - hsmmc.o -+obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o - # Platform specific device init code - usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o - obj-y += $(usbfs-m) $(usbfs-y) -@@ -242,3 +244,7 @@ - - smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o - obj-y += $(smsc911x-m) $(smsc911x-y) -+obj-$(CONFIG_ARCH_OMAP4) += hwspinlock.o -+ -+disp-$(CONFIG_OMAP2_DSS) := display.o -+obj-y += $(disp-m) $(disp-y) -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/mcbsp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/mcbsp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/mcbsp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/mcbsp.c 2011-03-09 13:19:09.821507400 +0100 -@@ -22,10 +22,11 @@ - #include - #include - #include -+#include -+#include - - #include "control.h" - -- - /* McBSP internal signal muxing functions */ - - void omap2_mcbsp1_mux_clkr_src(u8 mux) -@@ -83,7 +84,7 @@ - return -EINVAL; - } - -- clk_disable(mcbsp->fclk); -+ pm_runtime_put_sync(mcbsp->dev); - - r = clk_set_parent(mcbsp->fclk, fck_src); - if (IS_ERR_VALUE(r)) { -@@ -93,7 +94,7 @@ - return -EINVAL; - } - -- clk_enable(mcbsp->fclk); -+ pm_runtime_get_sync(mcbsp->dev); - - clk_put(fck_src); - -@@ -101,196 +102,70 @@ - } - EXPORT_SYMBOL(omap2_mcbsp_set_clks_src); - -- --/* Platform data */ -- --#ifdef CONFIG_ARCH_OMAP2420 --static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { -+struct omap_device_pm_latency omap2_mcbsp_latency[] = { - { -- .phys_base = OMAP24XX_MCBSP1_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, -- .rx_irq = INT_24XX_MCBSP1_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP1_IRQ_TX, -- }, -- { -- .phys_base = OMAP24XX_MCBSP2_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, -- .rx_irq = INT_24XX_MCBSP2_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP2_IRQ_TX, -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, - }; --#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) --#define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) --#else --#define omap2420_mcbsp_pdata NULL --#define OMAP2420_MCBSP_PDATA_SZ 0 --#define OMAP2420_MCBSP_REG_NUM 0 --#endif - --#ifdef CONFIG_ARCH_OMAP2430 --static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { -- { -- .phys_base = OMAP24XX_MCBSP1_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, -- .rx_irq = INT_24XX_MCBSP1_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP1_IRQ_TX, -- }, -- { -- .phys_base = OMAP24XX_MCBSP2_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, -- .rx_irq = INT_24XX_MCBSP2_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP2_IRQ_TX, -- }, -- { -- .phys_base = OMAP2430_MCBSP3_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, -- .rx_irq = INT_24XX_MCBSP3_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP3_IRQ_TX, -- }, -- { -- .phys_base = OMAP2430_MCBSP4_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, -- .rx_irq = INT_24XX_MCBSP4_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP4_IRQ_TX, -- }, -- { -- .phys_base = OMAP2430_MCBSP5_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, -- .rx_irq = INT_24XX_MCBSP5_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP5_IRQ_TX, -- }, --}; --#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) --#define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) --#else --#define omap2430_mcbsp_pdata NULL --#define OMAP2430_MCBSP_PDATA_SZ 0 --#define OMAP2430_MCBSP_REG_NUM 0 --#endif -+static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused) -+{ -+ int id, count = 1; -+ char *name = "omap-mcbsp"; -+ struct omap_hwmod *oh_device[2]; -+ struct omap_mcbsp_platform_data *pdata = NULL; -+ struct omap_device *od; -+ -+ sscanf(oh->name, "mcbsp%d", &id); -+ -+ pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); -+ if (!pdata) { -+ pr_err("%s: No memory for mcbsp\n", __func__); -+ return -ENOMEM; -+ } - --#ifdef CONFIG_ARCH_OMAP3 --static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { -- { -- .phys_base = OMAP34XX_MCBSP1_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, -- .rx_irq = INT_24XX_MCBSP1_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP1_IRQ_TX, -- .buffer_size = 0x80, /* The FIFO has 128 locations */ -- }, -- { -- .phys_base = OMAP34XX_MCBSP2_BASE, -- .phys_base_st = OMAP34XX_MCBSP2_ST_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, -- .rx_irq = INT_24XX_MCBSP2_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP2_IRQ_TX, -- .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ -- }, -- { -- .phys_base = OMAP34XX_MCBSP3_BASE, -- .phys_base_st = OMAP34XX_MCBSP3_ST_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, -- .rx_irq = INT_24XX_MCBSP3_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP3_IRQ_TX, -- .buffer_size = 0x80, /* The FIFO has 128 locations */ -- }, -- { -- .phys_base = OMAP34XX_MCBSP4_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, -- .rx_irq = INT_24XX_MCBSP4_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP4_IRQ_TX, -- .buffer_size = 0x80, /* The FIFO has 128 locations */ -- }, -- { -- .phys_base = OMAP34XX_MCBSP5_BASE, -- .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, -- .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, -- .rx_irq = INT_24XX_MCBSP5_IRQ_RX, -- .tx_irq = INT_24XX_MCBSP5_IRQ_TX, -- .buffer_size = 0x80, /* The FIFO has 128 locations */ -- }, --}; --#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) --#define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) --#else --#define omap34xx_mcbsp_pdata NULL --#define OMAP34XX_MCBSP_PDATA_SZ 0 --#define OMAP34XX_MCBSP_REG_NUM 0 --#endif -+ pdata->mcbsp_config_type = oh->class->rev; - --static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { -- { -- .phys_base = OMAP44XX_MCBSP1_BASE, -- .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, -- .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, -- .tx_irq = OMAP44XX_IRQ_MCBSP1, -- }, -- { -- .phys_base = OMAP44XX_MCBSP2_BASE, -- .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, -- .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, -- .tx_irq = OMAP44XX_IRQ_MCBSP2, -- }, -- { -- .phys_base = OMAP44XX_MCBSP3_BASE, -- .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, -- .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, -- .tx_irq = OMAP44XX_IRQ_MCBSP3, -- }, -- { -- .phys_base = OMAP44XX_MCBSP4_BASE, -- .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, -- .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, -- .tx_irq = OMAP44XX_IRQ_MCBSP4, -- }, --}; --#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) --#define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) -+ if (oh->class->rev == MCBSP_CONFIG_TYPE3) { -+ if (id == 2) -+ /* The FIFO has 1024 + 256 locations */ -+ pdata->buffer_size = 0x500; -+ else -+ /* The FIFO has 128 locations */ -+ pdata->buffer_size = 0x80; -+ } -+ -+ oh_device[0] = oh; -+ -+ if (oh->dev_attr) { -+ oh_device[1] = omap_hwmod_lookup(( -+ (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); -+ count++; -+ } -+ od = omap_device_build_ss(name, id, oh_device, count, pdata, -+ sizeof(*pdata), omap2_mcbsp_latency, -+ ARRAY_SIZE(omap2_mcbsp_latency), false); -+ kfree(pdata); -+ if (IS_ERR(od)) { -+ pr_err("%s: Cant build omap_device for %s:%s.\n", __func__, -+ name, oh->name); -+ return PTR_ERR(od); -+ } -+ omap_mcbsp_count++; -+ return 0; -+} - - static int __init omap2_mcbsp_init(void) - { -- if (cpu_is_omap2420()) { -- omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16); -- } else if (cpu_is_omap2430()) { -- omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32); -- } else if (cpu_is_omap34xx()) { -- omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32); -- } else if (cpu_is_omap44xx()) { -- omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; -- omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32); -- } -+ omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); - - mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), - GFP_KERNEL); - if (!mcbsp_ptr) - return -ENOMEM; - -- if (cpu_is_omap2420()) -- omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, -- OMAP2420_MCBSP_PDATA_SZ); -- if (cpu_is_omap2430()) -- omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, -- OMAP2430_MCBSP_PDATA_SZ); -- if (cpu_is_omap34xx()) -- omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, -- OMAP34XX_MCBSP_PDATA_SZ); -- if (cpu_is_omap44xx()) -- omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, -- OMAP44XX_MCBSP_PDATA_SZ); -- - return omap_mcbsp_init(); - } - arch_initcall(omap2_mcbsp_init); -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_2420_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_2420_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_2420_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_2420_data.c 2011-03-09 13:19:09.827507277 +0100 -@@ -18,6 +18,10 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - - #include "omap_hwmod_common_data.h" - -@@ -38,12 +42,18 @@ - static struct omap_hwmod omap2420_iva_hwmod; - static struct omap_hwmod omap2420_l3_main_hwmod; - static struct omap_hwmod omap2420_l4_core_hwmod; -+static struct omap_hwmod omap2420_dss_core_hwmod; -+static struct omap_hwmod omap2420_dss_dispc_hwmod; -+static struct omap_hwmod omap2420_dss_rfbi_hwmod; -+static struct omap_hwmod omap2420_dss_venc_hwmod; - static struct omap_hwmod omap2420_wd_timer2_hwmod; - static struct omap_hwmod omap2420_gpio1_hwmod; - static struct omap_hwmod omap2420_gpio2_hwmod; - static struct omap_hwmod omap2420_gpio3_hwmod; - static struct omap_hwmod omap2420_gpio4_hwmod; - static struct omap_hwmod omap2420_dma_system_hwmod; -+static struct omap_hwmod omap2420_mcspi1_hwmod; -+static struct omap_hwmod omap2420_mcspi2_hwmod; - - /* L3 -> L4_CORE interface */ - static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = { -@@ -64,6 +74,19 @@ - &omap2420_mpu__l3_main, - }; - -+/* DSS -> l3 */ -+static struct omap_hwmod_ocp_if omap2420_dss__l3 = { -+ .master = &omap2420_dss_core_hwmod, -+ .slave = &omap2420_l3_main_hwmod, -+ .fw = { -+ .omap2 = { -+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS, -+ .flags = OMAP_FIREWALL_L3, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* Master interfaces on the L3 interconnect */ - static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = { - &omap2420_l3_main__l4_core, -@@ -87,6 +110,44 @@ - static struct omap_hwmod omap2420_uart3_hwmod; - static struct omap_hwmod omap2420_i2c1_hwmod; - static struct omap_hwmod omap2420_i2c2_hwmod; -+static struct omap_hwmod omap2420_mcbsp1_hwmod; -+static struct omap_hwmod omap2420_mcbsp2_hwmod; -+ -+/* l4 core -> mcspi1 interface */ -+static struct omap_hwmod_addr_space omap2420_mcspi1_addr_space[] = { -+ { -+ .pa_start = 0x48098000, -+ .pa_end = 0x480980ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi1 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_mcspi1_hwmod, -+ .clk = "mcspi1_ick", -+ .addr = omap2420_mcspi1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2420_mcspi1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi2 interface */ -+static struct omap_hwmod_addr_space omap2420_mcspi2_addr_space[] = { -+ { -+ .pa_start = 0x4809a000, -+ .pa_end = 0x4809a0ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2420_l4_core__mcspi2 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_mcspi2_hwmod, -+ .clk = "mcspi2_ick", -+ .addr = omap2420_mcspi2_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2420_mcspi2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; - - /* L4_CORE -> L4_WKUP interface */ - static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { -@@ -279,6 +340,625 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) - }; - -+/* Timer Common */ -+static struct omap_hwmod_class_sysconfig omap2420_timer_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2420_timer_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap2420_timer_sysc, -+ .rev = OMAP_TIMER_IP_VERSION_1, -+}; -+ -+/* timer1 */ -+static struct omap_hwmod omap2420_timer1_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer1_mpu_irqs[] = { -+ { .irq = 37, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer1_addrs[] = { -+ { -+ .pa_start = 0x48028000, -+ .pa_end = 0x48028000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_wkup -> timer1 */ -+static struct omap_hwmod_ocp_if omap2420_l4_wkup__timer1 = { -+ .master = &omap2420_l4_wkup_hwmod, -+ .slave = &omap2420_timer1_hwmod, -+ .clk = "gpt1_ick", -+ .addr = omap2420_timer1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer1 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer1_slaves[] = { -+ &omap2420_l4_wkup__timer1, -+}; -+ -+/* timer1 hwmod */ -+static struct omap_hwmod omap2420_timer1_hwmod = { -+ .name = "timer1", -+ .mpu_irqs = omap2420_timer1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer1_mpu_irqs), -+ .main_clk = "gpt1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT1_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer1_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer2 */ -+static struct omap_hwmod omap2420_timer2_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer2_mpu_irqs[] = { -+ { .irq = 38, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer2_addrs[] = { -+ { -+ .pa_start = 0x4802a000, -+ .pa_end = 0x4802a000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer2 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer2 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer2_hwmod, -+ .clk = "gpt2_ick", -+ .addr = omap2420_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer2 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer2_slaves[] = { -+ &omap2420_l4_core__timer2, -+}; -+ -+/* timer2 hwmod */ -+static struct omap_hwmod omap2420_timer2_hwmod = { -+ .name = "timer2", -+ .mpu_irqs = omap2420_timer2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer2_mpu_irqs), -+ .main_clk = "gpt2_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT2_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer2_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer3 */ -+static struct omap_hwmod omap2420_timer3_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer3_mpu_irqs[] = { -+ { .irq = 39, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer3_addrs[] = { -+ { -+ .pa_start = 0x48078000, -+ .pa_end = 0x48078000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer3 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer3 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer3_hwmod, -+ .clk = "gpt3_ick", -+ .addr = omap2420_timer3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer3 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer3_slaves[] = { -+ &omap2420_l4_core__timer3, -+}; -+ -+/* timer3 hwmod */ -+static struct omap_hwmod omap2420_timer3_hwmod = { -+ .name = "timer3", -+ .mpu_irqs = omap2420_timer3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer3_mpu_irqs), -+ .main_clk = "gpt3_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT3_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer3_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer4 */ -+static struct omap_hwmod omap2420_timer4_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer4_mpu_irqs[] = { -+ { .irq = 40, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer4_addrs[] = { -+ { -+ .pa_start = 0x4807a000, -+ .pa_end = 0x4807a000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer4 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer4 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer4_hwmod, -+ .clk = "gpt4_ick", -+ .addr = omap2420_timer4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer4 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer4_slaves[] = { -+ &omap2420_l4_core__timer4, -+}; -+ -+/* timer4 hwmod */ -+static struct omap_hwmod omap2420_timer4_hwmod = { -+ .name = "timer4", -+ .mpu_irqs = omap2420_timer4_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer4_mpu_irqs), -+ .main_clk = "gpt4_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT4_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer4_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer5 */ -+static struct omap_hwmod omap2420_timer5_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer5_mpu_irqs[] = { -+ { .irq = 41, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer5_addrs[] = { -+ { -+ .pa_start = 0x4807c000, -+ .pa_end = 0x4807c000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer5 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer5 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer5_hwmod, -+ .clk = "gpt5_ick", -+ .addr = omap2420_timer5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer5 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer5_slaves[] = { -+ &omap2420_l4_core__timer5, -+}; -+ -+/* timer5 hwmod */ -+static struct omap_hwmod omap2420_timer5_hwmod = { -+ .name = "timer5", -+ .mpu_irqs = omap2420_timer5_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer5_mpu_irqs), -+ .main_clk = "gpt5_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT5_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer5_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+ -+/* timer6 */ -+static struct omap_hwmod omap2420_timer6_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer6_mpu_irqs[] = { -+ { .irq = 42, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer6_addrs[] = { -+ { -+ .pa_start = 0x4807e000, -+ .pa_end = 0x4807e000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer6 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer6 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer6_hwmod, -+ .clk = "gpt6_ick", -+ .addr = omap2420_timer6_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer6_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer6 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer6_slaves[] = { -+ &omap2420_l4_core__timer6, -+}; -+ -+/* timer6 hwmod */ -+static struct omap_hwmod omap2420_timer6_hwmod = { -+ .name = "timer6", -+ .mpu_irqs = omap2420_timer6_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer6_mpu_irqs), -+ .main_clk = "gpt6_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT6_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer6_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer6_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer7 */ -+static struct omap_hwmod omap2420_timer7_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer7_mpu_irqs[] = { -+ { .irq = 43, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer7_addrs[] = { -+ { -+ .pa_start = 0x48080000, -+ .pa_end = 0x48080000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer7 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer7 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer7_hwmod, -+ .clk = "gpt7_ick", -+ .addr = omap2420_timer7_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer7_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer7 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer7_slaves[] = { -+ &omap2420_l4_core__timer7, -+}; -+ -+/* timer7 hwmod */ -+static struct omap_hwmod omap2420_timer7_hwmod = { -+ .name = "timer7", -+ .mpu_irqs = omap2420_timer7_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer7_mpu_irqs), -+ .main_clk = "gpt7_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT7_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer7_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer7_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer8 */ -+static struct omap_hwmod omap2420_timer8_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer8_mpu_irqs[] = { -+ { .irq = 44, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer8_addrs[] = { -+ { -+ .pa_start = 0x48082000, -+ .pa_end = 0x48082000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer8 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer8 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer8_hwmod, -+ .clk = "gpt8_ick", -+ .addr = omap2420_timer8_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer8_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer8 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer8_slaves[] = { -+ &omap2420_l4_core__timer8, -+}; -+ -+/* timer8 hwmod */ -+static struct omap_hwmod omap2420_timer8_hwmod = { -+ .name = "timer8", -+ .mpu_irqs = omap2420_timer8_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer8_mpu_irqs), -+ .main_clk = "gpt8_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT8_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer8_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer8_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer9 */ -+static struct omap_hwmod omap2420_timer9_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer9_mpu_irqs[] = { -+ { .irq = 45, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer9_addrs[] = { -+ { -+ .pa_start = 0x48084000, -+ .pa_end = 0x48084000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer9 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer9 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer9_hwmod, -+ .clk = "gpt9_ick", -+ .addr = omap2420_timer9_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer9_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer9 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer9_slaves[] = { -+ &omap2420_l4_core__timer9, -+}; -+ -+/* timer9 hwmod */ -+static struct omap_hwmod omap2420_timer9_hwmod = { -+ .name = "timer9", -+ .mpu_irqs = omap2420_timer9_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer9_mpu_irqs), -+ .main_clk = "gpt9_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT9_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer9_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer9_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer10 */ -+static struct omap_hwmod omap2420_timer10_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer10_mpu_irqs[] = { -+ { .irq = 46, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer10_addrs[] = { -+ { -+ .pa_start = 0x48086000, -+ .pa_end = 0x48086000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer10 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer10 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer10_hwmod, -+ .clk = "gpt10_ick", -+ .addr = omap2420_timer10_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer10_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer10 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer10_slaves[] = { -+ &omap2420_l4_core__timer10, -+}; -+ -+/* timer10 hwmod */ -+static struct omap_hwmod omap2420_timer10_hwmod = { -+ .name = "timer10", -+ .mpu_irqs = omap2420_timer10_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer10_mpu_irqs), -+ .main_clk = "gpt10_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT10_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer10_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer10_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer11 */ -+static struct omap_hwmod omap2420_timer11_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer11_mpu_irqs[] = { -+ { .irq = 47, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer11_addrs[] = { -+ { -+ .pa_start = 0x48088000, -+ .pa_end = 0x48088000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer11 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer11 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer11_hwmod, -+ .clk = "gpt11_ick", -+ .addr = omap2420_timer11_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer11_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer11 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer11_slaves[] = { -+ &omap2420_l4_core__timer11, -+}; -+ -+/* timer11 hwmod */ -+static struct omap_hwmod omap2420_timer11_hwmod = { -+ .name = "timer11", -+ .mpu_irqs = omap2420_timer11_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer11_mpu_irqs), -+ .main_clk = "gpt11_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT11_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer11_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer11_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ -+/* timer12 */ -+static struct omap_hwmod omap2420_timer12_hwmod; -+static struct omap_hwmod_irq_info omap2420_timer12_mpu_irqs[] = { -+ { .irq = 48, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_timer12_addrs[] = { -+ { -+ .pa_start = 0x4808a000, -+ .pa_end = 0x4808a000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer12 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__timer12 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_timer12_hwmod, -+ .clk = "gpt12_ick", -+ .addr = omap2420_timer12_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_timer12_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer12 slave port */ -+static struct omap_hwmod_ocp_if *omap2420_timer12_slaves[] = { -+ &omap2420_l4_core__timer12, -+}; -+ -+/* timer12 hwmod */ -+static struct omap_hwmod omap2420_timer12_hwmod = { -+ .name = "timer12", -+ .mpu_irqs = omap2420_timer12_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_timer12_mpu_irqs), -+ .main_clk = "gpt12_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT12_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_timer12_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_timer12_slaves), -+ .class = &omap2420_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) -+}; -+ - /* l4_wkup -> wd_timer2 */ - static struct omap_hwmod_addr_space omap2420_wd_timer2_addrs[] = { - { -@@ -354,120 +1034,404 @@ - .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_class uart_class = { -- .name = "uart", -- .sysc = &uart_sysc, -+static struct omap_hwmod_class uart_class = { -+ .name = "uart", -+ .sysc = &uart_sysc, -+}; -+ -+/* UART1 */ -+ -+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -+ { .irq = INT_24XX_UART1_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2420_uart1_slaves[] = { -+ &omap2_l4_core__uart1, -+}; -+ -+static struct omap_hwmod omap2420_uart1_hwmod = { -+ .name = "uart1", -+ .mpu_irqs = uart1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -+ .sdma_reqs = uart1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -+ .main_clk = "uart1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_UART1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_uart1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_uart1_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* UART2 */ -+ -+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -+ { .irq = INT_24XX_UART2_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2420_uart2_slaves[] = { -+ &omap2_l4_core__uart2, -+}; -+ -+static struct omap_hwmod omap2420_uart2_hwmod = { -+ .name = "uart2", -+ .mpu_irqs = uart2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -+ .sdma_reqs = uart2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -+ .main_clk = "uart2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_UART2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_uart2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_uart2_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* UART3 */ -+ -+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -+ { .irq = INT_24XX_UART3_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2420_uart3_slaves[] = { -+ &omap2_l4_core__uart3, -+}; -+ -+static struct omap_hwmod omap2420_uart3_hwmod = { -+ .name = "uart3", -+ .mpu_irqs = uart3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -+ .sdma_reqs = uart3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -+ .main_clk = "uart3_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 2, -+ .module_bit = OMAP24XX_EN_UART3_SHIFT, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_uart3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_uart3_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* -+ * 'dss' class -+ * display sub-system -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2420_dss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2420_dss_hwmod_class = { -+ .name = "dss", -+ .sysc = &omap2420_dss_sysc, -+}; -+ -+static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = { -+ { .name = "dispc", .dma_req = 5 }, -+}; -+ -+/* dss */ -+/* dss master ports */ -+static struct omap_hwmod_ocp_if *omap2420_dss_masters[] = { -+ &omap2420_dss__l3, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_dss_addrs[] = { -+ { -+ .pa_start = 0x48050000, -+ .pa_end = 0x480503FF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__dss = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_dss_core_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2420_dss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_dss_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = { -+ &omap2420_l4_core__dss, -+}; -+ -+static struct omap_hwmod_opt_clk dss_opt_clks[] = { -+ { .role = "tv_clk", .clk = "dss_54m_fck" }, -+ { .role = "sys_clk", .clk = "dss2_fck" }, -+}; -+ -+static struct omap_hwmod omap2420_dss_core_hwmod = { -+ .name = "dss_core", -+ .class = &omap2420_dss_hwmod_class, -+ .main_clk = "dss1_fck", /* instead of dss_fck */ -+ .sdma_reqs = omap2420_dss_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs), -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, -+ }, -+ }, -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+ .slaves = omap2420_dss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_slaves), -+ .masters = omap2420_dss_masters, -+ .masters_cnt = ARRAY_SIZE(omap2420_dss_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'dispc' class -+ * display controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2420_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2420_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &omap2420_dispc_sysc, - }; - --/* UART1 */ -+static struct omap_hwmod_irq_info omap2420_dispc_irqs[] = { -+ { .irq = 25 }, -+}; - --static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -- { .irq = INT_24XX_UART1_IRQ, }, -+static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = { -+ { -+ .pa_start = 0x48050400, -+ .pa_end = 0x480507FF, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -+/* l4_core -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_dispc = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_dss_dispc_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2420_dss_dispc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_dss_dispc_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap2420_uart1_slaves[] = { -- &omap2_l4_core__uart1, -+/* dss_dispc slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = { -+ &omap2420_l4_core__dss_dispc, - }; - --static struct omap_hwmod omap2420_uart1_hwmod = { -- .name = "uart1", -- .mpu_irqs = uart1_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -- .sdma_reqs = uart1_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -- .main_clk = "uart1_fck", -+static struct omap_hwmod omap2420_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &omap2420_dispc_hwmod_class, -+ .mpu_irqs = omap2420_dispc_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dispc_irqs), -+ .main_clk = "dss1_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_UART1_SHIFT, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT, -+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, - }, - }, -- .slaves = omap2420_uart1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2420_uart1_slaves), -- .class = &uart_class, -+ .slaves = omap2420_dss_dispc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+ .flags = HWMOD_NO_IDLEST, - }; - --/* UART2 */ -+/* -+ * 'rfbi' class -+ * remote frame buffer interface -+ */ - --static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -- { .irq = INT_24XX_UART2_IRQ, }, -+static struct omap_hwmod_class_sysconfig omap2420_rfbi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -+static struct omap_hwmod_class omap2420_rfbi_hwmod_class = { -+ .name = "rfbi", -+ .sysc = &omap2420_rfbi_sysc, - }; - --static struct omap_hwmod_ocp_if *omap2420_uart2_slaves[] = { -- &omap2_l4_core__uart2, -+static struct omap_hwmod_addr_space omap2420_dss_rfbi_addrs[] = { -+ { -+ .pa_start = 0x48050800, -+ .pa_end = 0x48050BFF, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod omap2420_uart2_hwmod = { -- .name = "uart2", -- .mpu_irqs = uart2_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -- .sdma_reqs = uart2_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -- .main_clk = "uart2_fck", -+/* l4_core -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_rfbi = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_dss_rfbi_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2420_dss_rfbi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_dss_rfbi_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_rfbi slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = { -+ &omap2420_l4_core__dss_rfbi, -+}; -+ -+static struct omap_hwmod omap2420_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap2420_rfbi_hwmod_class, -+ .main_clk = "dss1_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_UART2_SHIFT, -- .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, - }, - }, -- .slaves = omap2420_uart2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2420_uart2_slaves), -- .class = &uart_class, -+ .slaves = omap2420_dss_rfbi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+ .flags = HWMOD_NO_IDLEST, - }; - --/* UART3 */ -+/* -+ * 'venc' class -+ * video encoder -+ */ - --static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -- { .irq = INT_24XX_UART3_IRQ, }, -+static struct omap_hwmod_class omap2420_venc_hwmod_class = { -+ .name = "venc", - }; - --static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -+/* dss_venc */ -+static struct omap_hwmod_addr_space omap2420_dss_venc_addrs[] = { -+ { -+ .pa_start = 0x48050C00, -+ .pa_end = 0x48050FFF, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_ocp_if *omap2420_uart3_slaves[] = { -- &omap2_l4_core__uart3, -+/* l4_core -> dss_venc */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_dss_venc_hwmod, -+ .clk = "dss_54m_fck", -+ .addr = omap2420_dss_venc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_dss_venc_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod omap2420_uart3_hwmod = { -- .name = "uart3", -- .mpu_irqs = uart3_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -- .sdma_reqs = uart3_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -- .main_clk = "uart3_fck", -+/* dss_venc slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = { -+ &omap2420_l4_core__dss_venc, -+}; -+ -+static struct omap_hwmod omap2420_dss_venc_hwmod = { -+ .name = "dss_venc", -+ .class = &omap2420_venc_hwmod_class, -+ .main_clk = "dss1_fck", - .prcm = { - .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, - .module_offs = CORE_MOD, -- .prcm_reg_id = 2, -- .module_bit = OMAP24XX_EN_UART3_SHIFT, -- .idlest_reg_id = 2, -- .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT, - }, - }, -- .slaves = omap2420_uart3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2420_uart3_slaves), -- .class = &uart_class, -+ .slaves = omap2420_dss_venc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_venc_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+ .flags = HWMOD_NO_IDLEST, - }; - - /* I2C common */ -@@ -864,16 +1828,342 @@ - .flags = HWMOD_NO_IDLEST, - }; - -+/* -+ * 'mailbox' class -+ * mailbox module allowing communication between the on-chip processors -+ * using a queued mailbox-interrupt mechanism. -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2420_mailbox_sysc = { -+ .rev_offs = 0x000, -+ .sysc_offs = 0x010, -+ .syss_offs = 0x014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2420_mailbox_hwmod_class = { -+ .name = "mailbox", -+ .sysc = &omap2420_mailbox_sysc, -+}; -+ -+/* mailbox */ -+static struct omap_hwmod omap2420_mailbox_hwmod; -+static struct omap_hwmod_irq_info omap2420_mailbox_irqs[] = { -+ { .name = "dsp", .irq = 26 }, -+ { .name = "iva", .irq = 34 }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_mailbox_addrs[] = { -+ { -+ .pa_start = 0x48094000, -+ .pa_end = 0x480941ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+/* l4_core -> mailbox */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__mailbox = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_mailbox_hwmod, -+ .addr = omap2420_mailbox_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_mailbox_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mailbox slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_mailbox_slaves[] = { -+ &omap2420_l4_core__mailbox, -+}; -+ -+static struct omap_hwmod omap2420_mailbox_hwmod = { -+ .name = "mailbox", -+ .class = &omap2420_mailbox_hwmod_class, -+ .mpu_irqs = omap2420_mailbox_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mailbox_irqs), -+ .main_clk = "mailboxes_ick", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_mailbox_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_mailbox_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* -+ * 'mcspi' class -+ * multichannel serial port interface (mcspi) / master/slave synchronous serial -+ * bus -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2420_mcspi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2420_mcspi_class = { -+ .name = "mcspi", -+ .sysc = &omap2420_mcspi_sysc, -+ .rev = OMAP2_MCSPI_REV, -+}; -+ -+/* mcspi1 */ -+static struct omap_hwmod_irq_info omap2420_mcspi1_mpu_irqs[] = { -+ { .irq = 65 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2420_mcspi1_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */ -+ { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */ -+ { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */ -+ { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */ -+ { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */ -+ { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */ -+ { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */ -+ { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2420_mcspi1_slaves[] = { -+ &omap2420_l4_core__mcspi1, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { -+ .num_chipselect = 4, -+}; -+ -+static struct omap_hwmod omap2420_mcspi1_hwmod = { -+ .name = "mcspi1_hwmod", -+ .mpu_irqs = omap2420_mcspi1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi1_mpu_irqs), -+ .sdma_reqs = omap2420_mcspi1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi1_sdma_reqs), -+ .main_clk = "mcspi1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCSPI1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_mcspi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_mcspi1_slaves), -+ .class = &omap2420_mcspi_class, -+ .dev_attr = &omap_mcspi1_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* mcspi2 */ -+static struct omap_hwmod_irq_info omap2420_mcspi2_mpu_irqs[] = { -+ { .irq = 66 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2420_mcspi2_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */ -+ { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */ -+ { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */ -+ { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2420_mcspi2_slaves[] = { -+ &omap2420_l4_core__mcspi2, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap2420_mcspi2_hwmod = { -+ .name = "mcspi2_hwmod", -+ .mpu_irqs = omap2420_mcspi2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcspi2_mpu_irqs), -+ .sdma_reqs = omap2420_mcspi2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcspi2_sdma_reqs), -+ .main_clk = "mcspi2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCSPI2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_mcspi2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_mcspi2_slaves), -+ .class = &omap2420_mcspi_class, -+ .dev_attr = &omap_mcspi2_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* -+ * 'mcbsp' class -+ * multi channel buffered serial port controller -+ */ -+ -+static struct omap_hwmod_class omap2420_mcbsp_hwmod_class = { -+ .name = "mcbsp", -+}; -+ -+/* mcbsp1 */ -+static struct omap_hwmod_irq_info omap2420_mcbsp1_irqs[] = { -+ { .name = "tx", .irq = 59 }, -+ { .name = "rx", .irq = 60 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2420_mcbsp1_sdma_chs[] = { -+ { .name = "rx", .dma_req = 32 }, -+ { .name = "tx", .dma_req = 31 }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_mcbsp1_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48074000, -+ .pa_end = 0x480740ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp1 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp1 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_mcbsp1_hwmod, -+ .clk = "mcbsp1_ick", -+ .addr = omap2420_mcbsp1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_mcbsp1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp1 slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_mcbsp1_slaves[] = { -+ &omap2420_l4_core__mcbsp1, -+}; -+ -+static struct omap_hwmod omap2420_mcbsp1_hwmod = { -+ .name = "mcbsp1", -+ .class = &omap2420_mcbsp_hwmod_class, -+ .mpu_irqs = omap2420_mcbsp1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcbsp1_irqs), -+ .sdma_reqs = omap2420_mcbsp1_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcbsp1_sdma_chs), -+ .main_clk = "mcbsp1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCBSP1_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_mcbsp1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_mcbsp1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ -+/* mcbsp2 */ -+static struct omap_hwmod_irq_info omap2420_mcbsp2_irqs[] = { -+ { .name = "tx", .irq = 62 }, -+ { .name = "rx", .irq = 63 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2420_mcbsp2_sdma_chs[] = { -+ { .name = "rx", .dma_req = 34 }, -+ { .name = "tx", .dma_req = 33 }, -+}; -+ -+static struct omap_hwmod_addr_space omap2420_mcbsp2_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48076000, -+ .pa_end = 0x480760ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp2 */ -+static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = { -+ .master = &omap2420_l4_core_hwmod, -+ .slave = &omap2420_mcbsp2_hwmod, -+ .clk = "mcbsp2_ick", -+ .addr = omap2420_mcbsp2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2420_mcbsp2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp2 slave ports */ -+static struct omap_hwmod_ocp_if *omap2420_mcbsp2_slaves[] = { -+ &omap2420_l4_core__mcbsp2, -+}; -+ -+static struct omap_hwmod omap2420_mcbsp2_hwmod = { -+ .name = "mcbsp2", -+ .class = &omap2420_mcbsp_hwmod_class, -+ .mpu_irqs = omap2420_mcbsp2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_mcbsp2_irqs), -+ .sdma_reqs = omap2420_mcbsp2_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_mcbsp2_sdma_chs), -+ .main_clk = "mcbsp2_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCBSP2_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, -+ }, -+ }, -+ .slaves = omap2420_mcbsp2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2420_mcbsp2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), -+}; -+ - static __initdata struct omap_hwmod *omap2420_hwmods[] = { - &omap2420_l3_main_hwmod, - &omap2420_l4_core_hwmod, - &omap2420_l4_wkup_hwmod, - &omap2420_mpu_hwmod, - &omap2420_iva_hwmod, -+ -+ &omap2420_timer1_hwmod, -+ &omap2420_timer2_hwmod, -+ &omap2420_timer3_hwmod, -+ &omap2420_timer4_hwmod, -+ &omap2420_timer5_hwmod, -+ &omap2420_timer6_hwmod, -+ &omap2420_timer7_hwmod, -+ &omap2420_timer8_hwmod, -+ &omap2420_timer9_hwmod, -+ &omap2420_timer10_hwmod, -+ &omap2420_timer11_hwmod, -+ &omap2420_timer12_hwmod, -+ - &omap2420_wd_timer2_hwmod, - &omap2420_uart1_hwmod, - &omap2420_uart2_hwmod, - &omap2420_uart3_hwmod, -+ /* dss class */ -+ &omap2420_dss_core_hwmod, -+ &omap2420_dss_dispc_hwmod, -+ &omap2420_dss_rfbi_hwmod, -+ &omap2420_dss_venc_hwmod, -+ /* i2c class */ - &omap2420_i2c1_hwmod, - &omap2420_i2c2_hwmod, - -@@ -885,10 +2175,21 @@ - - /* dma_system class*/ - &omap2420_dma_system_hwmod, -+ -+ /* mailbox class */ -+ &omap2420_mailbox_hwmod, -+ -+ /* mcbsp class */ -+ &omap2420_mcbsp1_hwmod, -+ &omap2420_mcbsp2_hwmod, -+ -+ /* mcspi class */ -+ &omap2420_mcspi1_hwmod, -+ &omap2420_mcspi2_hwmod, - NULL, - }; - - int __init omap2420_hwmod_init(void) - { -- return omap_hwmod_init(omap2420_hwmods); -+ return omap_hwmod_register(omap2420_hwmods); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_2430_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_2430_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_2430_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_2430_data.c 2011-03-09 13:19:09.828507257 +0100 -@@ -18,6 +18,11 @@ - #include - #include - #include -+#include -+#include -+#include -+#include -+#include - - #include "omap_hwmod_common_data.h" - -@@ -38,6 +43,10 @@ - static struct omap_hwmod omap2430_iva_hwmod; - static struct omap_hwmod omap2430_l3_main_hwmod; - static struct omap_hwmod omap2430_l4_core_hwmod; -+static struct omap_hwmod omap2430_dss_core_hwmod; -+static struct omap_hwmod omap2430_dss_dispc_hwmod; -+static struct omap_hwmod omap2430_dss_rfbi_hwmod; -+static struct omap_hwmod omap2430_dss_venc_hwmod; - static struct omap_hwmod omap2430_wd_timer2_hwmod; - static struct omap_hwmod omap2430_gpio1_hwmod; - static struct omap_hwmod omap2430_gpio2_hwmod; -@@ -45,6 +54,16 @@ - static struct omap_hwmod omap2430_gpio4_hwmod; - static struct omap_hwmod omap2430_gpio5_hwmod; - static struct omap_hwmod omap2430_dma_system_hwmod; -+static struct omap_hwmod omap2430_mcbsp1_hwmod; -+static struct omap_hwmod omap2430_mcbsp2_hwmod; -+static struct omap_hwmod omap2430_mcbsp3_hwmod; -+static struct omap_hwmod omap2430_mcbsp4_hwmod; -+static struct omap_hwmod omap2430_mcbsp5_hwmod; -+static struct omap_hwmod omap2430_mcspi1_hwmod; -+static struct omap_hwmod omap2430_mcspi2_hwmod; -+static struct omap_hwmod omap2430_mcspi3_hwmod; -+static struct omap_hwmod omap2430_mmc1_hwmod; -+static struct omap_hwmod omap2430_mmc2_hwmod; - - /* L3 -> L4_CORE interface */ - static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = { -@@ -65,6 +84,19 @@ - &omap2430_mpu__l3_main, - }; - -+/* DSS -> l3 */ -+static struct omap_hwmod_ocp_if omap2430_dss__l3 = { -+ .master = &omap2430_dss_core_hwmod, -+ .slave = &omap2430_l3_main_hwmod, -+ .fw = { -+ .omap2 = { -+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS, -+ .flags = OMAP_FIREWALL_L3, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* Master interfaces on the L3 interconnect */ - static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = { - &omap2430_l3_main__l4_core, -@@ -89,6 +121,16 @@ - static struct omap_hwmod omap2430_i2c1_hwmod; - static struct omap_hwmod omap2430_i2c2_hwmod; - -+static struct omap_hwmod omap2430_usbhsotg_hwmod; -+ -+/* l3_core -> usbhsotg interface */ -+static struct omap_hwmod_ocp_if omap2430_usbhsotg__l3 = { -+ .master = &omap2430_usbhsotg_hwmod, -+ .slave = &omap2430_l3_main_hwmod, -+ .clk = "core_l3_ck", -+ .user = OCP_USER_MPU, -+}; -+ - /* I2C IP block address space length (in bytes) */ - #define OMAP2_I2C_AS_LEN 128 - -@@ -189,6 +231,71 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* -+* usbhsotg interface data -+*/ -+static struct omap_hwmod_addr_space omap2430_usbhsotg_addrs[] = { -+ { -+ .pa_start = OMAP243X_HS_BASE, -+ .pa_end = OMAP243X_HS_BASE + SZ_4K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core ->usbhsotg interface */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__usbhsotg = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_usbhsotg_hwmod, -+ .clk = "usb_l4_ick", -+ .addr = omap2430_usbhsotg_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_usbhsotg_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_usbhsotg_masters[] = { -+ &omap2430_usbhsotg__l3, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_usbhsotg_slaves[] = { -+ &omap2430_l4_core__usbhsotg, -+}; -+ -+/* L4 CORE -> MMC1 interface */ -+static struct omap_hwmod_addr_space omap2430_mmc1_addr_space[] = { -+ { -+ .pa_start = 0x4809c000, -+ .pa_end = 0x4809c1ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc1 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mmc1_hwmod, -+ .clk = "mmchs1_ick", -+ .addr = omap2430_mmc1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_mmc1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* L4 CORE -> MMC2 interface */ -+static struct omap_hwmod_addr_space omap2430_mmc2_addr_space[] = { -+ { -+ .pa_start = 0x480b4000, -+ .pa_end = 0x480b41ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mmc2 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mmc2_hwmod, -+ .addr = omap2430_mmc2_addr_space, -+ .clk = "mmchs2_ick", -+ .addr_cnt = ARRAY_SIZE(omap2430_mmc2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* Slave interfaces on the L4_CORE interconnect */ - static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = { - &omap2430_l3_main__l4_core, -@@ -197,6 +304,8 @@ - /* Master interfaces on the L4_CORE interconnect */ - static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = { - &omap2430_l4_core__l4_wkup, -+ &omap2430_l4_core__mmc1, -+ &omap2430_l4_core__mmc2, - }; - - /* L4 CORE */ -@@ -223,6 +332,60 @@ - static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = { - }; - -+/* l4 core -> mcspi1 interface */ -+static struct omap_hwmod_addr_space omap2430_mcspi1_addr_space[] = { -+ { -+ .pa_start = 0x48098000, -+ .pa_end = 0x480980ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi1 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcspi1_hwmod, -+ .clk = "mcspi1_ick", -+ .addr = omap2430_mcspi1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi2 interface */ -+static struct omap_hwmod_addr_space omap2430_mcspi2_addr_space[] = { -+ { -+ .pa_start = 0x4809a000, -+ .pa_end = 0x4809a0ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi2 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcspi2_hwmod, -+ .clk = "mcspi2_ick", -+ .addr = omap2430_mcspi2_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi3 interface */ -+static struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[] = { -+ { -+ .pa_start = 0x480b8000, -+ .pa_end = 0x480b80ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcspi3 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcspi3_hwmod, -+ .clk = "mcspi3_ick", -+ .addr = omap2430_mcspi3_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcspi3_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* L4 WKUP */ - static struct omap_hwmod omap2430_l4_wkup_hwmod = { - .name = "l4_wkup", -@@ -278,645 +441,2224 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* l4_wkup -> wd_timer2 */ --static struct omap_hwmod_addr_space omap2430_wd_timer2_addrs[] = { -- { -- .pa_start = 0x49016000, -- .pa_end = 0x4901607f, -- .flags = ADDR_TYPE_RT -- }, -+/* Timer Common */ -+static struct omap_hwmod_class_sysconfig omap2430_timer_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = { -- .master = &omap2430_l4_wkup_hwmod, -- .slave = &omap2430_wd_timer2_hwmod, -- .clk = "mpu_wdt_ick", -- .addr = omap2430_wd_timer2_addrs, -- .addr_cnt = ARRAY_SIZE(omap2430_wd_timer2_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+static struct omap_hwmod_class omap2430_timer_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap2430_timer_sysc, -+ .rev = OMAP_TIMER_IP_VERSION_1, - }; - --/* -- * 'wd_timer' class -- * 32-bit watchdog upward counter that generates a pulse on the reset pin on -- * overflow condition -- */ -+/* timer1 */ -+static struct omap_hwmod omap2430_timer1_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer1_mpu_irqs[] = { -+ { .irq = 37, }, -+}; - --static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = { -- .rev_offs = 0x0, -- .sysc_offs = 0x0010, -- .syss_offs = 0x0014, -- .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | -- SYSC_HAS_AUTOIDLE), -- .sysc_fields = &omap_hwmod_sysc_type1, -+static struct omap_hwmod_addr_space omap2430_timer1_addrs[] = { -+ { -+ .pa_start = 0x49018000, -+ .pa_end = 0x49018000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_class omap2430_wd_timer_hwmod_class = { -- .name = "wd_timer", -- .sysc = &omap2430_wd_timer_sysc, -- .pre_shutdown = &omap2_wd_timer_disable -+/* l4_wkup -> timer1 */ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__timer1 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_timer1_hwmod, -+ .clk = "gpt1_ick", -+ .addr = omap2430_timer1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* wd_timer2 */ --static struct omap_hwmod_ocp_if *omap2430_wd_timer2_slaves[] = { -- &omap2430_l4_wkup__wd_timer2, -+/* timer1 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer1_slaves[] = { -+ &omap2430_l4_wkup__timer1, - }; - --static struct omap_hwmod omap2430_wd_timer2_hwmod = { -- .name = "wd_timer2", -- .class = &omap2430_wd_timer_hwmod_class, -- .main_clk = "mpu_wdt_fck", -+/* timer1 hwmod */ -+static struct omap_hwmod omap2430_timer1_hwmod = { -+ .name = "timer1", -+ .mpu_irqs = omap2430_timer1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer1_mpu_irqs), -+ .main_clk = "gpt1_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT, -+ .module_bit = OMAP24XX_EN_GPT1_SHIFT, - .module_offs = WKUP_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, - }, - }, -- .slaves = omap2430_wd_timer2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_wd_timer2_slaves), -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), --}; -- --/* UART */ -- --static struct omap_hwmod_class_sysconfig uart_sysc = { -- .rev_offs = 0x50, -- .sysc_offs = 0x54, -- .syss_offs = 0x58, -- .sysc_flags = (SYSC_HAS_SIDLEMODE | -- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -- SYSC_HAS_AUTOIDLE), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+ .slaves = omap2430_timer1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer1_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --static struct omap_hwmod_class uart_class = { -- .name = "uart", -- .sysc = &uart_sysc, -+/* timer2 */ -+static struct omap_hwmod omap2430_timer2_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer2_mpu_irqs[] = { -+ { .irq = 38, }, - }; - --/* UART1 */ -- --static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -- { .irq = INT_24XX_UART1_IRQ, }, -+static struct omap_hwmod_addr_space omap2430_timer2_addrs[] = { -+ { -+ .pa_start = 0x4802a000, -+ .pa_end = 0x4802a000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -+/* l4_core -> timer2 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer2 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer2_hwmod, -+ .clk = "gpt2_ick", -+ .addr = omap2430_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap2430_uart1_slaves[] = { -- &omap2_l4_core__uart1, -+/* timer2 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer2_slaves[] = { -+ &omap2430_l4_core__timer2, - }; - --static struct omap_hwmod omap2430_uart1_hwmod = { -- .name = "uart1", -- .mpu_irqs = uart1_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -- .sdma_reqs = uart1_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -- .main_clk = "uart1_fck", -+/* timer2 hwmod */ -+static struct omap_hwmod omap2430_timer2_hwmod = { -+ .name = "timer2", -+ .mpu_irqs = omap2430_timer2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer2_mpu_irqs), -+ .main_clk = "gpt2_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_UART1_SHIFT, -+ .module_bit = OMAP24XX_EN_GPT2_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT, - }, - }, -- .slaves = omap2430_uart1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_uart1_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .slaves = omap2430_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer2_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* UART2 */ -+/* timer3 */ -+static struct omap_hwmod omap2430_timer3_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer3_mpu_irqs[] = { -+ { .irq = 39, }, -+}; - --static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -- { .irq = INT_24XX_UART2_IRQ, }, -+static struct omap_hwmod_addr_space omap2430_timer3_addrs[] = { -+ { -+ .pa_start = 0x48078000, -+ .pa_end = 0x48078000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -+/* l4_core -> timer3 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer3 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer3_hwmod, -+ .clk = "gpt3_ick", -+ .addr = omap2430_timer3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap2430_uart2_slaves[] = { -- &omap2_l4_core__uart2, -+/* timer3 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer3_slaves[] = { -+ &omap2430_l4_core__timer3, - }; - --static struct omap_hwmod omap2430_uart2_hwmod = { -- .name = "uart2", -- .mpu_irqs = uart2_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -- .sdma_reqs = uart2_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -- .main_clk = "uart2_fck", -+/* timer3 hwmod */ -+static struct omap_hwmod omap2430_timer3_hwmod = { -+ .name = "timer3", -+ .mpu_irqs = omap2430_timer3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer3_mpu_irqs), -+ .main_clk = "gpt3_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_UART2_SHIFT, -+ .module_bit = OMAP24XX_EN_GPT3_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT, - }, - }, -- .slaves = omap2430_uart2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_uart2_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .slaves = omap2430_timer3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer3_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* UART3 */ -+/* timer4 */ -+static struct omap_hwmod omap2430_timer4_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer4_mpu_irqs[] = { -+ { .irq = 40, }, -+}; - --static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -- { .irq = INT_24XX_UART3_IRQ, }, -+static struct omap_hwmod_addr_space omap2430_timer4_addrs[] = { -+ { -+ .pa_start = 0x4807a000, -+ .pa_end = 0x4807a000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -+/* l4_core -> timer4 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer4 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer4_hwmod, -+ .clk = "gpt4_ick", -+ .addr = omap2430_timer4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap2430_uart3_slaves[] = { -- &omap2_l4_core__uart3, -+/* timer4 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer4_slaves[] = { -+ &omap2430_l4_core__timer4, - }; - --static struct omap_hwmod omap2430_uart3_hwmod = { -- .name = "uart3", -- .mpu_irqs = uart3_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -- .sdma_reqs = uart3_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -- .main_clk = "uart3_fck", -+/* timer4 hwmod */ -+static struct omap_hwmod omap2430_timer4_hwmod = { -+ .name = "timer4", -+ .mpu_irqs = omap2430_timer4_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer4_mpu_irqs), -+ .main_clk = "gpt4_fck", - .prcm = { - .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT4_SHIFT, - .module_offs = CORE_MOD, -- .prcm_reg_id = 2, -- .module_bit = OMAP24XX_EN_UART3_SHIFT, -- .idlest_reg_id = 2, -- .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT, - }, - }, -- .slaves = omap2430_uart3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_uart3_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .slaves = omap2430_timer4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer4_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* I2C common */ --static struct omap_hwmod_class_sysconfig i2c_sysc = { -- .rev_offs = 0x00, -- .sysc_offs = 0x20, -- .syss_offs = 0x10, -- .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -- .sysc_fields = &omap_hwmod_sysc_type1, -+/* timer5 */ -+static struct omap_hwmod omap2430_timer5_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer5_mpu_irqs[] = { -+ { .irq = 41, }, - }; - --static struct omap_hwmod_class i2c_class = { -- .name = "i2c", -- .sysc = &i2c_sysc, -+static struct omap_hwmod_addr_space omap2430_timer5_addrs[] = { -+ { -+ .pa_start = 0x4807c000, -+ .pa_end = 0x4807c000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_i2c_dev_attr i2c_dev_attr = { -- .fifo_depth = 8, /* bytes */ -+/* l4_core -> timer5 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer5 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer5_hwmod, -+ .clk = "gpt5_ick", -+ .addr = omap2430_timer5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* I2C1 */ -- --static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = { -- { .irq = INT_24XX_I2C1_IRQ, }, -+/* timer5 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer5_slaves[] = { -+ &omap2430_l4_core__timer5, - }; - --static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = { -- { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX }, -- { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX }, -+/* timer5 hwmod */ -+static struct omap_hwmod omap2430_timer5_hwmod = { -+ .name = "timer5", -+ .mpu_irqs = omap2430_timer5_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer5_mpu_irqs), -+ .main_clk = "gpt5_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT5_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer5_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = { -- &omap2430_l4_core__i2c1, -+/* timer6 */ -+static struct omap_hwmod omap2430_timer6_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer6_mpu_irqs[] = { -+ { .irq = 42, }, - }; - --static struct omap_hwmod omap2430_i2c1_hwmod = { -- .name = "i2c1", -- .mpu_irqs = i2c1_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), -- .sdma_reqs = i2c1_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs), -- .main_clk = "i2chs1_fck", -+static struct omap_hwmod_addr_space omap2430_timer6_addrs[] = { -+ { -+ .pa_start = 0x4807e000, -+ .pa_end = 0x4807e000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer6 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer6 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer6_hwmod, -+ .clk = "gpt6_ick", -+ .addr = omap2430_timer6_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer6_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer6 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer6_slaves[] = { -+ &omap2430_l4_core__timer6, -+}; -+ -+/* timer6 hwmod */ -+static struct omap_hwmod omap2430_timer6_hwmod = { -+ .name = "timer6", -+ .mpu_irqs = omap2430_timer6_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer6_mpu_irqs), -+ .main_clk = "gpt6_fck", - .prcm = { - .omap2 = { -- /* -- * NOTE: The CM_FCLKEN* and CM_ICLKEN* for -- * I2CHS IP's do not follow the usual pattern. -- * prcm_reg_id alone cannot be used to program -- * the iclk and fclk. Needs to be handled using -- * additonal flags when clk handling is moved -- * to hwmod framework. -- */ -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP2430_EN_I2CHS1_SHIFT, -+ .module_bit = OMAP24XX_EN_GPT6_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, - }, - }, -- .slaves = omap2430_i2c1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves), -- .class = &i2c_class, -- .dev_attr = &i2c_dev_attr, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .slaves = omap2430_timer6_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer6_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* I2C2 */ -+/* timer7 */ -+static struct omap_hwmod omap2430_timer7_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer7_mpu_irqs[] = { -+ { .irq = 43, }, -+}; - --static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = { -- { .irq = INT_24XX_I2C2_IRQ, }, -+static struct omap_hwmod_addr_space omap2430_timer7_addrs[] = { -+ { -+ .pa_start = 0x48080000, -+ .pa_end = 0x48080000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = { -- { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX }, -- { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX }, -+/* l4_core -> timer7 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer7 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer7_hwmod, -+ .clk = "gpt7_ick", -+ .addr = omap2430_timer7_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer7_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = { -- &omap2430_l4_core__i2c2, -+/* timer7 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer7_slaves[] = { -+ &omap2430_l4_core__timer7, - }; - --static struct omap_hwmod omap2430_i2c2_hwmod = { -- .name = "i2c2", -- .mpu_irqs = i2c2_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), -- .sdma_reqs = i2c2_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs), -- .main_clk = "i2chs2_fck", -+/* timer7 hwmod */ -+static struct omap_hwmod omap2430_timer7_hwmod = { -+ .name = "timer7", -+ .mpu_irqs = omap2430_timer7_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer7_mpu_irqs), -+ .main_clk = "gpt7_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP2430_EN_I2CHS2_SHIFT, -+ .module_bit = OMAP24XX_EN_GPT7_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, - }, - }, -- .slaves = omap2430_i2c2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves), -- .class = &i2c_class, -- .dev_attr = &i2c_dev_attr, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .slaves = omap2430_timer7_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer7_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) - }; - --/* l4_wkup -> gpio1 */ --static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = { -+/* timer8 */ -+static struct omap_hwmod omap2430_timer8_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer8_mpu_irqs[] = { -+ { .irq = 44, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_timer8_addrs[] = { - { -- .pa_start = 0x4900C000, -- .pa_end = 0x4900C1ff, -+ .pa_start = 0x48082000, -+ .pa_end = 0x48082000 + SZ_1K - 1, - .flags = ADDR_TYPE_RT - }, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = { -- .master = &omap2430_l4_wkup_hwmod, -- .slave = &omap2430_gpio1_hwmod, -- .clk = "gpios_ick", -- .addr = omap2430_gpio1_addr_space, -- .addr_cnt = ARRAY_SIZE(omap2430_gpio1_addr_space), -+/* l4_core -> timer8 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer8 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer8_hwmod, -+ .clk = "gpt8_ick", -+ .addr = omap2430_timer8_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer8_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* l4_wkup -> gpio2 */ --static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = { -+/* timer8 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer8_slaves[] = { -+ &omap2430_l4_core__timer8, -+}; -+ -+/* timer8 hwmod */ -+static struct omap_hwmod omap2430_timer8_hwmod = { -+ .name = "timer8", -+ .mpu_irqs = omap2430_timer8_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer8_mpu_irqs), -+ .main_clk = "gpt8_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT8_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer8_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer8_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* timer9 */ -+static struct omap_hwmod omap2430_timer9_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer9_mpu_irqs[] = { -+ { .irq = 45, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_timer9_addrs[] = { - { -- .pa_start = 0x4900E000, -- .pa_end = 0x4900E1ff, -+ .pa_start = 0x48084000, -+ .pa_end = 0x48084000 + SZ_1K - 1, - .flags = ADDR_TYPE_RT - }, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = { -- .master = &omap2430_l4_wkup_hwmod, -- .slave = &omap2430_gpio2_hwmod, -- .clk = "gpios_ick", -- .addr = omap2430_gpio2_addr_space, -- .addr_cnt = ARRAY_SIZE(omap2430_gpio2_addr_space), -+/* l4_core -> timer9 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer9 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer9_hwmod, -+ .clk = "gpt9_ick", -+ .addr = omap2430_timer9_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer9_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* l4_wkup -> gpio3 */ --static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = { -+/* timer9 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer9_slaves[] = { -+ &omap2430_l4_core__timer9, -+}; -+ -+/* timer9 hwmod */ -+static struct omap_hwmod omap2430_timer9_hwmod = { -+ .name = "timer9", -+ .mpu_irqs = omap2430_timer9_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer9_mpu_irqs), -+ .main_clk = "gpt9_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT9_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer9_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer9_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* timer10 */ -+static struct omap_hwmod omap2430_timer10_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer10_mpu_irqs[] = { -+ { .irq = 46, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_timer10_addrs[] = { - { -- .pa_start = 0x49010000, -- .pa_end = 0x490101ff, -+ .pa_start = 0x48086000, -+ .pa_end = 0x48086000 + SZ_1K - 1, - .flags = ADDR_TYPE_RT - }, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = { -- .master = &omap2430_l4_wkup_hwmod, -- .slave = &omap2430_gpio3_hwmod, -- .clk = "gpios_ick", -- .addr = omap2430_gpio3_addr_space, -- .addr_cnt = ARRAY_SIZE(omap2430_gpio3_addr_space), -+/* l4_core -> timer10 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer10 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer10_hwmod, -+ .clk = "gpt10_ick", -+ .addr = omap2430_timer10_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer10_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* l4_wkup -> gpio4 */ --static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = { -+/* timer10 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer10_slaves[] = { -+ &omap2430_l4_core__timer10, -+}; -+ -+/* timer10 hwmod */ -+static struct omap_hwmod omap2430_timer10_hwmod = { -+ .name = "timer10", -+ .mpu_irqs = omap2430_timer10_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer10_mpu_irqs), -+ .main_clk = "gpt10_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT10_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer10_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer10_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* timer11 */ -+static struct omap_hwmod omap2430_timer11_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer11_mpu_irqs[] = { -+ { .irq = 47, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_timer11_addrs[] = { - { -- .pa_start = 0x49012000, -- .pa_end = 0x490121ff, -+ .pa_start = 0x48088000, -+ .pa_end = 0x48088000 + SZ_1K - 1, - .flags = ADDR_TYPE_RT - }, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = { -- .master = &omap2430_l4_wkup_hwmod, -- .slave = &omap2430_gpio4_hwmod, -- .clk = "gpios_ick", -- .addr = omap2430_gpio4_addr_space, -- .addr_cnt = ARRAY_SIZE(omap2430_gpio4_addr_space), -+/* l4_core -> timer11 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer11 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_timer11_hwmod, -+ .clk = "gpt11_ick", -+ .addr = omap2430_timer11_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer11_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* l4_core -> gpio5 */ --static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = { -+/* timer11 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer11_slaves[] = { -+ &omap2430_l4_core__timer11, -+}; -+ -+/* timer11 hwmod */ -+static struct omap_hwmod omap2430_timer11_hwmod = { -+ .name = "timer11", -+ .mpu_irqs = omap2430_timer11_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer11_mpu_irqs), -+ .main_clk = "gpt11_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT11_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer11_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer11_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* timer12 */ -+static struct omap_hwmod omap2430_timer12_hwmod; -+static struct omap_hwmod_irq_info omap2430_timer12_mpu_irqs[] = { -+ { .irq = 48, }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_timer12_addrs[] = { - { -- .pa_start = 0x480B6000, -- .pa_end = 0x480B61ff, -+ .pa_start = 0x4808a000, -+ .pa_end = 0x4808a000 + SZ_1K - 1, - .flags = ADDR_TYPE_RT - }, - }; - --static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = { -+/* l4_core -> timer12 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__timer12 = { - .master = &omap2430_l4_core_hwmod, -- .slave = &omap2430_gpio5_hwmod, -- .clk = "gpio5_ick", -- .addr = omap2430_gpio5_addr_space, -- .addr_cnt = ARRAY_SIZE(omap2430_gpio5_addr_space), -+ .slave = &omap2430_timer12_hwmod, -+ .clk = "gpt12_ick", -+ .addr = omap2430_timer12_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_timer12_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer12 slave port */ -+static struct omap_hwmod_ocp_if *omap2430_timer12_slaves[] = { -+ &omap2430_l4_core__timer12, -+}; -+ -+/* timer12 hwmod */ -+static struct omap_hwmod omap2430_timer12_hwmod = { -+ .name = "timer12", -+ .mpu_irqs = omap2430_timer12_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_timer12_mpu_irqs), -+ .main_clk = "gpt12_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPT12_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_timer12_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_timer12_slaves), -+ .class = &omap2430_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* l4_wkup -> wd_timer2 */ -+static struct omap_hwmod_addr_space omap2430_wd_timer2_addrs[] = { -+ { -+ .pa_start = 0x49016000, -+ .pa_end = 0x4901607f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__wd_timer2 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_wd_timer2_hwmod, -+ .clk = "mpu_wdt_ick", -+ .addr = omap2430_wd_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_wd_timer2_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* gpio dev_attr */ --static struct omap_gpio_dev_attr gpio_dev_attr = { -- .bank_width = 32, -- .dbck_flag = false, -+/* -+ * 'wd_timer' class -+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on -+ * overflow condition -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_wd_timer_sysc = { -+ .rev_offs = 0x0, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_wd_timer_hwmod_class = { -+ .name = "wd_timer", -+ .sysc = &omap2430_wd_timer_sysc, -+ .pre_shutdown = &omap2_wd_timer_disable -+}; -+ -+/* wd_timer2 */ -+static struct omap_hwmod_ocp_if *omap2430_wd_timer2_slaves[] = { -+ &omap2430_l4_wkup__wd_timer2, -+}; -+ -+static struct omap_hwmod omap2430_wd_timer2_hwmod = { -+ .name = "wd_timer2", -+ .class = &omap2430_wd_timer_hwmod_class, -+ .main_clk = "mpu_wdt_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MPU_WDT_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MPU_WDT_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_wd_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_wd_timer2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* UART */ -+ -+static struct omap_hwmod_class_sysconfig uart_sysc = { -+ .rev_offs = 0x50, -+ .sysc_offs = 0x54, -+ .syss_offs = 0x58, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class uart_class = { -+ .name = "uart", -+ .sysc = &uart_sysc, -+}; -+ -+/* UART1 */ -+ -+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -+ { .irq = INT_24XX_UART1_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_uart1_slaves[] = { -+ &omap2_l4_core__uart1, -+}; -+ -+static struct omap_hwmod omap2430_uart1_hwmod = { -+ .name = "uart1", -+ .mpu_irqs = uart1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -+ .sdma_reqs = uart1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -+ .main_clk = "uart1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_UART1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_EN_UART1_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_uart1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_uart1_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* UART2 */ -+ -+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -+ { .irq = INT_24XX_UART2_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_uart2_slaves[] = { -+ &omap2_l4_core__uart2, -+}; -+ -+static struct omap_hwmod omap2430_uart2_hwmod = { -+ .name = "uart2", -+ .mpu_irqs = uart2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -+ .sdma_reqs = uart2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -+ .main_clk = "uart2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_UART2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_EN_UART2_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_uart2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_uart2_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* UART3 */ -+ -+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -+ { .irq = INT_24XX_UART3_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_uart3_slaves[] = { -+ &omap2_l4_core__uart3, -+}; -+ -+static struct omap_hwmod omap2430_uart3_hwmod = { -+ .name = "uart3", -+ .mpu_irqs = uart3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -+ .sdma_reqs = uart3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -+ .main_clk = "uart3_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 2, -+ .module_bit = OMAP24XX_EN_UART3_SHIFT, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP24XX_EN_UART3_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_uart3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_uart3_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* -+ * 'dss' class -+ * display sub-system -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_dss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_dss_hwmod_class = { -+ .name = "dss", -+ .sysc = &omap2430_dss_sysc, -+}; -+ -+static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = { -+ { .name = "dispc", .dma_req = 5 }, -+}; -+ -+/* dss */ -+/* dss master ports */ -+static struct omap_hwmod_ocp_if *omap2430_dss_masters[] = { -+ &omap2430_dss__l3, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_dss_addrs[] = { -+ { -+ .pa_start = 0x48050000, -+ .pa_end = 0x480503FF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__dss = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_dss_core_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2430_dss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_dss_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = { -+ &omap2430_l4_core__dss, -+}; -+ -+static struct omap_hwmod_opt_clk dss_opt_clks[] = { -+ { .role = "tv_clk", .clk = "dss_54m_fck" }, -+ { .role = "sys_clk", .clk = "dss2_fck" }, -+}; -+ -+static struct omap_hwmod omap2430_dss_core_hwmod = { -+ .name = "dss_core", -+ .class = &omap2430_dss_hwmod_class, -+ .main_clk = "dss1_fck", /* instead of dss_fck */ -+ .sdma_reqs = omap2430_dss_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs), -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, -+ }, -+ }, -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+ .slaves = omap2430_dss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_slaves), -+ .masters = omap2430_dss_masters, -+ .masters_cnt = ARRAY_SIZE(omap2430_dss_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'dispc' class -+ * display controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &omap2430_dispc_sysc, -+}; -+ -+static struct omap_hwmod_irq_info omap2430_dispc_irqs[] = { -+ { .irq = 25 }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = { -+ { -+ .pa_start = 0x48050400, -+ .pa_end = 0x480507FF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_dispc = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_dss_dispc_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2430_dss_dispc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_dss_dispc_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_dispc slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = { -+ &omap2430_l4_core__dss_dispc, -+}; -+ -+static struct omap_hwmod omap2430_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &omap2430_dispc_hwmod_class, -+ .mpu_irqs = omap2430_dispc_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dispc_irqs), -+ .main_clk = "dss1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_dss_dispc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'rfbi' class -+ * remote frame buffer interface -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_rfbi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_rfbi_hwmod_class = { -+ .name = "rfbi", -+ .sysc = &omap2430_rfbi_sysc, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_dss_rfbi_addrs[] = { -+ { -+ .pa_start = 0x48050800, -+ .pa_end = 0x48050BFF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_rfbi = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_dss_rfbi_hwmod, -+ .clk = "dss_ick", -+ .addr = omap2430_dss_rfbi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_dss_rfbi_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_rfbi slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = { -+ &omap2430_l4_core__dss_rfbi, -+}; -+ -+static struct omap_hwmod omap2430_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap2430_rfbi_hwmod_class, -+ .main_clk = "dss1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, -+ }, -+ }, -+ .slaves = omap2430_dss_rfbi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'venc' class -+ * video encoder -+ */ -+ -+static struct omap_hwmod_class omap2430_venc_hwmod_class = { -+ .name = "venc", -+}; -+ -+/* dss_venc */ -+static struct omap_hwmod_addr_space omap2430_dss_venc_addrs[] = { -+ { -+ .pa_start = 0x48050C00, -+ .pa_end = 0x48050FFF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_venc */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_dss_venc_hwmod, -+ .clk = "dss_54m_fck", -+ .addr = omap2430_dss_venc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_dss_venc_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_venc slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = { -+ &omap2430_l4_core__dss_venc, -+}; -+ -+static struct omap_hwmod omap2430_dss_venc_hwmod = { -+ .name = "dss_venc", -+ .class = &omap2430_venc_hwmod_class, -+ .main_clk = "dss1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_DSS1_SHIFT, -+ .module_offs = CORE_MOD, -+ }, -+ }, -+ .slaves = omap2430_dss_venc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_venc_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* I2C common */ -+static struct omap_hwmod_class_sysconfig i2c_sysc = { -+ .rev_offs = 0x00, -+ .sysc_offs = 0x20, -+ .syss_offs = 0x10, -+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class i2c_class = { -+ .name = "i2c", -+ .sysc = &i2c_sysc, -+}; -+ -+static struct omap_i2c_dev_attr i2c_dev_attr = { -+ .fifo_depth = 8, /* bytes */ -+}; -+ -+/* I2C1 */ -+ -+static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = { -+ { .irq = INT_24XX_I2C1_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX }, -+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = { -+ &omap2430_l4_core__i2c1, -+}; -+ -+static struct omap_hwmod omap2430_i2c1_hwmod = { -+ .name = "i2c1", -+ .mpu_irqs = i2c1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), -+ .sdma_reqs = i2c1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs), -+ .main_clk = "i2chs1_fck", -+ .prcm = { -+ .omap2 = { -+ /* -+ * NOTE: The CM_FCLKEN* and CM_ICLKEN* for -+ * I2CHS IP's do not follow the usual pattern. -+ * prcm_reg_id alone cannot be used to program -+ * the iclk and fclk. Needs to be handled using -+ * additonal flags when clk handling is moved -+ * to hwmod framework. -+ */ -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP2430_EN_I2CHS1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_i2c1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves), -+ .class = &i2c_class, -+ .dev_attr = &i2c_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* I2C2 */ -+ -+static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = { -+ { .irq = INT_24XX_I2C2_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX }, -+ { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = { -+ &omap2430_l4_core__i2c2, -+}; -+ -+static struct omap_hwmod omap2430_i2c2_hwmod = { -+ .name = "i2c2", -+ .mpu_irqs = i2c2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), -+ .sdma_reqs = i2c2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs), -+ .main_clk = "i2chs2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP2430_EN_I2CHS2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_i2c2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves), -+ .class = &i2c_class, -+ .dev_attr = &i2c_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* l4_wkup -> gpio1 */ -+static struct omap_hwmod_addr_space omap2430_gpio1_addr_space[] = { -+ { -+ .pa_start = 0x4900C000, -+ .pa_end = 0x4900C1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio1 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_gpio1_hwmod, -+ .clk = "gpios_ick", -+ .addr = omap2430_gpio1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_gpio1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_wkup -> gpio2 */ -+static struct omap_hwmod_addr_space omap2430_gpio2_addr_space[] = { -+ { -+ .pa_start = 0x4900E000, -+ .pa_end = 0x4900E1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio2 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_gpio2_hwmod, -+ .clk = "gpios_ick", -+ .addr = omap2430_gpio2_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_gpio2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_wkup -> gpio3 */ -+static struct omap_hwmod_addr_space omap2430_gpio3_addr_space[] = { -+ { -+ .pa_start = 0x49010000, -+ .pa_end = 0x490101ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio3 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_gpio3_hwmod, -+ .clk = "gpios_ick", -+ .addr = omap2430_gpio3_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_gpio3_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_wkup -> gpio4 */ -+static struct omap_hwmod_addr_space omap2430_gpio4_addr_space[] = { -+ { -+ .pa_start = 0x49012000, -+ .pa_end = 0x490121ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_wkup__gpio4 = { -+ .master = &omap2430_l4_wkup_hwmod, -+ .slave = &omap2430_gpio4_hwmod, -+ .clk = "gpios_ick", -+ .addr = omap2430_gpio4_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_gpio4_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4_core -> gpio5 */ -+static struct omap_hwmod_addr_space omap2430_gpio5_addr_space[] = { -+ { -+ .pa_start = 0x480B6000, -+ .pa_end = 0x480B61ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_gpio5_hwmod, -+ .clk = "gpio5_ick", -+ .addr = omap2430_gpio5_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap2430_gpio5_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio dev_attr */ -+static struct omap_gpio_dev_attr gpio_dev_attr = { -+ .bank_width = 32, -+ .dbck_flag = false, -+}; -+ -+static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+/* -+ * 'gpio' class -+ * general purpose io module -+ */ -+static struct omap_hwmod_class omap243x_gpio_hwmod_class = { -+ .name = "gpio", -+ .sysc = &omap243x_gpio_sysc, -+ .rev = 0, -+}; -+ -+/* gpio1 */ -+static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = { -+ { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = { -+ &omap2430_l4_wkup__gpio1, -+}; -+ -+static struct omap_hwmod omap2430_gpio1_hwmod = { -+ .name = "gpio1", -+ .mpu_irqs = omap243x_gpio1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs), -+ .main_clk = "gpios_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_gpio1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio1_slaves), -+ .class = &omap243x_gpio_hwmod_class, -+ .dev_attr = &gpio_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* gpio2 */ -+static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = { -+ { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = { -+ &omap2430_l4_wkup__gpio2, -+}; -+ -+static struct omap_hwmod omap2430_gpio2_hwmod = { -+ .name = "gpio2", -+ .mpu_irqs = omap243x_gpio2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs), -+ .main_clk = "gpios_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_gpio2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio2_slaves), -+ .class = &omap243x_gpio_hwmod_class, -+ .dev_attr = &gpio_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* gpio3 */ -+static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = { -+ { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = { -+ &omap2430_l4_wkup__gpio3, -+}; -+ -+static struct omap_hwmod omap2430_gpio3_hwmod = { -+ .name = "gpio3", -+ .mpu_irqs = omap243x_gpio3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs), -+ .main_clk = "gpios_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_gpio3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio3_slaves), -+ .class = &omap243x_gpio_hwmod_class, -+ .dev_attr = &gpio_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* gpio4 */ -+static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = { -+ { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = { -+ &omap2430_l4_wkup__gpio4, -+}; -+ -+static struct omap_hwmod omap2430_gpio4_hwmod = { -+ .name = "gpio4", -+ .mpu_irqs = omap243x_gpio4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs), -+ .main_clk = "gpios_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_gpio4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio4_slaves), -+ .class = &omap243x_gpio_hwmod_class, -+ .dev_attr = &gpio_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* gpio5 */ -+static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = { -+ { .irq = 33 }, /* INT_24XX_GPIO_BANK5 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = { -+ &omap2430_l4_core__gpio5, -+}; -+ -+static struct omap_hwmod omap2430_gpio5_hwmod = { -+ .name = "gpio5", -+ .mpu_irqs = omap243x_gpio5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs), -+ .main_clk = "gpio5_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 2, -+ .module_bit = OMAP2430_EN_GPIO5_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_gpio5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_gpio5_slaves), -+ .class = &omap243x_gpio_hwmod_class, -+ .dev_attr = &gpio_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* dma_system */ -+static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x002c, -+ .syss_offs = 0x0028, -+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_dma_hwmod_class = { -+ .name = "dma", -+ .sysc = &omap2430_dma_sysc, -+}; -+ -+/* dma attributes */ -+static struct omap_dma_dev_attr dma_dev_attr = { -+ .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | -+ IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, -+ .lch_count = 32, -+}; -+ -+static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = { -+ { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */ -+ { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */ -+ { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */ -+ { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */ -+}; -+ -+static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = { -+ { -+ .pa_start = 0x48056000, -+ .pa_end = 0x4a0560ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* dma_system -> L3 */ -+static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = { -+ .master = &omap2430_dma_system_hwmod, -+ .slave = &omap2430_l3_main_hwmod, -+ .clk = "core_l3_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dma_system master ports */ -+static struct omap_hwmod_ocp_if *omap2430_dma_system_masters[] = { -+ &omap2430_dma_system__l3, -+}; -+ -+/* l4_core -> dma_system */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_dma_system_hwmod, -+ .clk = "sdma_ick", -+ .addr = omap2430_dma_system_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_dma_system_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dma_system slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_dma_system_slaves[] = { -+ &omap2430_l4_core__dma_system, -+}; -+ -+static struct omap_hwmod omap2430_dma_system_hwmod = { -+ .name = "dma", -+ .class = &omap2430_dma_hwmod_class, -+ .mpu_irqs = omap2430_dma_system_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dma_system_irqs), -+ .main_clk = "core_l3_ck", -+ .slaves = omap2430_dma_system_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_dma_system_slaves), -+ .masters = omap2430_dma_system_masters, -+ .masters_cnt = ARRAY_SIZE(omap2430_dma_system_masters), -+ .dev_attr = &dma_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'mailbox' class -+ * mailbox module allowing communication between the on-chip processors -+ * using a queued mailbox-interrupt mechanism. -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_mailbox_sysc = { -+ .rev_offs = 0x000, -+ .sysc_offs = 0x010, -+ .syss_offs = 0x014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_mailbox_hwmod_class = { -+ .name = "mailbox", -+ .sysc = &omap2430_mailbox_sysc, -+}; -+ -+/* mailbox */ -+static struct omap_hwmod omap2430_mailbox_hwmod; -+static struct omap_hwmod_irq_info omap2430_mailbox_irqs[] = { -+ { .irq = 26 }, -+}; -+ -+static struct omap_hwmod_addr_space omap2430_mailbox_addrs[] = { -+ { -+ .pa_start = 0x48094000, -+ .pa_end = 0x480941ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+/* l4_core -> mailbox */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mailbox = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mailbox_hwmod, -+ .addr = omap2430_mailbox_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mailbox_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mailbox slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mailbox_slaves[] = { -+ &omap2430_l4_core__mailbox, -+}; -+ -+static struct omap_hwmod omap2430_mailbox_hwmod = { -+ .name = "mailbox", -+ .class = &omap2430_mailbox_hwmod_class, -+ .mpu_irqs = omap2430_mailbox_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mailbox_irqs), -+ .main_clk = "mailboxes_ick", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MAILBOXES_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MAILBOXES_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_mailbox_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mailbox_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* -+ * 'mcspi' class -+ * multichannel serial port interface (mcspi) / master/slave synchronous serial -+ * bus -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_mcspi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_mcspi_class = { -+ .name = "mcspi", -+ .sysc = &omap2430_mcspi_sysc, -+ .rev = OMAP2_MCSPI_REV, -+}; -+ -+/* mcspi1 */ -+static struct omap_hwmod_irq_info omap2430_mcspi1_mpu_irqs[] = { -+ { .irq = 65 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2430_mcspi1_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 35 }, /* DMA_SPI1_TX0 */ -+ { .name = "rx0", .dma_req = 36 }, /* DMA_SPI1_RX0 */ -+ { .name = "tx1", .dma_req = 37 }, /* DMA_SPI1_TX1 */ -+ { .name = "rx1", .dma_req = 38 }, /* DMA_SPI1_RX1 */ -+ { .name = "tx2", .dma_req = 39 }, /* DMA_SPI1_TX2 */ -+ { .name = "rx2", .dma_req = 40 }, /* DMA_SPI1_RX2 */ -+ { .name = "tx3", .dma_req = 41 }, /* DMA_SPI1_TX3 */ -+ { .name = "rx3", .dma_req = 42 }, /* DMA_SPI1_RX3 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_mcspi1_slaves[] = { -+ &omap2430_l4_core__mcspi1, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { -+ .num_chipselect = 4, -+}; -+ -+static struct omap_hwmod omap2430_mcspi1_hwmod = { -+ .name = "mcspi1_hwmod", -+ .mpu_irqs = omap2430_mcspi1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi1_mpu_irqs), -+ .sdma_reqs = omap2430_mcspi1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi1_sdma_reqs), -+ .main_clk = "mcspi1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCSPI1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCSPI1_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_mcspi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi1_slaves), -+ .class = &omap2430_mcspi_class, -+ .dev_attr = &omap_mcspi1_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* mcspi2 */ -+static struct omap_hwmod_irq_info omap2430_mcspi2_mpu_irqs[] = { -+ { .irq = 66 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2430_mcspi2_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 43 }, /* DMA_SPI2_TX0 */ -+ { .name = "rx0", .dma_req = 44 }, /* DMA_SPI2_RX0 */ -+ { .name = "tx1", .dma_req = 45 }, /* DMA_SPI2_TX1 */ -+ { .name = "rx1", .dma_req = 46 }, /* DMA_SPI2_RX1 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_mcspi2_slaves[] = { -+ &omap2430_l4_core__mcspi2, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap2430_mcspi2_hwmod = { -+ .name = "mcspi2_hwmod", -+ .mpu_irqs = omap2430_mcspi2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi2_mpu_irqs), -+ .sdma_reqs = omap2430_mcspi2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi2_sdma_reqs), -+ .main_clk = "mcspi2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP24XX_EN_MCSPI2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP24XX_ST_MCSPI2_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_mcspi2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi2_slaves), -+ .class = &omap2430_mcspi_class, -+ .dev_attr = &omap_mcspi2_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* mcspi3 */ -+static struct omap_hwmod_irq_info omap2430_mcspi3_mpu_irqs[] = { -+ { .irq = 91 }, -+}; -+ -+static struct omap_hwmod_dma_info omap2430_mcspi3_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 15 }, /* DMA_SPI3_TX0 */ -+ { .name = "rx0", .dma_req = 16 }, /* DMA_SPI3_RX0 */ -+ { .name = "tx1", .dma_req = 23 }, /* DMA_SPI3_TX1 */ -+ { .name = "rx1", .dma_req = 24 }, /* DMA_SPI3_RX1 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_mcspi3_slaves[] = { -+ &omap2430_l4_core__mcspi3, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap2430_mcspi3_hwmod = { -+ .name = "mcspi3_hwmod", -+ .mpu_irqs = omap2430_mcspi3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcspi3_mpu_irqs), -+ .sdma_reqs = omap2430_mcspi3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcspi3_sdma_reqs), -+ .main_clk = "mcspi3_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 2, -+ .module_bit = OMAP2430_EN_MCSPI3_SHIFT, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_MCSPI3_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_mcspi3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcspi3_slaves), -+ .class = &omap2430_mcspi_class, -+ .dev_attr = &omap_mcspi3_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -+}; -+ -+/* -+ * usbhsotg -+ */ -+static struct omap_hwmod_class_sysconfig omap2430_usbhsotg_sysc = { -+ .rev_offs = 0x0400, -+ .sysc_offs = 0x0404, -+ .syss_offs = 0x0408, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class usbotg_class = { -+ .name = "usbotg", -+ .sysc = &omap2430_usbhsotg_sysc, -+}; -+ -+/* usb_otg_hs */ -+static struct omap_hwmod_irq_info omap2430_usbhsotg_mpu_irqs[] = { -+ -+ { .name = "mc", .irq = 92 }, -+ { .name = "dma", .irq = 93 }, -+}; -+ -+static struct omap_hwmod omap2430_usbhsotg_hwmod = { -+ .name = "usb_otg_hs", -+ .mpu_irqs = omap2430_usbhsotg_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_usbhsotg_mpu_irqs), -+ .main_clk = "usbhs_ick", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP2430_EN_USBHS_MASK, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP2430_ST_USBHS_SHIFT, -+ }, -+ }, -+ .masters = omap2430_usbhsotg_masters, -+ .masters_cnt = ARRAY_SIZE(omap2430_usbhsotg_masters), -+ .slaves = omap2430_usbhsotg_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_usbhsotg_slaves), -+ .class = &usbotg_class, -+ /* -+ * Erratum ID: i479 idle_req / idle_ack mechanism potentially -+ * broken when autoidle is enabled -+ * workaround is to disable the autoidle bit at module level. -+ */ -+ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE -+ | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) -+}; -+ -+/* -+ * 'mcbsp' class -+ * multi channel buffered serial port controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = { -+ .rev_offs = 0x007C, -+ .sysc_offs = 0x008C, -+ .sysc_flags = (SYSC_HAS_SOFTRESET), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = { -+ .name = "mcbsp", -+ .sysc = &omap2430_mcbsp_sysc, -+ .rev = MCBSP_CONFIG_TYPE2, - }; - --static struct omap_hwmod_class_sysconfig omap243x_gpio_sysc = { -- .rev_offs = 0x0000, -- .sysc_offs = 0x0010, -- .syss_offs = 0x0014, -- .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -- SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+/* mcbsp1 */ -+static struct omap_hwmod_irq_info omap2430_mcbsp1_irqs[] = { -+ { .name = "tx", .irq = 59 }, -+ { .name = "rx", .irq = 60 }, -+ { .name = "ovr", .irq = 61 }, -+ { .name = "common", .irq = 64 }, - }; - --/* -- * 'gpio' class -- * general purpose io module -- */ --static struct omap_hwmod_class omap243x_gpio_hwmod_class = { -- .name = "gpio", -- .sysc = &omap243x_gpio_sysc, -- .rev = 0, -+static struct omap_hwmod_dma_info omap2430_mcbsp1_sdma_chs[] = { -+ { .name = "rx", .dma_req = 32 }, -+ { .name = "tx", .dma_req = 31 }, - }; - --/* gpio1 */ --static struct omap_hwmod_irq_info omap243x_gpio1_irqs[] = { -- { .irq = 29 }, /* INT_24XX_GPIO_BANK1 */ -+static struct omap_hwmod_addr_space omap2430_mcbsp1_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48074000, -+ .pa_end = 0x480740ff, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = { -- &omap2430_l4_wkup__gpio1, -+/* l4_core -> mcbsp1 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp1 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcbsp1_hwmod, -+ .clk = "mcbsp1_ick", -+ .addr = omap2430_mcbsp1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod omap2430_gpio1_hwmod = { -- .name = "gpio1", -- .mpu_irqs = omap243x_gpio1_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs), -- .main_clk = "gpios_fck", -+/* mcbsp1 slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mcbsp1_slaves[] = { -+ &omap2430_l4_core__mcbsp1, -+}; -+ -+static struct omap_hwmod omap2430_mcbsp1_hwmod = { -+ .name = "mcbsp1", -+ .class = &omap2430_mcbsp_hwmod_class, -+ .mpu_irqs = omap2430_mcbsp1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp1_irqs), -+ .sdma_reqs = omap2430_mcbsp1_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp1_sdma_chs), -+ .main_clk = "mcbsp1_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -- .module_offs = WKUP_MOD, -+ .module_bit = OMAP24XX_EN_MCBSP1_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_EN_GPIOS_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_MCBSP1_SHIFT, - }, - }, -- .slaves = omap2430_gpio1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_gpio1_slaves), -- .class = &omap243x_gpio_hwmod_class, -- .dev_attr = &gpio_dev_attr, -+ .slaves = omap2430_mcbsp1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp1_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* gpio2 */ --static struct omap_hwmod_irq_info omap243x_gpio2_irqs[] = { -- { .irq = 30 }, /* INT_24XX_GPIO_BANK2 */ -+/* mcbsp2 */ -+static struct omap_hwmod_irq_info omap2430_mcbsp2_irqs[] = { -+ { .name = "tx", .irq = 62 }, -+ { .name = "rx", .irq = 63 }, -+ { .name = "common", .irq = 16 }, - }; - --static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = { -- &omap2430_l4_wkup__gpio2, -+static struct omap_hwmod_dma_info omap2430_mcbsp2_sdma_chs[] = { -+ { .name = "rx", .dma_req = 34 }, -+ { .name = "tx", .dma_req = 33 }, - }; - --static struct omap_hwmod omap2430_gpio2_hwmod = { -- .name = "gpio2", -- .mpu_irqs = omap243x_gpio2_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs), -- .main_clk = "gpios_fck", -+static struct omap_hwmod_addr_space omap2430_mcbsp2_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48076000, -+ .pa_end = 0x480760ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp2 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp2 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcbsp2_hwmod, -+ .clk = "mcbsp2_ick", -+ .addr = omap2430_mcbsp2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp2 slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mcbsp2_slaves[] = { -+ &omap2430_l4_core__mcbsp2, -+}; -+ -+static struct omap_hwmod omap2430_mcbsp2_hwmod = { -+ .name = "mcbsp2", -+ .class = &omap2430_mcbsp_hwmod_class, -+ .mpu_irqs = omap2430_mcbsp2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp2_irqs), -+ .sdma_reqs = omap2430_mcbsp2_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp2_sdma_chs), -+ .main_clk = "mcbsp2_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -- .module_offs = WKUP_MOD, -+ .module_bit = OMAP24XX_EN_MCBSP2_SHIFT, -+ .module_offs = CORE_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ .idlest_idle_bit = OMAP24XX_ST_MCBSP2_SHIFT, - }, - }, -- .slaves = omap2430_gpio2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_gpio2_slaves), -- .class = &omap243x_gpio_hwmod_class, -- .dev_attr = &gpio_dev_attr, -+ .slaves = omap2430_mcbsp2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp2_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* gpio3 */ --static struct omap_hwmod_irq_info omap243x_gpio3_irqs[] = { -- { .irq = 31 }, /* INT_24XX_GPIO_BANK3 */ -+/* mcbsp3 */ -+static struct omap_hwmod_irq_info omap2430_mcbsp3_irqs[] = { -+ { .name = "tx", .irq = 89 }, -+ { .name = "rx", .irq = 90 }, -+ { .name = "common", .irq = 17 }, - }; - --static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = { -- &omap2430_l4_wkup__gpio3, -+static struct omap_hwmod_dma_info omap2430_mcbsp3_sdma_chs[] = { -+ { .name = "rx", .dma_req = 18 }, -+ { .name = "tx", .dma_req = 17 }, - }; - --static struct omap_hwmod omap2430_gpio3_hwmod = { -- .name = "gpio3", -- .mpu_irqs = omap243x_gpio3_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs), -- .main_clk = "gpios_fck", -+static struct omap_hwmod_addr_space omap2430_mcbsp3_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x4808C000, -+ .pa_end = 0x4808C0ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp3 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp3 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcbsp3_hwmod, -+ .clk = "mcbsp3_ick", -+ .addr = omap2430_mcbsp3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp3 slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mcbsp3_slaves[] = { -+ &omap2430_l4_core__mcbsp3, -+}; -+ -+static struct omap_hwmod omap2430_mcbsp3_hwmod = { -+ .name = "mcbsp3", -+ .class = &omap2430_mcbsp_hwmod_class, -+ .mpu_irqs = omap2430_mcbsp3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp3_irqs), -+ .sdma_reqs = omap2430_mcbsp3_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp3_sdma_chs), -+ .main_clk = "mcbsp3_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -- .module_offs = WKUP_MOD, -- .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ .module_bit = OMAP2430_EN_MCBSP3_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_MCBSP3_SHIFT, - }, - }, -- .slaves = omap2430_gpio3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_gpio3_slaves), -- .class = &omap243x_gpio_hwmod_class, -- .dev_attr = &gpio_dev_attr, -+ .slaves = omap2430_mcbsp3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp3_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* gpio4 */ --static struct omap_hwmod_irq_info omap243x_gpio4_irqs[] = { -- { .irq = 32 }, /* INT_24XX_GPIO_BANK4 */ -+/* mcbsp4 */ -+static struct omap_hwmod_irq_info omap2430_mcbsp4_irqs[] = { -+ { .name = "tx", .irq = 54 }, -+ { .name = "rx", .irq = 55 }, -+ { .name = "common", .irq = 18 }, - }; - --static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = { -- &omap2430_l4_wkup__gpio4, -+static struct omap_hwmod_dma_info omap2430_mcbsp4_sdma_chs[] = { -+ { .name = "rx", .dma_req = 20 }, -+ { .name = "tx", .dma_req = 19 }, - }; - --static struct omap_hwmod omap2430_gpio4_hwmod = { -- .name = "gpio4", -- .mpu_irqs = omap243x_gpio4_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs), -- .main_clk = "gpios_fck", -+static struct omap_hwmod_addr_space omap2430_mcbsp4_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x4808E000, -+ .pa_end = 0x4808E0ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp4 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp4 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcbsp4_hwmod, -+ .clk = "mcbsp4_ick", -+ .addr = omap2430_mcbsp4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp4 slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mcbsp4_slaves[] = { -+ &omap2430_l4_core__mcbsp4, -+}; -+ -+static struct omap_hwmod omap2430_mcbsp4_hwmod = { -+ .name = "mcbsp4", -+ .class = &omap2430_mcbsp_hwmod_class, -+ .mpu_irqs = omap2430_mcbsp4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp4_irqs), -+ .sdma_reqs = omap2430_mcbsp4_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp4_sdma_chs), -+ .main_clk = "mcbsp4_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP24XX_EN_GPIOS_SHIFT, -- .module_offs = WKUP_MOD, -- .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP24XX_ST_GPIOS_SHIFT, -+ .module_bit = OMAP2430_EN_MCBSP4_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_MCBSP4_SHIFT, - }, - }, -- .slaves = omap2430_gpio4_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_gpio4_slaves), -- .class = &omap243x_gpio_hwmod_class, -- .dev_attr = &gpio_dev_attr, -+ .slaves = omap2430_mcbsp4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp4_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* gpio5 */ --static struct omap_hwmod_irq_info omap243x_gpio5_irqs[] = { -- { .irq = 33 }, /* INT_24XX_GPIO_BANK5 */ -+/* mcbsp5 */ -+static struct omap_hwmod_irq_info omap2430_mcbsp5_irqs[] = { -+ { .name = "tx", .irq = 81 }, -+ { .name = "rx", .irq = 82 }, -+ { .name = "common", .irq = 19 }, - }; - --static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = { -- &omap2430_l4_core__gpio5, -+static struct omap_hwmod_dma_info omap2430_mcbsp5_sdma_chs[] = { -+ { .name = "rx", .dma_req = 22 }, -+ { .name = "tx", .dma_req = 21 }, - }; - --static struct omap_hwmod omap2430_gpio5_hwmod = { -- .name = "gpio5", -- .mpu_irqs = omap243x_gpio5_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs), -- .main_clk = "gpio5_fck", -+static struct omap_hwmod_addr_space omap2430_mcbsp5_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48096000, -+ .pa_end = 0x480960ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp5 */ -+static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = { -+ .master = &omap2430_l4_core_hwmod, -+ .slave = &omap2430_mcbsp5_hwmod, -+ .clk = "mcbsp5_ick", -+ .addr = omap2430_mcbsp5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap2430_mcbsp5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp5 slave ports */ -+static struct omap_hwmod_ocp_if *omap2430_mcbsp5_slaves[] = { -+ &omap2430_l4_core__mcbsp5, -+}; -+ -+static struct omap_hwmod omap2430_mcbsp5_hwmod = { -+ .name = "mcbsp5", -+ .class = &omap2430_mcbsp_hwmod_class, -+ .mpu_irqs = omap2430_mcbsp5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mcbsp5_irqs), -+ .sdma_reqs = omap2430_mcbsp5_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mcbsp5_sdma_chs), -+ .main_clk = "mcbsp5_fck", - .prcm = { - .omap2 = { -- .prcm_reg_id = 2, -- .module_bit = OMAP2430_EN_GPIO5_SHIFT, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP2430_EN_MCBSP5_SHIFT, - .module_offs = CORE_MOD, - .idlest_reg_id = 2, -- .idlest_idle_bit = OMAP2430_ST_GPIO5_SHIFT, -+ .idlest_idle_bit = OMAP2430_ST_MCBSP5_SHIFT, - }, - }, -- .slaves = omap2430_gpio5_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_gpio5_slaves), -- .class = &omap243x_gpio_hwmod_class, -- .dev_attr = &gpio_dev_attr, -+ .slaves = omap2430_mcbsp5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mcbsp5_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* dma_system */ --static struct omap_hwmod_class_sysconfig omap2430_dma_sysc = { -- .rev_offs = 0x0000, -- .sysc_offs = 0x002c, -- .syss_offs = 0x0028, -- .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE | -- SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE | -- SYSC_HAS_AUTOIDLE), -- .idlemodes = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+/* MMC/SD/SDIO common */ -+ -+static struct omap_hwmod_class_sysconfig omap2430_mmc_sysc = { -+ .rev_offs = 0x1fc, -+ .sysc_offs = 0x10, -+ .syss_offs = 0x14, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_class omap2430_dma_hwmod_class = { -- .name = "dma", -- .sysc = &omap2430_dma_sysc, -+static struct omap_hwmod_class omap2430_mmc_class = { -+ .name = "mmc", -+ .sysc = &omap2430_mmc_sysc, - }; - --/* dma attributes */ --static struct omap_dma_dev_attr dma_dev_attr = { -- .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | -- IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY, -- .lch_count = 32, -+/* MMC/SD/SDIO1 */ -+ -+static struct omap_hwmod_irq_info omap2430_mmc1_mpu_irqs[] = { -+ { .irq = 83 }, - }; - --static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = { -- { .name = "0", .irq = 12 }, /* INT_24XX_SDMA_IRQ0 */ -- { .name = "1", .irq = 13 }, /* INT_24XX_SDMA_IRQ1 */ -- { .name = "2", .irq = 14 }, /* INT_24XX_SDMA_IRQ2 */ -- { .name = "3", .irq = 15 }, /* INT_24XX_SDMA_IRQ3 */ -+static struct omap_hwmod_dma_info omap2430_mmc1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 61 }, /* DMA_MMC1_TX */ -+ { .name = "rx", .dma_req = 62 }, /* DMA_MMC1_RX */ - }; - --static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = { -- { -- .pa_start = 0x48056000, -- .pa_end = 0x4a0560ff, -- .flags = ADDR_TYPE_RT -+static struct omap_hwmod_opt_clk omap2430_mmc1_opt_clks[] = { -+ { .role = "dbck", .clk = "mmchsdb1_fck" }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap2430_mmc1_slaves[] = { -+ &omap2430_l4_core__mmc1, -+}; -+ -+static struct omap_mmc_dev_attr mmc1_dev_attr = { -+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -+}; -+ -+static struct omap_hwmod omap2430_mmc1_hwmod = { -+ .name = "mmc1", -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap2430_mmc1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mmc1_mpu_irqs), -+ .sdma_reqs = omap2430_mmc1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mmc1_sdma_reqs), -+ .opt_clks = omap2430_mmc1_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc1_opt_clks), -+ .main_clk = "mmchs1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 2, -+ .module_bit = OMAP2430_EN_MMCHS1_SHIFT, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_MMCHS1_SHIFT, -+ }, - }, -+ .dev_attr = &mmc1_dev_attr, -+ .slaves = omap2430_mmc1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mmc1_slaves), -+ .class = &omap2430_mmc_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), - }; - --/* dma_system -> L3 */ --static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = { -- .master = &omap2430_dma_system_hwmod, -- .slave = &omap2430_l3_main_hwmod, -- .clk = "core_l3_ck", -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+/* MMC/SD/SDIO2 */ -+ -+static struct omap_hwmod_irq_info omap2430_mmc2_mpu_irqs[] = { -+ { .irq = 86 }, - }; - --/* dma_system master ports */ --static struct omap_hwmod_ocp_if *omap2430_dma_system_masters[] = { -- &omap2430_dma_system__l3, -+static struct omap_hwmod_dma_info omap2430_mmc2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 47 }, /* DMA_MMC2_TX */ -+ { .name = "rx", .dma_req = 48 }, /* DMA_MMC2_RX */ - }; - --/* l4_core -> dma_system */ --static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = { -- .master = &omap2430_l4_core_hwmod, -- .slave = &omap2430_dma_system_hwmod, -- .clk = "sdma_ick", -- .addr = omap2430_dma_system_addrs, -- .addr_cnt = ARRAY_SIZE(omap2430_dma_system_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+static struct omap_hwmod_opt_clk omap2430_mmc2_opt_clks[] = { -+ { .role = "dbck", .clk = "mmchsdb2_fck" }, - }; - --/* dma_system slave ports */ --static struct omap_hwmod_ocp_if *omap2430_dma_system_slaves[] = { -- &omap2430_l4_core__dma_system, -+static struct omap_hwmod_ocp_if *omap2430_mmc2_slaves[] = { -+ &omap2430_l4_core__mmc2, - }; - --static struct omap_hwmod omap2430_dma_system_hwmod = { -- .name = "dma", -- .class = &omap2430_dma_hwmod_class, -- .mpu_irqs = omap2430_dma_system_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dma_system_irqs), -- .main_clk = "core_l3_ck", -- .slaves = omap2430_dma_system_slaves, -- .slaves_cnt = ARRAY_SIZE(omap2430_dma_system_slaves), -- .masters = omap2430_dma_system_masters, -- .masters_cnt = ARRAY_SIZE(omap2430_dma_system_masters), -- .dev_attr = &dma_dev_attr, -+static struct omap_hwmod omap2430_mmc2_hwmod = { -+ .name = "mmc2", -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap2430_mmc2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_mmc2_mpu_irqs), -+ .sdma_reqs = omap2430_mmc2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_mmc2_sdma_reqs), -+ .opt_clks = omap2430_mmc2_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(omap2430_mmc2_opt_clks), -+ .main_clk = "mmchs2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 2, -+ .module_bit = OMAP2430_EN_MMCHS2_SHIFT, -+ .idlest_reg_id = 2, -+ .idlest_idle_bit = OMAP2430_ST_MMCHS2_SHIFT, -+ }, -+ }, -+ .slaves = omap2430_mmc2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap2430_mmc2_slaves), -+ .class = &omap2430_mmc_class, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), -- .flags = HWMOD_NO_IDLEST, - }; - - static __initdata struct omap_hwmod *omap2430_hwmods[] = { -@@ -925,12 +2667,34 @@ - &omap2430_l4_wkup_hwmod, - &omap2430_mpu_hwmod, - &omap2430_iva_hwmod, -+ -+ &omap2430_timer1_hwmod, -+ &omap2430_timer2_hwmod, -+ &omap2430_timer3_hwmod, -+ &omap2430_timer4_hwmod, -+ &omap2430_timer5_hwmod, -+ &omap2430_timer6_hwmod, -+ &omap2430_timer7_hwmod, -+ &omap2430_timer8_hwmod, -+ &omap2430_timer9_hwmod, -+ &omap2430_timer10_hwmod, -+ &omap2430_timer11_hwmod, -+ &omap2430_timer12_hwmod, -+ - &omap2430_wd_timer2_hwmod, - &omap2430_uart1_hwmod, - &omap2430_uart2_hwmod, - &omap2430_uart3_hwmod, -+ /* dss class */ -+ &omap2430_dss_core_hwmod, -+ &omap2430_dss_dispc_hwmod, -+ &omap2430_dss_rfbi_hwmod, -+ &omap2430_dss_venc_hwmod, -+ /* i2c class */ - &omap2430_i2c1_hwmod, - &omap2430_i2c2_hwmod, -+ &omap2430_mmc1_hwmod, -+ &omap2430_mmc2_hwmod, - - /* gpio class */ - &omap2430_gpio1_hwmod, -@@ -941,10 +2705,29 @@ - - /* dma_system class*/ - &omap2430_dma_system_hwmod, -+ -+ /* mcbsp class */ -+ &omap2430_mcbsp1_hwmod, -+ &omap2430_mcbsp2_hwmod, -+ &omap2430_mcbsp3_hwmod, -+ &omap2430_mcbsp4_hwmod, -+ &omap2430_mcbsp5_hwmod, -+ -+ /* mailbox class */ -+ &omap2430_mailbox_hwmod, -+ -+ /* mcspi class */ -+ &omap2430_mcspi1_hwmod, -+ &omap2430_mcspi2_hwmod, -+ &omap2430_mcspi3_hwmod, -+ -+ /* usbotg class*/ -+ &omap2430_usbhsotg_hwmod, -+ - NULL, - }; - - int __init omap2430_hwmod_init(void) - { -- return omap_hwmod_init(omap2430_hwmods); -+ return omap_hwmod_register(omap2430_hwmods); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 2011-03-09 13:19:09.829507237 +0100 -@@ -18,16 +18,22 @@ - #include - #include - #include -+#include - #include - #include - #include -+#include - #include -+#include -+#include -+#include - - #include "omap_hwmod_common_data.h" - - #include "prm-regbits-34xx.h" - #include "cm-regbits-34xx.h" - #include "wd_timer.h" -+#include - - /* - * OMAP3xxx hardware module integration data -@@ -44,6 +50,12 @@ - static struct omap_hwmod omap3xxx_l4_core_hwmod; - static struct omap_hwmod omap3xxx_l4_per_hwmod; - static struct omap_hwmod omap3xxx_wd_timer2_hwmod; -+static struct omap_hwmod omap3430es1_dss_core_hwmod; -+static struct omap_hwmod omap3xxx_dss_core_hwmod; -+static struct omap_hwmod omap3xxx_dss_dispc_hwmod; -+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod; -+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod; -+static struct omap_hwmod omap3xxx_dss_venc_hwmod; - static struct omap_hwmod omap3xxx_i2c1_hwmod; - static struct omap_hwmod omap3xxx_i2c2_hwmod; - static struct omap_hwmod omap3xxx_i2c3_hwmod; -@@ -55,9 +67,25 @@ - static struct omap_hwmod omap3xxx_gpio6_hwmod; - static struct omap_hwmod omap34xx_sr1_hwmod; - static struct omap_hwmod omap34xx_sr2_hwmod; -+static struct omap_hwmod omap34xx_mcspi1; -+static struct omap_hwmod omap34xx_mcspi2; -+static struct omap_hwmod omap34xx_mcspi3; -+static struct omap_hwmod omap34xx_mcspi4; -+static struct omap_hwmod omap3xxx_mmc1_hwmod; -+static struct omap_hwmod omap3xxx_mmc2_hwmod; -+static struct omap_hwmod omap3xxx_mmc3_hwmod; -+static struct omap_hwmod am35xx_usbhsotg_hwmod; - - static struct omap_hwmod omap3xxx_dma_system_hwmod; - -+static struct omap_hwmod omap3xxx_mcbsp1_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp2_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp3_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp4_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp5_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod; -+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod; -+ - /* L3 -> L4_CORE interface */ - static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { - .master = &omap3xxx_l3_main_hwmod, -@@ -84,6 +112,19 @@ - &omap3xxx_mpu__l3_main, - }; - -+/* DSS -> l3 */ -+static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = { -+ .master = &omap3xxx_dss_core_hwmod, -+ .slave = &omap3xxx_l3_main_hwmod, -+ .fw = { -+ .omap2 = { -+ .l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS, -+ .flags = OMAP_FIREWALL_L3, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* Master interfaces on the L3 interconnect */ - static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = { - &omap3xxx_l3_main__l4_core, -@@ -107,7 +148,23 @@ - static struct omap_hwmod omap3xxx_uart2_hwmod; - static struct omap_hwmod omap3xxx_uart3_hwmod; - static struct omap_hwmod omap3xxx_uart4_hwmod; -+static struct omap_hwmod omap3xxx_usbhsotg_hwmod; -+ -+/* l3_core -> usbhsotg interface */ -+static struct omap_hwmod_ocp_if omap3xxx_usbhsotg__l3 = { -+ .master = &omap3xxx_usbhsotg_hwmod, -+ .slave = &omap3xxx_l3_main_hwmod, -+ .clk = "core_l3_ick", -+ .user = OCP_USER_MPU, -+}; - -+/* l3_core -> am35xx_usbhsotg interface */ -+static struct omap_hwmod_ocp_if am35xx_usbhsotg__l3 = { -+ .master = &am35xx_usbhsotg_hwmod, -+ .slave = &omap3xxx_l3_main_hwmod, -+ .clk = "core_l3_ick", -+ .user = OCP_USER_MPU, -+}; - /* L4_CORE -> L4_WKUP interface */ - static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { - .master = &omap3xxx_l4_core_hwmod, -@@ -115,6 +172,63 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* L4 CORE -> MMC1 interface */ -+static struct omap_hwmod_addr_space omap3xxx_mmc1_addr_space[] = { -+ { -+ .pa_start = 0x4809c000, -+ .pa_end = 0x4809c1ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc1 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mmc1_hwmod, -+ .clk = "mmchs1_ick", -+ .addr = omap3xxx_mmc1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+ .flags = OMAP_FIREWALL_L4 -+}; -+ -+/* L4 CORE -> MMC2 interface */ -+static struct omap_hwmod_addr_space omap3xxx_mmc2_addr_space[] = { -+ { -+ .pa_start = 0x480b4000, -+ .pa_end = 0x480b41ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc2 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mmc2_hwmod, -+ .clk = "mmchs2_ick", -+ .addr = omap3xxx_mmc2_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+ .flags = OMAP_FIREWALL_L4 -+}; -+ -+/* L4 CORE -> MMC3 interface */ -+static struct omap_hwmod_addr_space omap3xxx_mmc3_addr_space[] = { -+ { -+ .pa_start = 0x480ad000, -+ .pa_end = 0x480ad1ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mmc3 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mmc3_hwmod, -+ .clk = "mmchs3_ick", -+ .addr = omap3xxx_mmc3_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mmc3_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+ .flags = OMAP_FIREWALL_L4 -+}; -+ - /* L4 CORE -> UART1 interface */ - static struct omap_hwmod_addr_space omap3xxx_uart1_addr_space[] = { - { -@@ -301,6 +415,61 @@ - .user = OCP_USER_MPU, - }; - -+/* -+* usbhsotg interface data -+*/ -+ -+static struct omap_hwmod_addr_space omap3xxx_usbhsotg_addrs[] = { -+ { -+ .pa_start = OMAP34XX_HSUSB_OTG_BASE, -+ .pa_end = OMAP34XX_HSUSB_OTG_BASE + SZ_4K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> usbhsotg */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__usbhsotg = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_usbhsotg_hwmod, -+ .clk = "l4_ick", -+ .addr = omap3xxx_usbhsotg_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_masters[] = { -+ &omap3xxx_usbhsotg__l3, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_usbhsotg_slaves[] = { -+ &omap3xxx_l4_core__usbhsotg, -+}; -+ -+static struct omap_hwmod_addr_space am35xx_usbhsotg_addrs[] = { -+ { -+ .pa_start = AM35XX_IPSS_USBOTGSS_BASE, -+ .pa_end = AM35XX_IPSS_USBOTGSS_BASE + SZ_4K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> usbhsotg */ -+static struct omap_hwmod_ocp_if am35xx_l4_core__usbhsotg = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &am35xx_usbhsotg_hwmod, -+ .clk = "l4_ick", -+ .addr = am35xx_usbhsotg_addrs, -+ .addr_cnt = ARRAY_SIZE(am35xx_usbhsotg_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_ocp_if *am35xx_usbhsotg_masters[] = { -+ &am35xx_usbhsotg__l3, -+}; -+ -+static struct omap_hwmod_ocp_if *am35xx_usbhsotg_slaves[] = { -+ &am35xx_l4_core__usbhsotg, -+}; - /* Slave interfaces on the L4_CORE interconnect */ - static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { - &omap3xxx_l3_main__l4_core, -@@ -417,251 +586,1292 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }; - --/* l4_wkup -> wd_timer2 */ --static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = { -- { -- .pa_start = 0x48314000, -- .pa_end = 0x4831407f, -- .flags = ADDR_TYPE_RT -- }, -+/* timer class */ -+static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = { -- .master = &omap3xxx_l4_wkup_hwmod, -- .slave = &omap3xxx_wd_timer2_hwmod, -- .clk = "wdt2_ick", -- .addr = omap3xxx_wd_timer2_addrs, -- .addr_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap3xxx_timer_1ms_sysc, -+ .rev = OMAP_TIMER_IP_VERSION_1, - }; - --/* -- * 'wd_timer' class -- * 32-bit watchdog upward counter that generates a pulse on the reset pin on -- * overflow condition -- */ -- --static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = { -+static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { - .rev_offs = 0x0000, - .sysc_offs = 0x0010, - .syss_offs = 0x0014, -- .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | -- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -- SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY), -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), - .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --/* I2C common */ --static struct omap_hwmod_class_sysconfig i2c_sysc = { -- .rev_offs = 0x00, -- .sysc_offs = 0x20, -- .syss_offs = 0x10, -- .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -- SYSC_HAS_AUTOIDLE), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap3xxx_timer_sysc, -+ .rev = OMAP_TIMER_IP_VERSION_1, - }; - --static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = { -- .name = "wd_timer", -- .sysc = &omap3xxx_wd_timer_sysc, -- .pre_shutdown = &omap2_wd_timer_disable -+/* timer1 */ -+static struct omap_hwmod omap3xxx_timer1_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer1_mpu_irqs[] = { -+ { .irq = 37, }, - }; - --/* wd_timer2 */ --static struct omap_hwmod_ocp_if *omap3xxx_wd_timer2_slaves[] = { -- &omap3xxx_l4_wkup__wd_timer2, -+static struct omap_hwmod_addr_space omap3xxx_timer1_addrs[] = { -+ { -+ .pa_start = 0x48318000, -+ .pa_end = 0x48318000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { -- .name = "wd_timer2", -- .class = &omap3xxx_wd_timer_hwmod_class, -- .main_clk = "wdt2_fck", -+/* l4_wkup -> timer1 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__timer1 = { -+ .master = &omap3xxx_l4_wkup_hwmod, -+ .slave = &omap3xxx_timer1_hwmod, -+ .clk = "gpt1_ick", -+ .addr = omap3xxx_timer1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer1 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer1_slaves[] = { -+ &omap3xxx_l4_wkup__timer1, -+}; -+ -+/* timer1 hwmod */ -+static struct omap_hwmod omap3xxx_timer1_hwmod = { -+ .name = "timer1", -+ .mpu_irqs = omap3xxx_timer1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer1_mpu_irqs), -+ .main_clk = "gpt1_fck", - .prcm = { - .omap2 = { - .prcm_reg_id = 1, -- .module_bit = OMAP3430_EN_WDT2_SHIFT, -+ .module_bit = OMAP3430_EN_GPT1_SHIFT, - .module_offs = WKUP_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP3430_ST_WDT2_SHIFT, -+ .idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT, - }, - }, -- .slaves = omap3xxx_wd_timer2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves), -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), --}; -- --/* UART common */ -- --static struct omap_hwmod_class_sysconfig uart_sysc = { -- .rev_offs = 0x50, -- .sysc_offs = 0x54, -- .syss_offs = 0x58, -- .sysc_flags = (SYSC_HAS_SIDLEMODE | -- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -- SYSC_HAS_AUTOIDLE), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -- .sysc_fields = &omap_hwmod_sysc_type1, -+ .slaves = omap3xxx_timer1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer1_slaves), -+ .class = &omap3xxx_timer_1ms_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }; - --static struct omap_hwmod_class uart_class = { -- .name = "uart", -- .sysc = &uart_sysc, -+/* timer2 */ -+static struct omap_hwmod omap3xxx_timer2_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer2_mpu_irqs[] = { -+ { .irq = 38, }, - }; - --/* UART1 */ -- --static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -- { .irq = INT_24XX_UART1_IRQ, }, -+static struct omap_hwmod_addr_space omap3xxx_timer2_addrs[] = { -+ { -+ .pa_start = 0x49032000, -+ .pa_end = 0x49032000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -+/* l4_per -> timer2 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer2 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer2_hwmod, -+ .clk = "gpt2_ick", -+ .addr = omap3xxx_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap3xxx_uart1_slaves[] = { -- &omap3_l4_core__uart1, -+/* timer2 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer2_slaves[] = { -+ &omap3xxx_l4_per__timer2, - }; - --static struct omap_hwmod omap3xxx_uart1_hwmod = { -- .name = "uart1", -- .mpu_irqs = uart1_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -- .sdma_reqs = uart1_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -- .main_clk = "uart1_fck", -+/* timer2 hwmod */ -+static struct omap_hwmod omap3xxx_timer2_hwmod = { -+ .name = "timer2", -+ .mpu_irqs = omap3xxx_timer2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer2_mpu_irqs), -+ .main_clk = "gpt2_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP3430_EN_UART1_SHIFT, -+ .module_bit = OMAP3430_EN_GPT2_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP3430_EN_UART1_SHIFT, -+ .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, - }, - }, -- .slaves = omap3xxx_uart1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap3xxx_uart1_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+ .slaves = omap3xxx_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer2_slaves), -+ .class = &omap3xxx_timer_1ms_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }; - --/* UART2 */ -+/* timer3 */ -+static struct omap_hwmod omap3xxx_timer3_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer3_mpu_irqs[] = { -+ { .irq = 39, }, -+}; - --static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -- { .irq = INT_24XX_UART2_IRQ, }, -+static struct omap_hwmod_addr_space omap3xxx_timer3_addrs[] = { -+ { -+ .pa_start = 0x49034000, -+ .pa_end = 0x49034000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -+/* l4_per -> timer3 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer3 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer3_hwmod, -+ .clk = "gpt3_ick", -+ .addr = omap3xxx_timer3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap3xxx_uart2_slaves[] = { -- &omap3_l4_core__uart2, -+/* timer3 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer3_slaves[] = { -+ &omap3xxx_l4_per__timer3, - }; - --static struct omap_hwmod omap3xxx_uart2_hwmod = { -- .name = "uart2", -- .mpu_irqs = uart2_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -- .sdma_reqs = uart2_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -- .main_clk = "uart2_fck", -+/* timer3 hwmod */ -+static struct omap_hwmod omap3xxx_timer3_hwmod = { -+ .name = "timer3", -+ .mpu_irqs = omap3xxx_timer3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer3_mpu_irqs), -+ .main_clk = "gpt3_fck", - .prcm = { - .omap2 = { -- .module_offs = CORE_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP3430_EN_UART2_SHIFT, -+ .module_bit = OMAP3430_EN_GPT3_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP3430_EN_UART2_SHIFT, -+ .idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT, - }, - }, -- .slaves = omap3xxx_uart2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap3xxx_uart2_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+ .slaves = omap3xxx_timer3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer3_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }; - --/* UART3 */ -+/* timer4 */ -+static struct omap_hwmod omap3xxx_timer4_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer4_mpu_irqs[] = { -+ { .irq = 40, }, -+}; - --static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -- { .irq = INT_24XX_UART3_IRQ, }, -+static struct omap_hwmod_addr_space omap3xxx_timer4_addrs[] = { -+ { -+ .pa_start = 0x49036000, -+ .pa_end = 0x49036000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -- { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -- { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -+/* l4_per -> timer4 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer4 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer4_hwmod, -+ .clk = "gpt4_ick", -+ .addr = omap3xxx_timer4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --static struct omap_hwmod_ocp_if *omap3xxx_uart3_slaves[] = { -- &omap3_l4_per__uart3, -+/* timer4 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer4_slaves[] = { -+ &omap3xxx_l4_per__timer4, - }; - --static struct omap_hwmod omap3xxx_uart3_hwmod = { -- .name = "uart3", -- .mpu_irqs = uart3_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -- .sdma_reqs = uart3_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -- .main_clk = "uart3_fck", -+/* timer4 hwmod */ -+static struct omap_hwmod omap3xxx_timer4_hwmod = { -+ .name = "timer4", -+ .mpu_irqs = omap3xxx_timer4_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer4_mpu_irqs), -+ .main_clk = "gpt4_fck", - .prcm = { - .omap2 = { -- .module_offs = OMAP3430_PER_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP3430_EN_UART3_SHIFT, -+ .module_bit = OMAP3430_EN_GPT4_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, - .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP3430_EN_UART3_SHIFT, -+ .idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT, - }, - }, -- .slaves = omap3xxx_uart3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap3xxx_uart3_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+ .slaves = omap3xxx_timer4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer4_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) - }; - --/* UART4 */ -+/* timer5 */ -+static struct omap_hwmod omap3xxx_timer5_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer5_mpu_irqs[] = { -+ { .irq = 41, }, -+}; - --static struct omap_hwmod_irq_info uart4_mpu_irqs[] = { -- { .irq = INT_36XX_UART4_IRQ, }, -+static struct omap_hwmod_addr_space omap3xxx_timer5_addrs[] = { -+ { -+ .pa_start = 0x49038000, -+ .pa_end = 0x49038000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_dma_info uart4_sdma_reqs[] = { -- { .name = "rx", .dma_req = OMAP36XX_DMA_UART4_RX, }, -+/* l4_per -> timer5 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer5 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer5_hwmod, -+ .clk = "gpt5_ick", -+ .addr = omap3xxx_timer5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer5 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer5_slaves[] = { -+ &omap3xxx_l4_per__timer5, -+}; -+ -+/* timer5 hwmod */ -+static struct omap_hwmod omap3xxx_timer5_hwmod = { -+ .name = "timer5", -+ .mpu_irqs = omap3xxx_timer5_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer5_mpu_irqs), -+ .main_clk = "gpt5_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT5_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer5_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer6 */ -+static struct omap_hwmod omap3xxx_timer6_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer6_mpu_irqs[] = { -+ { .irq = 42, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer6_addrs[] = { -+ { -+ .pa_start = 0x4903A000, -+ .pa_end = 0x4903A000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> timer6 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer6 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer6_hwmod, -+ .clk = "gpt6_ick", -+ .addr = omap3xxx_timer6_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer6_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer6 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer6_slaves[] = { -+ &omap3xxx_l4_per__timer6, -+}; -+ -+/* timer6 hwmod */ -+static struct omap_hwmod omap3xxx_timer6_hwmod = { -+ .name = "timer6", -+ .mpu_irqs = omap3xxx_timer6_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer6_mpu_irqs), -+ .main_clk = "gpt6_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT6_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer6_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer6_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer7 */ -+static struct omap_hwmod omap3xxx_timer7_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer7_mpu_irqs[] = { -+ { .irq = 43, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer7_addrs[] = { -+ { -+ .pa_start = 0x4903C000, -+ .pa_end = 0x4903C000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> timer7 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer7 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer7_hwmod, -+ .clk = "gpt7_ick", -+ .addr = omap3xxx_timer7_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer7_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer7 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer7_slaves[] = { -+ &omap3xxx_l4_per__timer7, -+}; -+ -+/* timer7 hwmod */ -+static struct omap_hwmod omap3xxx_timer7_hwmod = { -+ .name = "timer7", -+ .mpu_irqs = omap3xxx_timer7_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer7_mpu_irqs), -+ .main_clk = "gpt7_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT7_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer7_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer7_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer8 */ -+static struct omap_hwmod omap3xxx_timer8_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer8_mpu_irqs[] = { -+ { .irq = 44, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer8_addrs[] = { -+ { -+ .pa_start = 0x4903E000, -+ .pa_end = 0x4903E000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> timer8 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer8 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer8_hwmod, -+ .clk = "gpt8_ick", -+ .addr = omap3xxx_timer8_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer8_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer8 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer8_slaves[] = { -+ &omap3xxx_l4_per__timer8, -+}; -+ -+/* timer8 hwmod */ -+static struct omap_hwmod omap3xxx_timer8_hwmod = { -+ .name = "timer8", -+ .mpu_irqs = omap3xxx_timer8_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer8_mpu_irqs), -+ .main_clk = "gpt8_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT8_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer8_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer8_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer9 */ -+static struct omap_hwmod omap3xxx_timer9_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer9_mpu_irqs[] = { -+ { .irq = 45, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer9_addrs[] = { -+ { -+ .pa_start = 0x49040000, -+ .pa_end = 0x49040000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> timer9 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__timer9 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_timer9_hwmod, -+ .clk = "gpt9_ick", -+ .addr = omap3xxx_timer9_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer9_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer9 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer9_slaves[] = { -+ &omap3xxx_l4_per__timer9, -+}; -+ -+/* timer9 hwmod */ -+static struct omap_hwmod omap3xxx_timer9_hwmod = { -+ .name = "timer9", -+ .mpu_irqs = omap3xxx_timer9_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer9_mpu_irqs), -+ .main_clk = "gpt9_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT9_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer9_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer9_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer10 */ -+static struct omap_hwmod omap3xxx_timer10_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer10_mpu_irqs[] = { -+ { .irq = 46, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer10_addrs[] = { -+ { -+ .pa_start = 0x48086000, -+ .pa_end = 0x48086000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer10 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer10 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_timer10_hwmod, -+ .clk = "gpt10_ick", -+ .addr = omap3xxx_timer10_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer10_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer10 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer10_slaves[] = { -+ &omap3xxx_l4_core__timer10, -+}; -+ -+/* timer10 hwmod */ -+static struct omap_hwmod omap3xxx_timer10_hwmod = { -+ .name = "timer10", -+ .mpu_irqs = omap3xxx_timer10_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer10_mpu_irqs), -+ .main_clk = "gpt10_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT10_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer10_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer10_slaves), -+ .class = &omap3xxx_timer_1ms_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer11 */ -+static struct omap_hwmod omap3xxx_timer11_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer11_mpu_irqs[] = { -+ { .irq = 47, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer11_addrs[] = { -+ { -+ .pa_start = 0x48088000, -+ .pa_end = 0x48088000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer11 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer11 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_timer11_hwmod, -+ .clk = "gpt11_ick", -+ .addr = omap3xxx_timer11_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer11_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer11 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer11_slaves[] = { -+ &omap3xxx_l4_core__timer11, -+}; -+ -+/* timer11 hwmod */ -+static struct omap_hwmod omap3xxx_timer11_hwmod = { -+ .name = "timer11", -+ .mpu_irqs = omap3xxx_timer11_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer11_mpu_irqs), -+ .main_clk = "gpt11_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT11_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer11_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer11_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* timer12*/ -+static struct omap_hwmod omap3xxx_timer12_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_timer12_mpu_irqs[] = { -+ { .irq = 95, }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_timer12_addrs[] = { -+ { -+ .pa_start = 0x48304000, -+ .pa_end = 0x48304000 + SZ_1K - 1, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> timer12 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__timer12 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_timer12_hwmod, -+ .clk = "gpt12_ick", -+ .addr = omap3xxx_timer12_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_timer12_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* timer12 slave port */ -+static struct omap_hwmod_ocp_if *omap3xxx_timer12_slaves[] = { -+ &omap3xxx_l4_core__timer12, -+}; -+ -+/* timer12 hwmod */ -+static struct omap_hwmod omap3xxx_timer12_hwmod = { -+ .name = "timer12", -+ .mpu_irqs = omap3xxx_timer12_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_timer12_mpu_irqs), -+ .main_clk = "gpt12_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_GPT12_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_timer12_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_timer12_slaves), -+ .class = &omap3xxx_timer_hwmod_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* l4_wkup -> wd_timer2 */ -+static struct omap_hwmod_addr_space omap3xxx_wd_timer2_addrs[] = { -+ { -+ .pa_start = 0x48314000, -+ .pa_end = 0x4831407f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__wd_timer2 = { -+ .master = &omap3xxx_l4_wkup_hwmod, -+ .slave = &omap3xxx_wd_timer2_hwmod, -+ .clk = "wdt2_ick", -+ .addr = omap3xxx_wd_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* -+ * 'wd_timer' class -+ * 32-bit watchdog upward counter that generates a pulse on the reset pin on -+ * overflow condition -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_wd_timer_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_EMUFREE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+/* I2C common */ -+static struct omap_hwmod_class_sysconfig i2c_sysc = { -+ .rev_offs = 0x00, -+ .sysc_offs = 0x20, -+ .syss_offs = 0x10, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = { -+ .name = "wd_timer", -+ .sysc = &omap3xxx_wd_timer_sysc, -+ .pre_shutdown = &omap2_wd_timer_disable -+}; -+ -+/* wd_timer2 */ -+static struct omap_hwmod_ocp_if *omap3xxx_wd_timer2_slaves[] = { -+ &omap3xxx_l4_wkup__wd_timer2, -+}; -+ -+static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { -+ .name = "wd_timer2", -+ .class = &omap3xxx_wd_timer_hwmod_class, -+ .main_clk = "wdt2_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_WDT2_SHIFT, -+ .module_offs = WKUP_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_WDT2_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_wd_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* UART common */ -+ -+static struct omap_hwmod_class_sysconfig uart_sysc = { -+ .rev_offs = 0x50, -+ .sysc_offs = 0x54, -+ .syss_offs = 0x58, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class uart_class = { -+ .name = "uart", -+ .sysc = &uart_sysc, -+}; -+ -+/* UART1 */ -+ -+static struct omap_hwmod_irq_info uart1_mpu_irqs[] = { -+ { .irq = INT_24XX_UART1_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART1_TX, }, -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART1_RX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_uart1_slaves[] = { -+ &omap3_l4_core__uart1, -+}; -+ -+static struct omap_hwmod omap3xxx_uart1_hwmod = { -+ .name = "uart1", -+ .mpu_irqs = uart1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart1_mpu_irqs), -+ .sdma_reqs = uart1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart1_sdma_reqs), -+ .main_clk = "uart1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_UART1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_EN_UART1_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_uart1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart1_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* UART2 */ -+ -+static struct omap_hwmod_irq_info uart2_mpu_irqs[] = { -+ { .irq = INT_24XX_UART2_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART2_TX, }, -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART2_RX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_uart2_slaves[] = { -+ &omap3_l4_core__uart2, -+}; -+ -+static struct omap_hwmod omap3xxx_uart2_hwmod = { -+ .name = "uart2", -+ .mpu_irqs = uart2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart2_mpu_irqs), -+ .sdma_reqs = uart2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart2_sdma_reqs), -+ .main_clk = "uart2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_UART2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_EN_UART2_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_uart2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart2_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* UART3 */ -+ -+static struct omap_hwmod_irq_info uart3_mpu_irqs[] = { -+ { .irq = INT_24XX_UART3_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart3_sdma_reqs[] = { -+ { .name = "tx", .dma_req = OMAP24XX_DMA_UART3_TX, }, -+ { .name = "rx", .dma_req = OMAP24XX_DMA_UART3_RX, }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_uart3_slaves[] = { -+ &omap3_l4_per__uart3, -+}; -+ -+static struct omap_hwmod omap3xxx_uart3_hwmod = { -+ .name = "uart3", -+ .mpu_irqs = uart3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart3_mpu_irqs), -+ .sdma_reqs = uart3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart3_sdma_reqs), -+ .main_clk = "uart3_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = OMAP3430_PER_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_UART3_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_EN_UART3_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_uart3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart3_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* UART4 */ -+ -+static struct omap_hwmod_irq_info uart4_mpu_irqs[] = { -+ { .irq = INT_36XX_UART4_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info uart4_sdma_reqs[] = { -+ { .name = "rx", .dma_req = OMAP36XX_DMA_UART4_RX, }, - { .name = "tx", .dma_req = OMAP36XX_DMA_UART4_TX, }, - }; - --static struct omap_hwmod_ocp_if *omap3xxx_uart4_slaves[] = { -- &omap3_l4_per__uart4, -+static struct omap_hwmod_ocp_if *omap3xxx_uart4_slaves[] = { -+ &omap3_l4_per__uart4, -+}; -+ -+static struct omap_hwmod omap3xxx_uart4_hwmod = { -+ .name = "uart4", -+ .mpu_irqs = uart4_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(uart4_mpu_irqs), -+ .sdma_reqs = uart4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(uart4_sdma_reqs), -+ .main_clk = "uart4_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = OMAP3430_PER_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3630_EN_UART4_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3630_EN_UART4_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_uart4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_uart4_slaves), -+ .class = &uart_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1), -+}; -+ -+static struct omap_hwmod_class i2c_class = { -+ .name = "i2c", -+ .sysc = &i2c_sysc, -+}; -+ -+/* -+ * 'dss' class -+ * display sub-system -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_dss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_dss_hwmod_class = { -+ .name = "dss", -+ .sysc = &omap3xxx_dss_sysc, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = { -+ { .name = "dispc", .dma_req = 5 }, -+ { .name = "dsi1", .dma_req = 74 }, -+}; -+ -+/* dss */ -+/* dss master ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_masters[] = { -+ &omap3xxx_dss__l3, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_dss_addrs[] = { -+ { -+ .pa_start = 0x48050000, -+ .pa_end = 0x480503FF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss */ -+static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3430es1_dss_core_hwmod, -+ .clk = "dss_ick", -+ .addr = omap3xxx_dss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_dss_core_hwmod, -+ .clk = "dss_ick", -+ .addr = omap3xxx_dss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss slave ports */ -+static struct omap_hwmod_ocp_if *omap3430es1_dss_slaves[] = { -+ &omap3430es1_l4_core__dss, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = { -+ &omap3xxx_l4_core__dss, -+}; -+ -+static struct omap_hwmod_opt_clk dss_opt_clks[] = { -+ { .role = "tv_clk", .clk = "dss_tv_fck" }, -+ { .role = "video_clk", .clk = "dss_96m_fck" }, -+ { .role = "sys_clk", .clk = "dss2_alwon_fck" }, -+}; -+ -+static struct omap_hwmod omap3430es1_dss_core_hwmod = { -+ .name = "dss_core", -+ .class = &omap3xxx_dss_hwmod_class, -+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ -+ .sdma_reqs = omap3xxx_dss_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), -+ -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, -+ .idlest_reg_id = 1, -+ .idlest_stdby_bit = OMAP3430ES1_ST_DSS_SHIFT, -+ }, -+ }, -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+ .slaves = omap3430es1_dss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3430es1_dss_slaves), -+ .masters = omap3xxx_dss_masters, -+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+static struct omap_hwmod omap3xxx_dss_core_hwmod = { -+ .name = "dss_core", -+ .class = &omap3xxx_dss_hwmod_class, -+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */ -+ .sdma_reqs = omap3xxx_dss_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs), -+ -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT, -+ .idlest_stdby_bit = OMAP3430ES2_ST_DSS_STDBY_SHIFT, -+ }, -+ }, -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+ .slaves = omap3xxx_dss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_slaves), -+ .masters = omap3xxx_dss_masters, -+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2 | -+ CHIP_IS_OMAP3630ES1 | CHIP_GE_OMAP3630ES1_1), -+}; -+ -+/* -+ * 'dispc' class -+ * display controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_MIDLEMODE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &omap3xxx_dispc_sysc, -+}; -+ -+static struct omap_hwmod_irq_info omap3xxx_dispc_irqs[] = { -+ { .irq = 25 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = { -+ { -+ .pa_start = 0x48050400, -+ .pa_end = 0x480507FF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_dss_dispc_hwmod, -+ .clk = "dss_ick", -+ .addr = omap3xxx_dss_dispc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_dispc slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = { -+ &omap3xxx_l4_core__dss_dispc, -+}; -+ -+static struct omap_hwmod omap3xxx_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &omap3xxx_dispc_hwmod_class, -+ .mpu_irqs = omap3xxx_dispc_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dispc_irqs), -+ .main_clk = "dss1_alwon_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, -+ }, -+ }, -+ .slaves = omap3xxx_dss_dispc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | -+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | -+ CHIP_GE_OMAP3630ES1_1), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'dsi' class -+ * display serial interface controller -+ */ -+ -+static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = { -+ .name = "dsi", -+}; -+ -+static struct omap_hwmod_irq_info omap3xxx_dsi1_irqs[] = { -+ { .irq = 25 }, -+}; -+ -+/* dss_dsi1 */ -+static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = { -+ { -+ .pa_start = 0x4804FC00, -+ .pa_end = 0x4804FFFF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_dsi1 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_dss_dsi1_hwmod, -+ .addr = omap3xxx_dss_dsi1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_dsi1 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = { -+ &omap3xxx_l4_core__dss_dsi1, -+}; -+ -+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = { -+ .name = "dss_dsi1", -+ .class = &omap3xxx_dsi_hwmod_class, -+ .mpu_irqs = omap3xxx_dsi1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dsi1_irqs), -+ .main_clk = "dss1_alwon_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, -+ }, -+ }, -+ .slaves = omap3xxx_dss_dsi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | -+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | -+ CHIP_GE_OMAP3630ES1_1), -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'rfbi' class -+ * remote frame buffer interface -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_rfbi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_rfbi_hwmod_class = { -+ .name = "rfbi", -+ .sysc = &omap3xxx_rfbi_sysc, - }; - --static struct omap_hwmod omap3xxx_uart4_hwmod = { -- .name = "uart4", -- .mpu_irqs = uart4_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(uart4_mpu_irqs), -- .sdma_reqs = uart4_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(uart4_sdma_reqs), -- .main_clk = "uart4_fck", -+static struct omap_hwmod_addr_space omap3xxx_dss_rfbi_addrs[] = { -+ { -+ .pa_start = 0x48050800, -+ .pa_end = 0x48050BFF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_dss_rfbi_hwmod, -+ .clk = "dss_ick", -+ .addr = omap3xxx_dss_rfbi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP , -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_rfbi slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = { -+ &omap3xxx_l4_core__dss_rfbi, -+}; -+ -+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap3xxx_rfbi_hwmod_class, -+ .main_clk = "dss1_alwon_fck", - .prcm = { - .omap2 = { -- .module_offs = OMAP3430_PER_MOD, - .prcm_reg_id = 1, -- .module_bit = OMAP3630_EN_UART4_SHIFT, -- .idlest_reg_id = 1, -- .idlest_idle_bit = OMAP3630_EN_UART4_SHIFT, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, - }, - }, -- .slaves = omap3xxx_uart4_slaves, -- .slaves_cnt = ARRAY_SIZE(omap3xxx_uart4_slaves), -- .class = &uart_class, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1), -+ .slaves = omap3xxx_dss_rfbi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | -+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | -+ CHIP_GE_OMAP3630ES1_1), -+ .flags = HWMOD_NO_IDLEST, - }; - --static struct omap_hwmod_class i2c_class = { -- .name = "i2c", -- .sysc = &i2c_sysc, -+/* -+ * 'venc' class -+ * video encoder -+ */ -+ -+static struct omap_hwmod_class omap3xxx_venc_hwmod_class = { -+ .name = "venc", -+}; -+ -+/* dss_venc */ -+static struct omap_hwmod_addr_space omap3xxx_dss_venc_addrs[] = { -+ { -+ .pa_start = 0x48050C00, -+ .pa_end = 0x48050FFF, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> dss_venc */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_dss_venc_hwmod, -+ .clk = "dss_tv_fck", -+ .addr = omap3xxx_dss_venc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_venc_addrs), -+ .fw = { -+ .omap2 = { -+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION, -+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP, -+ .flags = OMAP_FIREWALL_L4, -+ } -+ }, -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* dss_venc slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = { -+ &omap3xxx_l4_core__dss_venc, -+}; -+ -+static struct omap_hwmod omap3xxx_dss_venc_hwmod = { -+ .name = "dss_venc", -+ .class = &omap3xxx_venc_hwmod_class, -+ .main_clk = "dss1_alwon_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_DSS1_SHIFT, -+ .module_offs = OMAP3430_DSS_MOD, -+ }, -+ }, -+ .slaves = omap3xxx_dss_venc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 | -+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 | -+ CHIP_GE_OMAP3630ES1_1), -+ .flags = HWMOD_NO_IDLEST, - }; - - /* I2C1 */ -@@ -1224,9 +2434,440 @@ - .masters_cnt = ARRAY_SIZE(omap3xxx_dma_system_masters), - .dev_attr = &dma_dev_attr, - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -- .flags = HWMOD_NO_IDLEST, -+ .flags = HWMOD_NO_IDLEST, -+}; -+ -+/* -+ * 'mcbsp' class -+ * multi channel buffered serial port controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = { -+ .sysc_offs = 0x008c, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+ .clockact = 0x2, -+}; -+ -+static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { -+ .name = "mcbsp", -+ .sysc = &omap3xxx_mcbsp_sysc, -+ .rev = MCBSP_CONFIG_TYPE3, -+}; -+ -+/* mcbsp1 */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = { -+ { .name = "irq", .irq = 16 }, -+ { .name = "tx", .irq = 59 }, -+ { .name = "rx", .irq = 60 }, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_mcbsp1_sdma_chs[] = { -+ { .name = "rx", .dma_req = 32 }, -+ { .name = "tx", .dma_req = 31 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp1_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48074000, -+ .pa_end = 0x480740ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp1 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mcbsp1_hwmod, -+ .clk = "mcbsp1_ick", -+ .addr = omap3xxx_mcbsp1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp1 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp1_slaves[] = { -+ &omap3xxx_l4_core__mcbsp1, -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { -+ .name = "mcbsp1", -+ .class = &omap3xxx_mcbsp_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_irqs), -+ .sdma_reqs = omap3xxx_mcbsp1_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_sdma_chs), -+ .main_clk = "mcbsp1_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP1_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP1_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcbsp2 */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = { -+ { .name = "irq", .irq = 17 }, -+ { .name = "tx", .irq = 62 }, -+ { .name = "rx", .irq = 63 }, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_mcbsp2_sdma_chs[] = { -+ { .name = "rx", .dma_req = 34 }, -+ { .name = "tx", .dma_req = 33 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x49022000, -+ .pa_end = 0x490220ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp2 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_mcbsp2_hwmod, -+ .clk = "mcbsp2_ick", -+ .addr = omap3xxx_mcbsp2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp2 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_slaves[] = { -+ &omap3xxx_l4_per__mcbsp2, -+}; -+ -+static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = { -+ .sidetone = "mcbsp2_sidetone", -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { -+ .name = "mcbsp2", -+ .class = &omap3xxx_mcbsp_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_irqs), -+ .sdma_reqs = omap3xxx_mcbsp2_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sdma_chs), -+ .main_clk = "mcbsp2_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP2_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_slaves), -+ .dev_attr = &omap34xx_mcbsp2_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcbsp3 */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = { -+ { .name = "irq", .irq = 22 }, -+ { .name = "tx", .irq = 89 }, -+ { .name = "rx", .irq = 90 }, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_mcbsp3_sdma_chs[] = { -+ { .name = "rx", .dma_req = 18 }, -+ { .name = "tx", .dma_req = 17 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x49024000, -+ .pa_end = 0x490240ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp3 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_mcbsp3_hwmod, -+ .clk = "mcbsp3_ick", -+ .addr = omap3xxx_mcbsp3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp3 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_slaves[] = { -+ &omap3xxx_l4_per__mcbsp3, -+}; -+ -+static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = { -+ .sidetone = "mcbsp3_sidetone", -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { -+ .name = "mcbsp3", -+ .class = &omap3xxx_mcbsp_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_irqs), -+ .sdma_reqs = omap3xxx_mcbsp3_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sdma_chs), -+ .main_clk = "mcbsp3_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP3_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_slaves), -+ .dev_attr = &omap34xx_mcbsp3_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcbsp4 */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = { -+ { .name = "irq", .irq = 23 }, -+ { .name = "tx", .irq = 54 }, -+ { .name = "rx", .irq = 55 }, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_mcbsp4_sdma_chs[] = { -+ { .name = "rx", .dma_req = 20 }, -+ { .name = "tx", .dma_req = 19 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp4_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x49026000, -+ .pa_end = 0x490260ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp4 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp4 = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_mcbsp4_hwmod, -+ .clk = "mcbsp4_ick", -+ .addr = omap3xxx_mcbsp4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp4 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp4_slaves[] = { -+ &omap3xxx_l4_per__mcbsp4, -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { -+ .name = "mcbsp4", -+ .class = &omap3xxx_mcbsp_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_irqs), -+ .sdma_reqs = omap3xxx_mcbsp4_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_sdma_chs), -+ .main_clk = "mcbsp4_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP4_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP4_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcbsp5 */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = { -+ { .name = "irq", .irq = 27 }, -+ { .name = "tx", .irq = 81 }, -+ { .name = "rx", .irq = 82 }, -+}; -+ -+static struct omap_hwmod_dma_info omap3xxx_mcbsp5_sdma_chs[] = { -+ { .name = "rx", .dma_req = 22 }, -+ { .name = "tx", .dma_req = 21 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp5_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x48096000, -+ .pa_end = 0x480960ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_core -> mcbsp5 */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp5 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mcbsp5_hwmod, -+ .clk = "mcbsp5_ick", -+ .addr = omap3xxx_mcbsp5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp5 slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp5_slaves[] = { -+ &omap3xxx_l4_core__mcbsp5, -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp5_hwmod = { -+ .name = "mcbsp5", -+ .class = &omap3xxx_mcbsp_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_irqs), -+ .sdma_reqs = omap3xxx_mcbsp5_sdma_chs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_sdma_chs), -+ .main_clk = "mcbsp5_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP5_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP5_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+/* 'mcbsp sidetone' class */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = { -+ .sysc_offs = 0x0010, -+ .sysc_flags = SYSC_HAS_AUTOIDLE, -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = { -+ .name = "mcbsp_sidetone", -+ .sysc = &omap3xxx_mcbsp_sidetone_sysc, -+}; -+ -+/* mcbsp2_sidetone */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp2_sidetone_irqs[] = { -+ { .name = "irq", .irq = 4 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp2_sidetone_addrs[] = { -+ { -+ .name = "sidetone", -+ .pa_start = 0x49028000, -+ .pa_end = 0x490280ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp2_sidetone */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp2_sidetone = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_mcbsp2_sidetone_hwmod, -+ .clk = "mcbsp2_ick", -+ .addr = omap3xxx_mcbsp2_sidetone_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* mcbsp2_sidetone slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp2_sidetone_slaves[] = { -+ &omap3xxx_l4_per__mcbsp2_sidetone, -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = { -+ .name = "mcbsp2_sidetone", -+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp2_sidetone_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_irqs), -+ .main_clk = "mcbsp2_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP2_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP2_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp2_sidetone_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcbsp3_sidetone */ -+static struct omap_hwmod_irq_info omap3xxx_mcbsp3_sidetone_irqs[] = { -+ { .name = "irq", .irq = 5 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mcbsp3_sidetone_addrs[] = { -+ { -+ .name = "sidetone", -+ .pa_start = 0x4902A000, -+ .pa_end = 0x4902A0ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp3_sidetone */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_per__mcbsp3_sidetone = { -+ .master = &omap3xxx_l4_per_hwmod, -+ .slave = &omap3xxx_mcbsp3_sidetone_hwmod, -+ .clk = "mcbsp3_ick", -+ .addr = omap3xxx_mcbsp3_sidetone_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* mcbsp3_sidetone slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mcbsp3_sidetone_slaves[] = { -+ &omap3xxx_l4_per__mcbsp3_sidetone, -+}; -+ -+static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = { -+ .name = "mcbsp3_sidetone", -+ .class = &omap3xxx_mcbsp_sidetone_hwmod_class, -+ .mpu_irqs = omap3xxx_mcbsp3_sidetone_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_irqs), -+ .main_clk = "mcbsp3_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCBSP3_SHIFT, -+ .module_offs = OMAP3430_PER_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCBSP3_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mcbsp3_sidetone_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), - }; - -+ - /* SR common */ - static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = { - .clkact_shift = 20, -@@ -1356,18 +2997,617 @@ - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1), - }; - -+/* -+ * 'mailbox' class -+ * mailbox module allowing communication between the on-chip processors -+ * using a queued mailbox-interrupt mechanism. -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap3xxx_mailbox_sysc = { -+ .rev_offs = 0x000, -+ .sysc_offs = 0x010, -+ .syss_offs = 0x014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap3xxx_mailbox_hwmod_class = { -+ .name = "mailbox", -+ .sysc = &omap3xxx_mailbox_sysc, -+}; -+ -+static struct omap_hwmod omap3xxx_mailbox_hwmod; -+static struct omap_hwmod_irq_info omap3xxx_mailbox_irqs[] = { -+ { .irq = 26 }, -+}; -+ -+static struct omap_hwmod_addr_space omap3xxx_mailbox_addrs[] = { -+ { -+ .pa_start = 0x48094000, -+ .pa_end = 0x480941ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+/* l4_core -> mailbox */ -+static struct omap_hwmod_ocp_if omap3xxx_l4_core__mailbox = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap3xxx_mailbox_hwmod, -+ .addr = omap3xxx_mailbox_addrs, -+ .addr_cnt = ARRAY_SIZE(omap3xxx_mailbox_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mailbox slave ports */ -+static struct omap_hwmod_ocp_if *omap3xxx_mailbox_slaves[] = { -+ &omap3xxx_l4_core__mailbox, -+}; -+ -+static struct omap_hwmod omap3xxx_mailbox_hwmod = { -+ .name = "mailbox", -+ .class = &omap3xxx_mailbox_hwmod_class, -+ .mpu_irqs = omap3xxx_mailbox_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_mailbox_irqs), -+ .main_clk = "mailboxes_ick", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MAILBOXES_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MAILBOXES_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mailbox_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mailbox_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* l4 core -> mcspi1 interface */ -+static struct omap_hwmod_addr_space omap34xx_mcspi1_addr_space[] = { -+ { -+ .pa_start = 0x48098000, -+ .pa_end = 0x480980ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi1 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_mcspi1, -+ .clk = "mcspi1_ick", -+ .addr = omap34xx_mcspi1_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi1_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi2 interface */ -+static struct omap_hwmod_addr_space omap34xx_mcspi2_addr_space[] = { -+ { -+ .pa_start = 0x4809a000, -+ .pa_end = 0x4809a0ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi2 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_mcspi2, -+ .clk = "mcspi2_ick", -+ .addr = omap34xx_mcspi2_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi2_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi3 interface */ -+static struct omap_hwmod_addr_space omap34xx_mcspi3_addr_space[] = { -+ { -+ .pa_start = 0x480b8000, -+ .pa_end = 0x480b80ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi3 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_mcspi3, -+ .clk = "mcspi3_ick", -+ .addr = omap34xx_mcspi3_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi3_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* l4 core -> mcspi4 interface */ -+static struct omap_hwmod_addr_space omap34xx_mcspi4_addr_space[] = { -+ { -+ .pa_start = 0x480ba000, -+ .pa_end = 0x480ba0ff, -+ .flags = ADDR_TYPE_RT, -+ }, -+}; -+ -+static struct omap_hwmod_ocp_if omap34xx_l4_core__mcspi4 = { -+ .master = &omap3xxx_l4_core_hwmod, -+ .slave = &omap34xx_mcspi4, -+ .clk = "mcspi4_ick", -+ .addr = omap34xx_mcspi4_addr_space, -+ .addr_cnt = ARRAY_SIZE(omap34xx_mcspi4_addr_space), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* -+ * 'mcspi' class -+ * multichannel serial port interface (mcspi) / master/slave synchronous serial -+ * bus -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap34xx_mcspi_class = { -+ .name = "mcspi", -+ .sysc = &omap34xx_mcspi_sysc, -+ .rev = OMAP3_MCSPI_REV, -+}; -+ -+/* mcspi1 */ -+static struct omap_hwmod_irq_info omap34xx_mcspi1_mpu_irqs[] = { -+ { .name = "irq", .irq = 65 }, -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mcspi1_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 35 }, -+ { .name = "rx0", .dma_req = 36 }, -+ { .name = "tx1", .dma_req = 37 }, -+ { .name = "rx1", .dma_req = 38 }, -+ { .name = "tx2", .dma_req = 39 }, -+ { .name = "rx2", .dma_req = 40 }, -+ { .name = "tx3", .dma_req = 41 }, -+ { .name = "rx3", .dma_req = 42 }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_mcspi1_slaves[] = { -+ &omap34xx_l4_core__mcspi1, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { -+ .num_chipselect = 4, -+}; -+ -+static struct omap_hwmod omap34xx_mcspi1 = { -+ .name = "mcspi1", -+ .mpu_irqs = omap34xx_mcspi1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_mpu_irqs), -+ .sdma_reqs = omap34xx_mcspi1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi1_sdma_reqs), -+ .main_clk = "mcspi1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCSPI1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCSPI1_SHIFT, -+ }, -+ }, -+ .slaves = omap34xx_mcspi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi1_slaves), -+ .class = &omap34xx_mcspi_class, -+ .dev_attr = &omap_mcspi1_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcspi2 */ -+static struct omap_hwmod_irq_info omap34xx_mcspi2_mpu_irqs[] = { -+ { .name = "irq", .irq = 66 }, -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mcspi2_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 43 }, -+ { .name = "rx0", .dma_req = 44 }, -+ { .name = "tx1", .dma_req = 45 }, -+ { .name = "rx1", .dma_req = 46 }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_mcspi2_slaves[] = { -+ &omap34xx_l4_core__mcspi2, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap34xx_mcspi2 = { -+ .name = "mcspi2", -+ .mpu_irqs = omap34xx_mcspi2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_mpu_irqs), -+ .sdma_reqs = omap34xx_mcspi2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi2_sdma_reqs), -+ .main_clk = "mcspi2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCSPI2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCSPI2_SHIFT, -+ }, -+ }, -+ .slaves = omap34xx_mcspi2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi2_slaves), -+ .class = &omap34xx_mcspi_class, -+ .dev_attr = &omap_mcspi2_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* mcspi3 */ -+static struct omap_hwmod_irq_info omap34xx_mcspi3_mpu_irqs[] = { -+ { .name = "irq", .irq = 91 }, /* 91 */ -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mcspi3_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 15 }, -+ { .name = "rx0", .dma_req = 16 }, -+ { .name = "tx1", .dma_req = 23 }, -+ { .name = "rx1", .dma_req = 24 }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_mcspi3_slaves[] = { -+ &omap34xx_l4_core__mcspi3, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap34xx_mcspi3 = { -+ .name = "mcspi3", -+ .mpu_irqs = omap34xx_mcspi3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_mpu_irqs), -+ .sdma_reqs = omap34xx_mcspi3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi3_sdma_reqs), -+ .main_clk = "mcspi3_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCSPI3_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCSPI3_SHIFT, -+ }, -+ }, -+ .slaves = omap34xx_mcspi3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi3_slaves), -+ .class = &omap34xx_mcspi_class, -+ .dev_attr = &omap_mcspi3_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* SPI4 */ -+static struct omap_hwmod_irq_info omap34xx_mcspi4_mpu_irqs[] = { -+ { .name = "irq", .irq = INT_34XX_SPI4_IRQ }, /* 48 */ -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mcspi4_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 70 }, /* DMA_SPI4_TX0 */ -+ { .name = "rx0", .dma_req = 71 }, /* DMA_SPI4_RX0 */ -+}; -+ -+static struct omap_hwmod_ocp_if *omap34xx_mcspi4_slaves[] = { -+ &omap34xx_l4_core__mcspi4, -+}; -+ -+static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = { -+ .num_chipselect = 1, -+}; -+ -+static struct omap_hwmod omap34xx_mcspi4 = { -+ .name = "mcspi4", -+ .mpu_irqs = omap34xx_mcspi4_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_mpu_irqs), -+ .sdma_reqs = omap34xx_mcspi4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mcspi4_sdma_reqs), -+ .main_clk = "mcspi4_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MCSPI4_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MCSPI4_SHIFT, -+ }, -+ }, -+ .slaves = omap34xx_mcspi4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap34xx_mcspi4_slaves), -+ .class = &omap34xx_mcspi_class, -+ .dev_attr = &omap_mcspi4_dev_attr, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* -+ * usbhsotg -+ */ -+static struct omap_hwmod_class_sysconfig omap3xxx_usbhsotg_sysc = { -+ .rev_offs = 0x0400, -+ .sysc_offs = 0x0404, -+ .syss_offs = 0x0408, -+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE| -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class usbotg_class = { -+ .name = "usbotg", -+ .sysc = &omap3xxx_usbhsotg_sysc, -+}; -+/* usb_otg_hs */ -+static struct omap_hwmod_irq_info omap3xxx_usbhsotg_mpu_irqs[] = { -+ -+ { .name = "mc", .irq = 92 }, -+ { .name = "dma", .irq = 93 }, -+}; -+ -+static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { -+ .name = "usb_otg_hs", -+ .mpu_irqs = omap3xxx_usbhsotg_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_mpu_irqs), -+ .main_clk = "hsotgusb_ick", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_HSOTGUSB_SHIFT, -+ .module_offs = CORE_MOD, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT, -+ .idlest_stdby_bit = OMAP3430ES2_ST_HSOTGUSB_STDBY_SHIFT -+ }, -+ }, -+ .masters = omap3xxx_usbhsotg_masters, -+ .masters_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_masters), -+ .slaves = omap3xxx_usbhsotg_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_usbhsotg_slaves), -+ .class = &usbotg_class, -+ -+ /* -+ * Erratum ID: i479 idle_req / idle_ack mechanism potentially -+ * broken when autoidle is enabled -+ * workaround is to disable the autoidle bit at module level. -+ */ -+ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE -+ | HWMOD_SWSUP_MSTANDBY, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) -+}; -+ -+/* usb_otg_hs */ -+static struct omap_hwmod_irq_info am35xx_usbhsotg_mpu_irqs[] = { -+ -+ { .name = "mc", .irq = 71 }, -+}; -+ -+static struct omap_hwmod_class am35xx_usbotg_class = { -+ .name = "am35xx_usbotg", -+ .sysc = NULL, -+}; -+ -+static struct omap_hwmod am35xx_usbhsotg_hwmod = { -+ .name = "am35x_otg_hs", -+ .mpu_irqs = am35xx_usbhsotg_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(am35xx_usbhsotg_mpu_irqs), -+ .main_clk = NULL, -+ .prcm = { -+ .omap2 = { -+ }, -+ }, -+ .masters = am35xx_usbhsotg_masters, -+ .masters_cnt = ARRAY_SIZE(am35xx_usbhsotg_masters), -+ .slaves = am35xx_usbhsotg_slaves, -+ .slaves_cnt = ARRAY_SIZE(am35xx_usbhsotg_slaves), -+ .class = &am35xx_usbotg_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1) -+}; -+ -+/* MMC/SD/SDIO common */ -+ -+static struct omap_hwmod_class_sysconfig omap34xx_mmc_sysc = { -+ .rev_offs = 0x1fc, -+ .sysc_offs = 0x10, -+ .syss_offs = 0x14, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | -+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap34xx_mmc_class = { -+ .name = "mmc", -+ .sysc = &omap34xx_mmc_sysc, -+}; -+ -+/* MMC/SD/SDIO1 */ -+ -+static struct omap_hwmod_irq_info omap34xx_mmc1_mpu_irqs[] = { -+ { .irq = 83, }, -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mmc1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 61, }, -+ { .name = "rx", .dma_req = 62, }, -+}; -+ -+static struct omap_hwmod_opt_clk omap34xx_mmc1_opt_clks[] = { -+ { .role = "dbck", .clk = "omap_32k_fck", }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_mmc1_slaves[] = { -+ &omap3xxx_l4_core__mmc1, -+}; -+ -+static struct omap_mmc_dev_attr mmc1_dev_attr = { -+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -+}; -+ -+static struct omap_hwmod omap3xxx_mmc1_hwmod = { -+ .name = "mmc1", -+ .mpu_irqs = omap34xx_mmc1_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc1_mpu_irqs), -+ .sdma_reqs = omap34xx_mmc1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc1_sdma_reqs), -+ .opt_clks = omap34xx_mmc1_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc1_opt_clks), -+ .main_clk = "mmchs1_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MMC1_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MMC1_SHIFT, -+ }, -+ }, -+ .dev_attr = &mmc1_dev_attr, -+ .slaves = omap3xxx_mmc1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves), -+ .class = &omap34xx_mmc_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* MMC/SD/SDIO2 */ -+ -+static struct omap_hwmod_irq_info omap34xx_mmc2_mpu_irqs[] = { -+ { .irq = INT_24XX_MMC2_IRQ, }, -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mmc2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 47, }, -+ { .name = "rx", .dma_req = 48, }, -+}; -+ -+static struct omap_hwmod_opt_clk omap34xx_mmc2_opt_clks[] = { -+ { .role = "dbck", .clk = "omap_32k_fck", }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_mmc2_slaves[] = { -+ &omap3xxx_l4_core__mmc2, -+}; -+ -+static struct omap_hwmod omap3xxx_mmc2_hwmod = { -+ .name = "mmc2", -+ .mpu_irqs = omap34xx_mmc2_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc2_mpu_irqs), -+ .sdma_reqs = omap34xx_mmc2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc2_sdma_reqs), -+ .opt_clks = omap34xx_mmc2_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc2_opt_clks), -+ .main_clk = "mmchs2_fck", -+ .prcm = { -+ .omap2 = { -+ .module_offs = CORE_MOD, -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MMC2_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MMC2_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mmc2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves), -+ .class = &omap34xx_mmc_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ -+/* MMC/SD/SDIO3 */ -+ -+static struct omap_hwmod_irq_info omap34xx_mmc3_mpu_irqs[] = { -+ { .irq = 94, }, -+}; -+ -+static struct omap_hwmod_dma_info omap34xx_mmc3_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 77, }, -+ { .name = "rx", .dma_req = 78, }, -+}; -+ -+static struct omap_hwmod_opt_clk omap34xx_mmc3_opt_clks[] = { -+ { .role = "dbck", .clk = "omap_32k_fck", }, -+}; -+ -+static struct omap_hwmod_ocp_if *omap3xxx_mmc3_slaves[] = { -+ &omap3xxx_l4_core__mmc3, -+}; -+ -+static struct omap_hwmod omap3xxx_mmc3_hwmod = { -+ .name = "mmc3", -+ .mpu_irqs = omap34xx_mmc3_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap34xx_mmc3_mpu_irqs), -+ .sdma_reqs = omap34xx_mmc3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap34xx_mmc3_sdma_reqs), -+ .opt_clks = omap34xx_mmc3_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(omap34xx_mmc3_opt_clks), -+ .main_clk = "mmchs3_fck", -+ .prcm = { -+ .omap2 = { -+ .prcm_reg_id = 1, -+ .module_bit = OMAP3430_EN_MMC3_SHIFT, -+ .idlest_reg_id = 1, -+ .idlest_idle_bit = OMAP3430_ST_MMC3_SHIFT, -+ }, -+ }, -+ .slaves = omap3xxx_mmc3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap3xxx_mmc3_slaves), -+ .class = &omap34xx_mmc_class, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), -+}; -+ - static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { - &omap3xxx_l3_main_hwmod, - &omap3xxx_l4_core_hwmod, - &omap3xxx_l4_per_hwmod, - &omap3xxx_l4_wkup_hwmod, -+ &omap3xxx_mmc1_hwmod, -+ &omap3xxx_mmc2_hwmod, -+ &omap3xxx_mmc3_hwmod, - &omap3xxx_mpu_hwmod, - &omap3xxx_iva_hwmod, -+ -+ &omap3xxx_timer1_hwmod, -+ &omap3xxx_timer2_hwmod, -+ &omap3xxx_timer3_hwmod, -+ &omap3xxx_timer4_hwmod, -+ &omap3xxx_timer5_hwmod, -+ &omap3xxx_timer6_hwmod, -+ &omap3xxx_timer7_hwmod, -+ &omap3xxx_timer8_hwmod, -+ &omap3xxx_timer9_hwmod, -+ &omap3xxx_timer10_hwmod, -+ &omap3xxx_timer11_hwmod, -+ &omap3xxx_timer12_hwmod, -+ - &omap3xxx_wd_timer2_hwmod, - &omap3xxx_uart1_hwmod, - &omap3xxx_uart2_hwmod, - &omap3xxx_uart3_hwmod, - &omap3xxx_uart4_hwmod, -+ /* dss class */ -+ &omap3430es1_dss_core_hwmod, -+ &omap3xxx_dss_core_hwmod, -+ &omap3xxx_dss_dispc_hwmod, -+ &omap3xxx_dss_dsi1_hwmod, -+ &omap3xxx_dss_rfbi_hwmod, -+ &omap3xxx_dss_venc_hwmod, -+ -+ /* i2c class */ - &omap3xxx_i2c1_hwmod, - &omap3xxx_i2c2_hwmod, - &omap3xxx_i2c3_hwmod, -@@ -1387,10 +3627,35 @@ - - /* dma_system class*/ - &omap3xxx_dma_system_hwmod, -+ -+ /* mcbsp class */ -+ &omap3xxx_mcbsp1_hwmod, -+ &omap3xxx_mcbsp2_hwmod, -+ &omap3xxx_mcbsp3_hwmod, -+ &omap3xxx_mcbsp4_hwmod, -+ &omap3xxx_mcbsp5_hwmod, -+ &omap3xxx_mcbsp2_sidetone_hwmod, -+ &omap3xxx_mcbsp3_sidetone_hwmod, -+ -+ /* mailbox class */ -+ &omap3xxx_mailbox_hwmod, -+ -+ /* mcspi class */ -+ &omap34xx_mcspi1, -+ &omap34xx_mcspi2, -+ &omap34xx_mcspi3, -+ &omap34xx_mcspi4, -+ -+ /* usbotg class */ -+ &omap3xxx_usbhsotg_hwmod, -+ -+ /* usbotg for am35x */ -+ &am35xx_usbhsotg_hwmod, -+ - NULL, - }; - - int __init omap3xxx_hwmod_init(void) - { -- return omap_hwmod_init(omap3xxx_hwmods); -+ return omap_hwmod_register(omap3xxx_hwmods); - } -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_44xx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_44xx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 2011-03-09 13:19:09.830507217 +0100 -@@ -1,7 +1,7 @@ - /* - * Hardware modules present on the OMAP44xx chips - * -- * Copyright (C) 2009-2010 Texas Instruments, Inc. -+ * Copyright (C) 2009-2011 Texas Instruments, Inc. - * Copyright (C) 2009-2010 Nokia Corporation - * - * Paul Walmsley -@@ -24,6 +24,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include "omap_hwmod_common_data.h" - -@@ -40,10 +43,15 @@ - #define OMAP44XX_DMA_REQ_START 1 - - /* Backward references (IPs with Bus Master capability) */ -+static struct omap_hwmod omap44xx_aess_hwmod; - static struct omap_hwmod omap44xx_dma_system_hwmod; - static struct omap_hwmod omap44xx_dmm_hwmod; - static struct omap_hwmod omap44xx_dsp_hwmod; -+static struct omap_hwmod omap44xx_dss_hwmod; - static struct omap_hwmod omap44xx_emif_fw_hwmod; -+static struct omap_hwmod omap44xx_hsi_hwmod; -+static struct omap_hwmod omap44xx_ipu_hwmod; -+static struct omap_hwmod omap44xx_iss_hwmod; - static struct omap_hwmod omap44xx_iva_hwmod; - static struct omap_hwmod omap44xx_l3_instr_hwmod; - static struct omap_hwmod omap44xx_l3_main_1_hwmod; -@@ -53,8 +61,11 @@ - static struct omap_hwmod omap44xx_l4_cfg_hwmod; - static struct omap_hwmod omap44xx_l4_per_hwmod; - static struct omap_hwmod omap44xx_l4_wkup_hwmod; -+static struct omap_hwmod omap44xx_mmc1_hwmod; -+static struct omap_hwmod omap44xx_mmc2_hwmod; - static struct omap_hwmod omap44xx_mpu_hwmod; - static struct omap_hwmod omap44xx_mpu_private_hwmod; -+static struct omap_hwmod omap44xx_usb_otg_hs_hwmod; - - /* - * Interconnects omap_hwmod structures -@@ -213,6 +224,14 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* dss -> l3_main_1 */ -+static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = { -+ .master = &omap44xx_dss_hwmod, -+ .slave = &omap44xx_l3_main_1_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* l3_main_2 -> l3_main_1 */ - static struct omap_hwmod_ocp_if omap44xx_l3_main_2__l3_main_1 = { - .master = &omap44xx_l3_main_2_hwmod, -@@ -229,6 +248,22 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* mmc1 -> l3_main_1 */ -+static struct omap_hwmod_ocp_if omap44xx_mmc1__l3_main_1 = { -+ .master = &omap44xx_mmc1_hwmod, -+ .slave = &omap44xx_l3_main_1_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc2 -> l3_main_1 */ -+static struct omap_hwmod_ocp_if omap44xx_mmc2__l3_main_1 = { -+ .master = &omap44xx_mmc2_hwmod, -+ .slave = &omap44xx_l3_main_1_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* mpu -> l3_main_1 */ - static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { - .master = &omap44xx_mpu_hwmod, -@@ -240,8 +275,11 @@ - /* l3_main_1 slave ports */ - static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = { - &omap44xx_dsp__l3_main_1, -+ &omap44xx_dss__l3_main_1, - &omap44xx_l3_main_2__l3_main_1, - &omap44xx_l4_cfg__l3_main_1, -+ &omap44xx_mmc1__l3_main_1, -+ &omap44xx_mmc2__l3_main_1, - &omap44xx_mpu__l3_main_1, - }; - -@@ -262,6 +300,30 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* hsi -> l3_main_2 */ -+static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = { -+ .master = &omap44xx_hsi_hwmod, -+ .slave = &omap44xx_l3_main_2_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* ipu -> l3_main_2 */ -+static struct omap_hwmod_ocp_if omap44xx_ipu__l3_main_2 = { -+ .master = &omap44xx_ipu_hwmod, -+ .slave = &omap44xx_l3_main_2_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* iss -> l3_main_2 */ -+static struct omap_hwmod_ocp_if omap44xx_iss__l3_main_2 = { -+ .master = &omap44xx_iss_hwmod, -+ .slave = &omap44xx_l3_main_2_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* iva -> l3_main_2 */ - static struct omap_hwmod_ocp_if omap44xx_iva__l3_main_2 = { - .master = &omap44xx_iva_hwmod, -@@ -286,12 +348,24 @@ - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - -+/* usb_otg_hs -> l3_main_2 */ -+static struct omap_hwmod_ocp_if omap44xx_usb_otg_hs__l3_main_2 = { -+ .master = &omap44xx_usb_otg_hs_hwmod, -+ .slave = &omap44xx_l3_main_2_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* l3_main_2 slave ports */ - static struct omap_hwmod_ocp_if *omap44xx_l3_main_2_slaves[] = { - &omap44xx_dma_system__l3_main_2, -+ &omap44xx_hsi__l3_main_2, -+ &omap44xx_ipu__l3_main_2, -+ &omap44xx_iss__l3_main_2, - &omap44xx_iva__l3_main_2, - &omap44xx_l3_main_1__l3_main_2, - &omap44xx_l4_cfg__l3_main_2, -+ &omap44xx_usb_otg_hs__l3_main_2, - }; - - static struct omap_hwmod omap44xx_l3_main_2_hwmod = { -@@ -351,6 +425,14 @@ - }; - - /* l4_abe interface data */ -+/* aess -> l4_abe */ -+static struct omap_hwmod_ocp_if omap44xx_aess__l4_abe = { -+ .master = &omap44xx_aess_hwmod, -+ .slave = &omap44xx_l4_abe_hwmod, -+ .clk = "ocp_abe_iclk", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ - /* dsp -> l4_abe */ - static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = { - .master = &omap44xx_dsp_hwmod, -@@ -377,6 +459,7 @@ - - /* l4_abe slave ports */ - static struct omap_hwmod_ocp_if *omap44xx_l4_abe_slaves[] = { -+ &omap44xx_aess__l4_abe, - &omap44xx_dsp__l4_abe, - &omap44xx_l3_main_1__l4_abe, - &omap44xx_mpu__l4_abe, -@@ -494,26 +577,15 @@ - * - They still need to be validated with the driver - * properly adapted to omap_hwmod / omap_device - * -- * aess -- * bandgap - * c2c - * c2c_target_fw - * cm_core - * cm_core_aon -- * counter_32k - * ctrl_module_core - * ctrl_module_pad_core - * ctrl_module_pad_wkup - * ctrl_module_wkup - * debugss -- * dmic -- * dss -- * dss_dispc -- * dss_dsi1 -- * dss_dsi2 -- * dss_hdmi -- * dss_rfbi -- * dss_venc - * efuse_ctrl_cust - * efuse_ctrl_std - * elm -@@ -524,58 +596,211 @@ - * gpu - * hdq1w - * hsi -- * ipu -- * iss -- * kbd -- * mailbox -- * mcasp -- * mcbsp1 -- * mcbsp2 -- * mcbsp3 -- * mcbsp4 -- * mcpdm -- * mcspi1 -- * mcspi2 -- * mcspi3 -- * mcspi4 -- * mmc1 -- * mmc2 -- * mmc3 -- * mmc4 -- * mmc5 -- * mpu_c0 -- * mpu_c1 - * ocmc_ram - * ocp2scp_usb_phy - * ocp_wp_noc -- * prcm - * prcm_mpu - * prm - * scrm - * sl2if - * slimbus1 - * slimbus2 -- * spinlock -- * timer1 -- * timer10 -- * timer11 -- * timer2 -- * timer3 -- * timer4 -- * timer5 -- * timer6 -- * timer7 -- * timer8 -- * timer9 - * usb_host_fs - * usb_host_hs -- * usb_otg_hs - * usb_phy_cm - * usb_tll_hs - * usim - */ - - /* -+ * 'aess' class -+ * audio engine sub system -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_aess_hwmod_class = { -+ .name = "aess", -+ .sysc = &omap44xx_aess_sysc, -+}; -+ -+/* aess */ -+static struct omap_hwmod_irq_info omap44xx_aess_irqs[] = { -+ { .irq = 99 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_aess_sdma_reqs[] = { -+ { .name = "fifo0", .dma_req = 100 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo1", .dma_req = 101 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo2", .dma_req = 102 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo3", .dma_req = 103 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo4", .dma_req = 104 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo5", .dma_req = 105 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo6", .dma_req = 106 + OMAP44XX_DMA_REQ_START }, -+ { .name = "fifo7", .dma_req = 107 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+/* aess master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_aess_masters[] = { -+ &omap44xx_aess__l4_abe, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = { -+ { -+ .pa_start = 0x401f1000, -+ .pa_end = 0x401f13ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> aess */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_aess_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_aess_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_aess_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = { -+ { -+ .pa_start = 0x490f1000, -+ .pa_end = 0x490f13ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> aess (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_aess_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_aess_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_aess_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* aess slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_aess_slaves[] = { -+ &omap44xx_l4_abe__aess, -+ &omap44xx_l4_abe__aess_dma, -+}; -+ -+static struct omap_hwmod omap44xx_aess_hwmod = { -+ .name = "aess", -+ .class = &omap44xx_aess_hwmod_class, -+ .mpu_irqs = omap44xx_aess_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_aess_irqs), -+ .sdma_reqs = omap44xx_aess_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_aess_sdma_reqs), -+ .main_clk = "aess_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_AESS_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_aess_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_aess_slaves), -+ .masters = omap44xx_aess_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_aess_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'bandgap' class -+ * bangap reference for ldo regulators -+ */ -+ -+static struct omap_hwmod_class omap44xx_bandgap_hwmod_class = { -+ .name = "bandgap", -+}; -+ -+/* bandgap */ -+static struct omap_hwmod_opt_clk bandgap_opt_clks[] = { -+ { .role = "fclk", .clk = "bandgap_fclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_bandgap_hwmod = { -+ .name = "bandgap", -+ .class = &omap44xx_bandgap_hwmod_class, -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_WKUP_BANDGAP_CLKCTRL, -+ }, -+ }, -+ .opt_clks = bandgap_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(bandgap_opt_clks), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'counter' class -+ * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_counter_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0004, -+ .sysc_flags = SYSC_HAS_SIDLEMODE, -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_counter_hwmod_class = { -+ .name = "counter", -+ .sysc = &omap44xx_counter_sysc, -+}; -+ -+/* counter_32k */ -+static struct omap_hwmod omap44xx_counter_32k_hwmod; -+static struct omap_hwmod_addr_space omap44xx_counter_32k_addrs[] = { -+ { -+ .pa_start = 0x4a304000, -+ .pa_end = 0x4a30401f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_wkup -> counter_32k */ -+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = { -+ .master = &omap44xx_l4_wkup_hwmod, -+ .slave = &omap44xx_counter_32k_hwmod, -+ .clk = "l4_wkup_clk_mux_ck", -+ .addr = omap44xx_counter_32k_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_counter_32k_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* counter_32k slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_counter_32k_slaves[] = { -+ &omap44xx_l4_wkup__counter_32k, -+}; -+ -+static struct omap_hwmod omap44xx_counter_32k_hwmod = { -+ .name = "counter_32k", -+ .class = &omap44xx_counter_hwmod_class, -+ .flags = HWMOD_SWSUP_SIDLE, -+ .main_clk = "sys_32k_ck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_WKUP_SYNCTIMER_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_counter_32k_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_counter_32k_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* - * 'dma' class - * dma controller for data exchange between memory to memory (i.e. internal or - * external memory) and gp peripherals to memory or memory to gp peripherals -@@ -662,6 +887,96 @@ - }; - - /* -+ * 'dmic' class -+ * digital microphone controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_dmic_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_dmic_hwmod_class = { -+ .name = "dmic", -+ .sysc = &omap44xx_dmic_sysc, -+}; -+ -+/* dmic */ -+static struct omap_hwmod omap44xx_dmic_hwmod; -+static struct omap_hwmod_irq_info omap44xx_dmic_irqs[] = { -+ { .irq = 114 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_dmic_sdma_reqs[] = { -+ { .dma_req = 66 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dmic_addrs[] = { -+ { -+ .pa_start = 0x4012e000, -+ .pa_end = 0x4012e07f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> dmic */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_dmic_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_dmic_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dmic_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dmic_dma_addrs[] = { -+ { -+ .pa_start = 0x4902e000, -+ .pa_end = 0x4902e07f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> dmic (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_dmic_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_dmic_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dmic_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* dmic slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dmic_slaves[] = { -+ &omap44xx_l4_abe__dmic, -+ &omap44xx_l4_abe__dmic_dma, -+}; -+ -+static struct omap_hwmod omap44xx_dmic_hwmod = { -+ .name = "dmic", -+ .class = &omap44xx_dmic_hwmod_class, -+ .mpu_irqs = omap44xx_dmic_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dmic_irqs), -+ .sdma_reqs = omap44xx_dmic_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dmic_sdma_reqs), -+ .main_clk = "dmic_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_DMIC_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_dmic_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dmic_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* - * 'dsp' class - * dsp sub-system - */ -@@ -747,894 +1062,3485 @@ - }; - - /* -- * 'gpio' class -- * general purpose io module -+ * 'dss' class -+ * display sub-system - */ - --static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = { -+static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = { - .rev_offs = 0x0000, -- .sysc_offs = 0x0010, -- .syss_offs = 0x0114, -- .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | -- SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -- SYSS_HAS_RESET_STATUS), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -- SIDLE_SMART_WKUP), -- .sysc_fields = &omap_hwmod_sysc_type1, --}; -- --static struct omap_hwmod_class omap44xx_gpio_hwmod_class = { -- .name = "gpio", -- .sysc = &omap44xx_gpio_sysc, -- .rev = 2, -+ .syss_offs = 0x0014, -+ .sysc_flags = SYSS_HAS_RESET_STATUS, - }; - --/* gpio dev_attr */ --static struct omap_gpio_dev_attr gpio_dev_attr = { -- .bank_width = 32, -- .dbck_flag = true, -+static struct omap_hwmod_class omap44xx_dss_hwmod_class = { -+ .name = "dss", -+ .sysc = &omap44xx_dss_sysc, - }; - --/* gpio1 */ --static struct omap_hwmod omap44xx_gpio1_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = { -- { .irq = 29 + OMAP44XX_IRQ_GIC_START }, -+/* dss */ -+/* dss master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_masters[] = { -+ &omap44xx_dss__l3_main_1, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = { - { -- .pa_start = 0x4a310000, -- .pa_end = 0x4a3101ff, -+ .pa_start = 0x58000000, -+ .pa_end = 0x5800007f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_wkup -> gpio1 */ --static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = { -- .master = &omap44xx_l4_wkup_hwmod, -- .slave = &omap44xx_gpio1_hwmod, -- .clk = "l4_wkup_clk_mux_ck", -- .addr = omap44xx_gpio1_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio1_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+/* l3_main_2 -> dss */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --/* gpio1 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = { -- &omap44xx_l4_wkup__gpio1, -+static struct omap_hwmod_addr_space omap44xx_dss_addrs[] = { -+ { -+ .pa_start = 0x48040000, -+ .pa_end = 0x4804007f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio1_dbclk" }, -+/* l4_per -> dss */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_addrs), -+ .user = OCP_USER_MPU, - }; - --static struct omap_hwmod omap44xx_gpio1_hwmod = { -- .name = "gpio1", -- .class = &omap44xx_gpio_hwmod_class, -- .mpu_irqs = omap44xx_gpio1_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs), -- .main_clk = "gpio1_ick", -+/* dss slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = { -+ &omap44xx_l3_main_2__dss, -+ &omap44xx_l4_per__dss, -+}; -+ -+static struct omap_hwmod_opt_clk dss_opt_clks[] = { -+ { .role = "sys_clk", .clk = "dss_sys_clk" }, -+ { .role = "tv_clk", .clk = "dss_tv_clk" }, -+ { .role = "dss_clk", .clk = "dss_dss_clk" }, -+ { .role = "video_clk", .clk = "dss_48mhz_clk" }, -+}; -+ -+static struct omap_hwmod omap44xx_dss_hwmod = { -+ .name = "dss_core", -+ .class = &omap44xx_dss_hwmod_class, -+ .main_clk = "dss_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, - }, - }, -- .opt_clks = gpio1_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves), -+ .opt_clks = dss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks), -+ .slaves = omap44xx_dss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_slaves), -+ .masters = omap44xx_dss_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_dss_masters), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* gpio2 */ --static struct omap_hwmod omap44xx_gpio2_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = { -- { .irq = 30 + OMAP44XX_IRQ_GIC_START }, -+/* -+ * 'dispc' class -+ * display controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = { -- { -- .pa_start = 0x48055000, -- .pa_end = 0x480551ff, -- .flags = ADDR_TYPE_RT -- }, -+static struct omap_hwmod_class omap44xx_dispc_hwmod_class = { -+ .name = "dispc", -+ .sysc = &omap44xx_dispc_sysc, - }; - --/* l4_per -> gpio2 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = { -- .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_gpio2_hwmod, -- .clk = "l4_div_ck", -- .addr = omap44xx_gpio2_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio2_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+/* dss_dispc */ -+static struct omap_hwmod omap44xx_dss_dispc_hwmod; -+static struct omap_hwmod_irq_info omap44xx_dss_dispc_irqs[] = { -+ { .irq = 25 + OMAP44XX_IRQ_GIC_START }, - }; - --/* gpio2 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = { -- &omap44xx_l4_per__gpio2, -+static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = { -+ { .dma_req = 5 + OMAP44XX_DMA_REQ_START }, - }; - --static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio2_dbclk" }, -+static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = { -+ { -+ .pa_start = 0x58001000, -+ .pa_end = 0x58001fff, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod omap44xx_gpio2_hwmod = { -- .name = "gpio2", -- .class = &omap44xx_gpio_hwmod_class, -- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .mpu_irqs = omap44xx_gpio2_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs), -- .main_clk = "gpio2_ick", -+/* l3_main_2 -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_dispc_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_dispc_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = { -+ { -+ .pa_start = 0x48041000, -+ .pa_end = 0x48041fff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> dss_dispc */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_dispc_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_dispc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* dss_dispc slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = { -+ &omap44xx_l3_main_2__dss_dispc, -+ &omap44xx_l4_per__dss_dispc, -+}; -+ -+static struct omap_hwmod omap44xx_dss_dispc_hwmod = { -+ .name = "dss_dispc", -+ .class = &omap44xx_dispc_hwmod_class, -+ .mpu_irqs = omap44xx_dss_dispc_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs), -+ .sdma_reqs = omap44xx_dss_dispc_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_sdma_reqs), -+ .main_clk = "dss_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, - }, - }, -- .opt_clks = gpio2_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves), -+ .slaves = omap44xx_dss_dispc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* gpio3 */ --static struct omap_hwmod omap44xx_gpio3_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = { -- { .irq = 31 + OMAP44XX_IRQ_GIC_START }, -+/* -+ * 'dsi' class -+ * display serial interface controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = { -+static struct omap_hwmod_class omap44xx_dsi_hwmod_class = { -+ .name = "dsi", -+ .sysc = &omap44xx_dsi_sysc, -+}; -+ -+/* dss_dsi1 */ -+static struct omap_hwmod omap44xx_dss_dsi1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_dss_dsi1_irqs[] = { -+ { .irq = 53 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = { -+ { .dma_req = 74 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = { - { -- .pa_start = 0x48057000, -- .pa_end = 0x480571ff, -+ .pa_start = 0x58004000, -+ .pa_end = 0x580041ff, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> gpio3 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = { -- .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_gpio3_hwmod, -- .clk = "l4_div_ck", -- .addr = omap44xx_gpio3_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio3_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+/* l3_main_2 -> dss_dsi1 */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_dsi1_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_dsi1_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --/* gpio3 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = { -- &omap44xx_l4_per__gpio3, -+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_addrs[] = { -+ { -+ .pa_start = 0x48044000, -+ .pa_end = 0x480441ff, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio3_dbclk" }, -+/* l4_per -> dss_dsi1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_dsi1_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_dsi1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_addrs), -+ .user = OCP_USER_MPU, - }; - --static struct omap_hwmod omap44xx_gpio3_hwmod = { -- .name = "gpio3", -- .class = &omap44xx_gpio_hwmod_class, -- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .mpu_irqs = omap44xx_gpio3_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio3_irqs), -- .main_clk = "gpio3_ick", -+/* dss_dsi1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = { -+ &omap44xx_l3_main_2__dss_dsi1, -+ &omap44xx_l4_per__dss_dsi1, -+}; -+ -+static struct omap_hwmod omap44xx_dss_dsi1_hwmod = { -+ .name = "dss_dsi1", -+ .class = &omap44xx_dsi_hwmod_class, -+ .mpu_irqs = omap44xx_dss_dsi1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_irqs), -+ .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_sdma_reqs), -+ .main_clk = "dss_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, - }, - }, -- .opt_clks = gpio3_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves), -+ .slaves = omap44xx_dss_dsi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* gpio4 */ --static struct omap_hwmod omap44xx_gpio4_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = { -- { .irq = 32 + OMAP44XX_IRQ_GIC_START }, -+/* dss_dsi2 */ -+static struct omap_hwmod omap44xx_dss_dsi2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = { -+ { .irq = 84 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = { -+static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = { -+ { .dma_req = 83 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = { - { -- .pa_start = 0x48059000, -- .pa_end = 0x480591ff, -+ .pa_start = 0x58005000, -+ .pa_end = 0x580051ff, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> gpio4 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = { -- .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_gpio4_hwmod, -- .clk = "l4_div_ck", -- .addr = omap44xx_gpio4_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio4_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+/* l3_main_2 -> dss_dsi2 */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_dsi2_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_dsi2_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --/* gpio4 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = { -- &omap44xx_l4_per__gpio4, -+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_addrs[] = { -+ { -+ .pa_start = 0x48045000, -+ .pa_end = 0x480451ff, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio4_dbclk" }, -+/* l4_per -> dss_dsi2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_dsi2_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_dsi2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_addrs), -+ .user = OCP_USER_MPU, - }; - --static struct omap_hwmod omap44xx_gpio4_hwmod = { -- .name = "gpio4", -- .class = &omap44xx_gpio_hwmod_class, -- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .mpu_irqs = omap44xx_gpio4_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio4_irqs), -- .main_clk = "gpio4_ick", -+/* dss_dsi2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = { -+ &omap44xx_l3_main_2__dss_dsi2, -+ &omap44xx_l4_per__dss_dsi2, -+}; -+ -+static struct omap_hwmod omap44xx_dss_dsi2_hwmod = { -+ .name = "dss_dsi2", -+ .class = &omap44xx_dsi_hwmod_class, -+ .mpu_irqs = omap44xx_dss_dsi2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_irqs), -+ .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_sdma_reqs), -+ .main_clk = "dss_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, - }, - }, -- .opt_clks = gpio4_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio4_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves), -+ .slaves = omap44xx_dss_dsi2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* gpio5 */ --static struct omap_hwmod omap44xx_gpio5_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = { -- { .irq = 33 + OMAP44XX_IRQ_GIC_START }, -+/* -+ * 'hdmi' class -+ * hdmi controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_hdmi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = { -+static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = { -+ .name = "hdmi", -+ .sysc = &omap44xx_hdmi_sysc, -+}; -+ -+/* dss_hdmi */ -+static struct omap_hwmod omap44xx_dss_hdmi_hwmod; -+static struct omap_hwmod_irq_info omap44xx_dss_hdmi_irqs[] = { -+ { .irq = 101 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { -+ { .dma_req = 75 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = { - { -- .pa_start = 0x4805b000, -- .pa_end = 0x4805b1ff, -+ .pa_start = 0x58006000, -+ .pa_end = 0x58006fff, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> gpio5 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = { -+/* l3_main_2 -> dss_hdmi */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_hdmi_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_hdmi_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_addrs[] = { -+ { -+ .pa_start = 0x48046000, -+ .pa_end = 0x48046fff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> dss_hdmi */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = { - .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_gpio5_hwmod, -+ .slave = &omap44xx_dss_hdmi_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_gpio5_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio5_addrs), -- .user = OCP_USER_MPU | OCP_USER_SDMA, -+ .addr = omap44xx_dss_hdmi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_addrs), -+ .user = OCP_USER_MPU, - }; - --/* gpio5 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = { -- &omap44xx_l4_per__gpio5, -+/* dss_hdmi slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = { -+ &omap44xx_l3_main_2__dss_hdmi, -+ &omap44xx_l4_per__dss_hdmi, - }; - --static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio5_dbclk" }, -+static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { -+ .name = "dss_hdmi", -+ .class = &omap44xx_hdmi_hwmod_class, -+ .mpu_irqs = omap44xx_dss_hdmi_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_irqs), -+ .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_sdma_reqs), -+ .main_clk = "dss_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_dss_hdmi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --static struct omap_hwmod omap44xx_gpio5_hwmod = { -- .name = "gpio5", -- .class = &omap44xx_gpio_hwmod_class, -- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .mpu_irqs = omap44xx_gpio5_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio5_irqs), -- .main_clk = "gpio5_ick", -+/* -+ * 'rfbi' class -+ * remote frame buffer interface -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = { -+ .name = "rfbi", -+ .sysc = &omap44xx_rfbi_sysc, -+}; -+ -+/* dss_rfbi */ -+static struct omap_hwmod omap44xx_dss_rfbi_hwmod; -+static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = { -+ { .dma_req = 13 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = { -+ { -+ .pa_start = 0x58002000, -+ .pa_end = 0x580020ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l3_main_2 -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_rfbi_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_rfbi_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_addrs[] = { -+ { -+ .pa_start = 0x48042000, -+ .pa_end = 0x480420ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> dss_rfbi */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_rfbi_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_rfbi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* dss_rfbi slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = { -+ &omap44xx_l3_main_2__dss_rfbi, -+ &omap44xx_l4_per__dss_rfbi, -+}; -+ -+static struct omap_hwmod omap44xx_dss_rfbi_hwmod = { -+ .name = "dss_rfbi", -+ .class = &omap44xx_rfbi_hwmod_class, -+ .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_sdma_reqs), -+ .main_clk = "dss_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, - }, - }, -- .opt_clks = gpio5_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio5_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves), -+ .slaves = omap44xx_dss_rfbi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* gpio6 */ --static struct omap_hwmod omap44xx_gpio6_hwmod; --static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = { -- { .irq = 34 + OMAP44XX_IRQ_GIC_START }, -+/* -+ * 'venc' class -+ * video encoder -+ */ -+ -+static struct omap_hwmod_class omap44xx_venc_hwmod_class = { -+ .name = "venc", -+}; -+ -+/* dss_venc */ -+static struct omap_hwmod omap44xx_dss_venc_hwmod; -+static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = { -+ { -+ .pa_start = 0x58003000, -+ .pa_end = 0x580030ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l3_main_2 -> dss_venc */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_dss_venc_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_dss_venc_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_dss_venc_addrs[] = { -+ { -+ .pa_start = 0x48043000, -+ .pa_end = 0x480430ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> dss_venc */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_dss_venc_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_dss_venc_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* dss_venc slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = { -+ &omap44xx_l3_main_2__dss_venc, -+ &omap44xx_l4_per__dss_venc, -+}; -+ -+static struct omap_hwmod omap44xx_dss_venc_hwmod = { -+ .name = "dss_venc", -+ .class = &omap44xx_venc_hwmod_class, -+ .main_clk = "dss_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_dss_venc_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'gpio' class -+ * general purpose io module -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_gpio_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0114, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_gpio_hwmod_class = { -+ .name = "gpio", -+ .sysc = &omap44xx_gpio_sysc, -+ .rev = 2, -+}; -+ -+/* gpio dev_attr */ -+static struct omap_gpio_dev_attr gpio_dev_attr = { -+ .bank_width = 32, -+ .dbck_flag = true, -+}; -+ -+/* gpio1 */ -+static struct omap_hwmod omap44xx_gpio1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio1_irqs[] = { -+ { .irq = 29 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = { -+ { -+ .pa_start = 0x4a310000, -+ .pa_end = 0x4a3101ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_wkup -> gpio1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__gpio1 = { -+ .master = &omap44xx_l4_wkup_hwmod, -+ .slave = &omap44xx_gpio1_hwmod, -+ .clk = "l4_wkup_clk_mux_ck", -+ .addr = omap44xx_gpio1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio1_slaves[] = { -+ &omap44xx_l4_wkup__gpio1, -+}; -+ -+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio1_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio1_hwmod = { -+ .name = "gpio1", -+ .class = &omap44xx_gpio_hwmod_class, -+ .mpu_irqs = omap44xx_gpio1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio1_irqs), -+ .main_clk = "gpio1_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_WKUP_GPIO1_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio1_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* gpio2 */ -+static struct omap_hwmod omap44xx_gpio2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio2_irqs[] = { -+ { .irq = 30 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio2_addrs[] = { -+ { -+ .pa_start = 0x48055000, -+ .pa_end = 0x480551ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> gpio2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio2 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_gpio2_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_gpio2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio2_slaves[] = { -+ &omap44xx_l4_per__gpio2, -+}; -+ -+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio2_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio2_hwmod = { -+ .name = "gpio2", -+ .class = &omap44xx_gpio_hwmod_class, -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap44xx_gpio2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio2_irqs), -+ .main_clk = "gpio2_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO2_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio2_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* gpio3 */ -+static struct omap_hwmod omap44xx_gpio3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio3_irqs[] = { -+ { .irq = 31 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio3_addrs[] = { -+ { -+ .pa_start = 0x48057000, -+ .pa_end = 0x480571ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> gpio3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio3 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_gpio3_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_gpio3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio3_slaves[] = { -+ &omap44xx_l4_per__gpio3, -+}; -+ -+static struct omap_hwmod_opt_clk gpio3_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio3_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio3_hwmod = { -+ .name = "gpio3", -+ .class = &omap44xx_gpio_hwmod_class, -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap44xx_gpio3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio3_irqs), -+ .main_clk = "gpio3_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO3_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio3_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* gpio4 */ -+static struct omap_hwmod omap44xx_gpio4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio4_irqs[] = { -+ { .irq = 32 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio4_addrs[] = { -+ { -+ .pa_start = 0x48059000, -+ .pa_end = 0x480591ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> gpio4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio4 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_gpio4_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_gpio4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio4_slaves[] = { -+ &omap44xx_l4_per__gpio4, -+}; -+ -+static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio4_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio4_hwmod = { -+ .name = "gpio4", -+ .class = &omap44xx_gpio_hwmod_class, -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap44xx_gpio4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio4_irqs), -+ .main_clk = "gpio4_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO4_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio4_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* gpio5 */ -+static struct omap_hwmod omap44xx_gpio5_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio5_irqs[] = { -+ { .irq = 33 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio5_addrs[] = { -+ { -+ .pa_start = 0x4805b000, -+ .pa_end = 0x4805b1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> gpio5 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio5 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_gpio5_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_gpio5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio5 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio5_slaves[] = { -+ &omap44xx_l4_per__gpio5, -+}; -+ -+static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio5_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio5_hwmod = { -+ .name = "gpio5", -+ .class = &omap44xx_gpio_hwmod_class, -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap44xx_gpio5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio5_irqs), -+ .main_clk = "gpio5_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO5_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio5_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* gpio6 */ -+static struct omap_hwmod omap44xx_gpio6_hwmod; -+static struct omap_hwmod_irq_info omap44xx_gpio6_irqs[] = { -+ { .irq = 34 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = { -+ { -+ .pa_start = 0x4805d000, -+ .pa_end = 0x4805d1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> gpio6 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_gpio6_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_gpio6_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_gpio6_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* gpio6 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = { -+ &omap44xx_l4_per__gpio6, -+}; -+ -+static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -+ { .role = "dbclk", .clk = "gpio6_dbclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_gpio6_hwmod = { -+ .name = "gpio6", -+ .class = &omap44xx_gpio_hwmod_class, -+ .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -+ .mpu_irqs = omap44xx_gpio6_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio6_irqs), -+ .main_clk = "gpio6_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL, -+ }, -+ }, -+ .opt_clks = gpio6_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), -+ .dev_attr = &gpio_dev_attr, -+ .slaves = omap44xx_gpio6_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'hsi' class -+ * mipi high-speed synchronous serial interface (multichannel and full-duplex -+ * serial if) -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_hsi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE | -+ SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_hsi_hwmod_class = { -+ .name = "hsi", -+ .sysc = &omap44xx_hsi_sysc, -+}; -+ -+/* hsi */ -+static struct omap_hwmod_irq_info omap44xx_hsi_irqs[] = { -+ { .name = "mpu_p1", .irq = 67 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "mpu_p2", .irq = 68 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "mpu_dma", .irq = 71 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+/* hsi master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_hsi_masters[] = { -+ &omap44xx_hsi__l3_main_2, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_hsi_addrs[] = { -+ { -+ .pa_start = 0x4a058000, -+ .pa_end = 0x4a05bfff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> hsi */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__hsi = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_hsi_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_hsi_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_hsi_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* hsi slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_hsi_slaves[] = { -+ &omap44xx_l4_cfg__hsi, -+}; -+ -+static struct omap_hwmod omap44xx_hsi_hwmod = { -+ .name = "hsi", -+ .class = &omap44xx_hsi_hwmod_class, -+ .mpu_irqs = omap44xx_hsi_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_hsi_irqs), -+ .main_clk = "hsi_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_HSI_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_hsi_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_hsi_slaves), -+ .masters = omap44xx_hsi_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_hsi_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'i2c' class -+ * multimaster high-speed i2c controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0090, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { -+ .name = "i2c", -+ .sysc = &omap44xx_i2c_sysc, -+}; -+ -+/* i2c1 */ -+static struct omap_hwmod omap44xx_i2c1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = { -+ { .irq = 56 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = { -+ { -+ .pa_start = 0x48070000, -+ .pa_end = 0x480700ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> i2c1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_i2c1_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_i2c1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* i2c1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { -+ &omap44xx_l4_per__i2c1, -+}; -+ -+static struct omap_hwmod omap44xx_i2c1_hwmod = { -+ .name = "i2c1", -+ .class = &omap44xx_i2c_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .mpu_irqs = omap44xx_i2c1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs), -+ .sdma_reqs = omap44xx_i2c1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c1_sdma_reqs), -+ .main_clk = "i2c1_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_i2c1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* i2c2 */ -+static struct omap_hwmod omap44xx_i2c2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = { -+ { .irq = 57 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = { -+ { -+ .pa_start = 0x48072000, -+ .pa_end = 0x480720ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> i2c2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_i2c2_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_i2c2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* i2c2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { -+ &omap44xx_l4_per__i2c2, -+}; -+ -+static struct omap_hwmod omap44xx_i2c2_hwmod = { -+ .name = "i2c2", -+ .class = &omap44xx_i2c_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .mpu_irqs = omap44xx_i2c2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs), -+ .sdma_reqs = omap44xx_i2c2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c2_sdma_reqs), -+ .main_clk = "i2c2_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_i2c2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* i2c3 */ -+static struct omap_hwmod omap44xx_i2c3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = { -+ { .irq = 61 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = { -+ { -+ .pa_start = 0x48060000, -+ .pa_end = 0x480600ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> i2c3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_i2c3_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_i2c3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* i2c3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { -+ &omap44xx_l4_per__i2c3, -+}; -+ -+static struct omap_hwmod omap44xx_i2c3_hwmod = { -+ .name = "i2c3", -+ .class = &omap44xx_i2c_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .mpu_irqs = omap44xx_i2c3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs), -+ .sdma_reqs = omap44xx_i2c3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c3_sdma_reqs), -+ .main_clk = "i2c3_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_i2c3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* i2c4 */ -+static struct omap_hwmod omap44xx_i2c4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = { -+ { .irq = 62 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = { -+ { -+ .pa_start = 0x48350000, -+ .pa_end = 0x483500ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> i2c4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_i2c4_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_i2c4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_i2c4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* i2c4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = { -+ &omap44xx_l4_per__i2c4, -+}; -+ -+static struct omap_hwmod omap44xx_i2c4_hwmod = { -+ .name = "i2c4", -+ .class = &omap44xx_i2c_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .mpu_irqs = omap44xx_i2c4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs), -+ .sdma_reqs = omap44xx_i2c4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c4_sdma_reqs), -+ .main_clk = "i2c4_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_i2c4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'ipu' class -+ * imaging processor unit -+ */ -+ -+static struct omap_hwmod_class omap44xx_ipu_hwmod_class = { -+ .name = "ipu", -+}; -+ -+/* ipu */ -+static struct omap_hwmod_irq_info omap44xx_ipu_irqs[] = { -+ { .irq = 100 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_ipu_c0_resets[] = { -+ { .name = "cpu0", .rst_shift = 0 }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_ipu_c1_resets[] = { -+ { .name = "cpu1", .rst_shift = 1 }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_ipu_resets[] = { -+ { .name = "mmu_cache", .rst_shift = 2 }, -+}; -+ -+/* ipu master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_ipu_masters[] = { -+ &omap44xx_ipu__l3_main_2, -+}; -+ -+/* l3_main_2 -> ipu */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_ipu_hwmod, -+ .clk = "l3_div_ck", -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* ipu slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_ipu_slaves[] = { -+ &omap44xx_l3_main_2__ipu, -+}; -+ -+/* Pseudo hwmod for reset control purpose only */ -+static struct omap_hwmod omap44xx_ipu_c0_hwmod = { -+ .name = "ipu_c0", -+ .class = &omap44xx_ipu_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .rst_lines = omap44xx_ipu_c0_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c0_resets), -+ .prcm = { -+ .omap4 = { -+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, -+ }, -+ }, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* Pseudo hwmod for reset control purpose only */ -+static struct omap_hwmod omap44xx_ipu_c1_hwmod = { -+ .name = "ipu_c1", -+ .class = &omap44xx_ipu_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .rst_lines = omap44xx_ipu_c1_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_c1_resets), -+ .prcm = { -+ .omap4 = { -+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, -+ }, -+ }, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+static struct omap_hwmod omap44xx_ipu_hwmod = { -+ .name = "ipu", -+ .class = &omap44xx_ipu_hwmod_class, -+ .mpu_irqs = omap44xx_ipu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_ipu_irqs), -+ .rst_lines = omap44xx_ipu_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_ipu_resets), -+ .main_clk = "ipu_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_DUCATI_DUCATI_CLKCTRL, -+ .rstctrl_reg = OMAP4430_RM_DUCATI_RSTCTRL, -+ }, -+ }, -+ .slaves = omap44xx_ipu_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_ipu_slaves), -+ .masters = omap44xx_ipu_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_ipu_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'iss' class -+ * external images sensor pixel data processor -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_iss_hwmod_class = { -+ .name = "iss", -+ .sysc = &omap44xx_iss_sysc, -+}; -+ -+/* iss */ -+static struct omap_hwmod_irq_info omap44xx_iss_irqs[] = { -+ { .irq = 24 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_iss_sdma_reqs[] = { -+ { .name = "1", .dma_req = 8 + OMAP44XX_DMA_REQ_START }, -+ { .name = "2", .dma_req = 9 + OMAP44XX_DMA_REQ_START }, -+ { .name = "3", .dma_req = 11 + OMAP44XX_DMA_REQ_START }, -+ { .name = "4", .dma_req = 12 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+/* iss master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_iss_masters[] = { -+ &omap44xx_iss__l3_main_2, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_iss_addrs[] = { -+ { -+ .pa_start = 0x52000000, -+ .pa_end = 0x520000ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l3_main_2 -> iss */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_iss_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_iss_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_iss_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* iss slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_iss_slaves[] = { -+ &omap44xx_l3_main_2__iss, -+}; -+ -+static struct omap_hwmod_opt_clk iss_opt_clks[] = { -+ { .role = "ctrlclk", .clk = "iss_ctrlclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_iss_hwmod = { -+ .name = "iss", -+ .class = &omap44xx_iss_hwmod_class, -+ .mpu_irqs = omap44xx_iss_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iss_irqs), -+ .sdma_reqs = omap44xx_iss_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_iss_sdma_reqs), -+ .main_clk = "iss_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_CAM_ISS_CLKCTRL, -+ }, -+ }, -+ .opt_clks = iss_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(iss_opt_clks), -+ .slaves = omap44xx_iss_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_iss_slaves), -+ .masters = omap44xx_iss_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_iss_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'iva' class -+ * multi-standard video encoder/decoder hardware accelerator -+ */ -+ -+static struct omap_hwmod_class omap44xx_iva_hwmod_class = { -+ .name = "iva", -+}; -+ -+/* iva */ -+static struct omap_hwmod_irq_info omap44xx_iva_irqs[] = { -+ { .name = "sync_1", .irq = 103 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "sync_0", .irq = 104 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "mailbox_0", .irq = 107 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_iva_resets[] = { -+ { .name = "logic", .rst_shift = 2 }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_iva_seq0_resets[] = { -+ { .name = "seq0", .rst_shift = 0 }, -+}; -+ -+static struct omap_hwmod_rst_info omap44xx_iva_seq1_resets[] = { -+ { .name = "seq1", .rst_shift = 1 }, -+}; -+ -+/* iva master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_iva_masters[] = { -+ &omap44xx_iva__l3_main_2, -+ &omap44xx_iva__l3_instr, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = { -+ { -+ .pa_start = 0x5a000000, -+ .pa_end = 0x5a07ffff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l3_main_2 -> iva */ -+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = { -+ .master = &omap44xx_l3_main_2_hwmod, -+ .slave = &omap44xx_iva_hwmod, -+ .clk = "l3_div_ck", -+ .addr = omap44xx_iva_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_iva_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+/* iva slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = { -+ &omap44xx_dsp__iva, -+ &omap44xx_l3_main_2__iva, -+}; -+ -+/* Pseudo hwmod for reset control purpose only */ -+static struct omap_hwmod omap44xx_iva_seq0_hwmod = { -+ .name = "iva_seq0", -+ .class = &omap44xx_iva_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .rst_lines = omap44xx_iva_seq0_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets), -+ .prcm = { -+ .omap4 = { -+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -+ }, -+ }, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* Pseudo hwmod for reset control purpose only */ -+static struct omap_hwmod omap44xx_iva_seq1_hwmod = { -+ .name = "iva_seq1", -+ .class = &omap44xx_iva_hwmod_class, -+ .flags = HWMOD_INIT_NO_RESET, -+ .rst_lines = omap44xx_iva_seq1_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets), -+ .prcm = { -+ .omap4 = { -+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -+ }, -+ }, -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+static struct omap_hwmod omap44xx_iva_hwmod = { -+ .name = "iva", -+ .class = &omap44xx_iva_hwmod_class, -+ .mpu_irqs = omap44xx_iva_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iva_irqs), -+ .rst_lines = omap44xx_iva_resets, -+ .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), -+ .main_clk = "iva_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, -+ .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -+ }, -+ }, -+ .slaves = omap44xx_iva_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves), -+ .masters = omap44xx_iva_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_iva_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'kbd' class -+ * keyboard controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_kbd_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_kbd_hwmod_class = { -+ .name = "kbd", -+ .sysc = &omap44xx_kbd_sysc, -+}; -+ -+/* kbd */ -+static struct omap_hwmod omap44xx_kbd_hwmod; -+static struct omap_hwmod_irq_info omap44xx_kbd_irqs[] = { -+ { .irq = 120 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_kbd_addrs[] = { -+ { -+ .pa_start = 0x4a31c000, -+ .pa_end = 0x4a31c07f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_wkup -> kbd */ -+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = { -+ .master = &omap44xx_l4_wkup_hwmod, -+ .slave = &omap44xx_kbd_hwmod, -+ .clk = "l4_wkup_clk_mux_ck", -+ .addr = omap44xx_kbd_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_kbd_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* kbd slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_kbd_slaves[] = { -+ &omap44xx_l4_wkup__kbd, -+}; -+ -+static struct omap_hwmod omap44xx_kbd_hwmod = { -+ .name = "kbd", -+ .class = &omap44xx_kbd_hwmod_class, -+ .mpu_irqs = omap44xx_kbd_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_kbd_irqs), -+ .main_clk = "kbd_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_kbd_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_kbd_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mailbox' class -+ * mailbox module allowing communication between the on-chip processors using a -+ * queued mailbox-interrupt mechanism. -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_mailbox_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_mailbox_hwmod_class = { -+ .name = "mailbox", -+ .sysc = &omap44xx_mailbox_sysc, -+}; -+ -+/* mailbox */ -+static struct omap_hwmod omap44xx_mailbox_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mailbox_irqs[] = { -+ { .irq = 26 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mailbox_addrs[] = { -+ { -+ .pa_start = 0x4a0f4000, -+ .pa_end = 0x4a0f41ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> mailbox */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mailbox = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_mailbox_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mailbox_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mailbox_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mailbox slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mailbox_slaves[] = { -+ &omap44xx_l4_cfg__mailbox, -+}; -+ -+static struct omap_hwmod omap44xx_mailbox_hwmod = { -+ .name = "mailbox", -+ .class = &omap44xx_mailbox_hwmod_class, -+ .mpu_irqs = omap44xx_mailbox_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mailbox_irqs), -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4CFG_MAILBOX_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mailbox_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mailbox_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mcbsp' class -+ * multi channel buffered serial port controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = { -+ .sysc_offs = 0x008c, -+ .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = { -+ .name = "mcbsp", -+ .sysc = &omap44xx_mcbsp_sysc, -+ .rev = MCBSP_CONFIG_TYPE4, -+}; -+ -+/* mcbsp1 */ -+static struct omap_hwmod omap44xx_mcbsp1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = { -+ { .irq = 17 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcbsp1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 32 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 33 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x40122000, -+ .pa_end = 0x401220ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp1_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp1_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp1_dma_addrs[] = { -+ { -+ .name = "dma", -+ .pa_start = 0x49022000, -+ .pa_end = 0x490220ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp1 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp1_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp1_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp1_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp1_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* mcbsp1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcbsp1_slaves[] = { -+ &omap44xx_l4_abe__mcbsp1, -+ &omap44xx_l4_abe__mcbsp1_dma, -+}; -+ -+static struct omap_hwmod omap44xx_mcbsp1_hwmod = { -+ .name = "mcbsp1", -+ .class = &omap44xx_mcbsp_hwmod_class, -+ .mpu_irqs = omap44xx_mcbsp1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp1_irqs), -+ .sdma_reqs = omap44xx_mcbsp1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp1_sdma_reqs), -+ .main_clk = "mcbsp1_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mcbsp1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcbsp2 */ -+static struct omap_hwmod omap44xx_mcbsp2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = { -+ { .irq = 22 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcbsp2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 16 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 17 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp2_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x40124000, -+ .pa_end = 0x401240ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp2_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp2_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp2_dma_addrs[] = { -+ { -+ .name = "dma", -+ .pa_start = 0x49024000, -+ .pa_end = 0x490240ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp2 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp2_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp2_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp2_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp2_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* mcbsp2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcbsp2_slaves[] = { -+ &omap44xx_l4_abe__mcbsp2, -+ &omap44xx_l4_abe__mcbsp2_dma, -+}; -+ -+static struct omap_hwmod omap44xx_mcbsp2_hwmod = { -+ .name = "mcbsp2", -+ .class = &omap44xx_mcbsp_hwmod_class, -+ .mpu_irqs = omap44xx_mcbsp2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp2_irqs), -+ .sdma_reqs = omap44xx_mcbsp2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp2_sdma_reqs), -+ .main_clk = "mcbsp2_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mcbsp2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcbsp3 */ -+static struct omap_hwmod omap44xx_mcbsp3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = { -+ { .irq = 23 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcbsp3_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 18 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 19 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp3_addrs[] = { -+ { -+ .name = "mpu", -+ .pa_start = 0x40126000, -+ .pa_end = 0x401260ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp3_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp3_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp3_dma_addrs[] = { -+ { -+ .name = "dma", -+ .pa_start = 0x49026000, -+ .pa_end = 0x490260ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcbsp3 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcbsp3_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcbsp3_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcbsp3_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp3_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* mcbsp3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcbsp3_slaves[] = { -+ &omap44xx_l4_abe__mcbsp3, -+ &omap44xx_l4_abe__mcbsp3_dma, -+}; -+ -+static struct omap_hwmod omap44xx_mcbsp3_hwmod = { -+ .name = "mcbsp3", -+ .class = &omap44xx_mcbsp_hwmod_class, -+ .mpu_irqs = omap44xx_mcbsp3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp3_irqs), -+ .sdma_reqs = omap44xx_mcbsp3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp3_sdma_reqs), -+ .main_clk = "mcbsp3_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mcbsp3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcbsp4 */ -+static struct omap_hwmod omap44xx_mcbsp4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = { -+ { .irq = 16 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcbsp4_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 30 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 31 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcbsp4_addrs[] = { -+ { -+ .pa_start = 0x48096000, -+ .pa_end = 0x480960ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcbsp4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcbsp4 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mcbsp4_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mcbsp4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcbsp4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcbsp4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcbsp4_slaves[] = { -+ &omap44xx_l4_per__mcbsp4, -+}; -+ -+static struct omap_hwmod omap44xx_mcbsp4_hwmod = { -+ .name = "mcbsp4", -+ .class = &omap44xx_mcbsp_hwmod_class, -+ .mpu_irqs = omap44xx_mcbsp4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcbsp4_irqs), -+ .sdma_reqs = omap44xx_mcbsp4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcbsp4_sdma_reqs), -+ .main_clk = "mcbsp4_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mcbsp4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mcpdm' class -+ * multi channel pdm controller (proprietary interface with phoenix power -+ * ic) -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_mcpdm_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_mcpdm_hwmod_class = { -+ .name = "mcpdm", -+ .sysc = &omap44xx_mcpdm_sysc, -+}; -+ -+/* mcpdm */ -+static struct omap_hwmod omap44xx_mcpdm_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcpdm_irqs[] = { -+ { .irq = 112 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcpdm_sdma_reqs[] = { -+ { .name = "up_link", .dma_req = 64 + OMAP44XX_DMA_REQ_START }, -+ { .name = "dn_link", .dma_req = 65 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = { -+ { -+ .pa_start = 0x40132000, -+ .pa_end = 0x4013207f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcpdm */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcpdm_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcpdm_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcpdm_addrs), -+ .user = OCP_USER_MPU, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = { -+ { -+ .pa_start = 0x49032000, -+ .pa_end = 0x4903207f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> mcpdm (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_mcpdm_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_mcpdm_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcpdm_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* mcpdm slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcpdm_slaves[] = { -+ &omap44xx_l4_abe__mcpdm, -+ &omap44xx_l4_abe__mcpdm_dma, -+}; -+ -+static struct omap_hwmod omap44xx_mcpdm_hwmod = { -+ .name = "mcpdm", -+ .class = &omap44xx_mcpdm_hwmod_class, -+ .mpu_irqs = omap44xx_mcpdm_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcpdm_irqs), -+ .sdma_reqs = omap44xx_mcpdm_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcpdm_sdma_reqs), -+ .main_clk = "mcpdm_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_PDM_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mcpdm_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcpdm_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mcspi' class -+ * multichannel serial port interface (mcspi) / master/slave synchronous serial -+ * bus -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = { -+ .name = "mcspi", -+ .sysc = &omap44xx_mcspi_sysc, -+ .rev = OMAP4_MCSPI_REV, -+}; -+ -+/* mcspi1 */ -+static struct omap_hwmod omap44xx_mcspi1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcspi1_irqs[] = { -+ { .irq = 65 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcspi1_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 34 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx0", .dma_req = 35 + OMAP44XX_DMA_REQ_START }, -+ { .name = "tx1", .dma_req = 36 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx1", .dma_req = 37 + OMAP44XX_DMA_REQ_START }, -+ { .name = "tx2", .dma_req = 38 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx2", .dma_req = 39 + OMAP44XX_DMA_REQ_START }, -+ { .name = "tx3", .dma_req = 40 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx3", .dma_req = 41 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcspi1_addrs[] = { -+ { -+ .pa_start = 0x48098000, -+ .pa_end = 0x480981ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcspi1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi1 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mcspi1_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mcspi1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcspi1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcspi1_slaves[] = { -+ &omap44xx_l4_per__mcspi1, -+}; -+ -+/* mcspi1 dev_attr */ -+static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { -+ .num_chipselect = 4, -+}; -+ -+static struct omap_hwmod omap44xx_mcspi1_hwmod = { -+ .name = "mcspi1", -+ .class = &omap44xx_mcspi_hwmod_class, -+ .mpu_irqs = omap44xx_mcspi1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi1_irqs), -+ .sdma_reqs = omap44xx_mcspi1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi1_sdma_reqs), -+ .main_clk = "mcspi1_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI1_CLKCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi1_dev_attr, -+ .slaves = omap44xx_mcspi1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi1_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcspi2 */ -+static struct omap_hwmod omap44xx_mcspi2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcspi2_irqs[] = { -+ { .irq = 66 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcspi2_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 42 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx0", .dma_req = 43 + OMAP44XX_DMA_REQ_START }, -+ { .name = "tx1", .dma_req = 44 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx1", .dma_req = 45 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcspi2_addrs[] = { -+ { -+ .pa_start = 0x4809a000, -+ .pa_end = 0x4809a1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcspi2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi2 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mcspi2_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mcspi2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcspi2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcspi2_slaves[] = { -+ &omap44xx_l4_per__mcspi2, -+}; -+ -+/* mcspi2 dev_attr */ -+static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap44xx_mcspi2_hwmod = { -+ .name = "mcspi2", -+ .class = &omap44xx_mcspi_hwmod_class, -+ .mpu_irqs = omap44xx_mcspi2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi2_irqs), -+ .sdma_reqs = omap44xx_mcspi2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi2_sdma_reqs), -+ .main_clk = "mcspi2_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI2_CLKCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi2_dev_attr, -+ .slaves = omap44xx_mcspi2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi2_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcspi3 */ -+static struct omap_hwmod omap44xx_mcspi3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcspi3_irqs[] = { -+ { .irq = 91 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcspi3_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 14 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx0", .dma_req = 15 + OMAP44XX_DMA_REQ_START }, -+ { .name = "tx1", .dma_req = 22 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx1", .dma_req = 23 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcspi3_addrs[] = { -+ { -+ .pa_start = 0x480b8000, -+ .pa_end = 0x480b81ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcspi3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi3 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mcspi3_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mcspi3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcspi3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcspi3_slaves[] = { -+ &omap44xx_l4_per__mcspi3, -+}; -+ -+/* mcspi3 dev_attr */ -+static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { -+ .num_chipselect = 2, -+}; -+ -+static struct omap_hwmod omap44xx_mcspi3_hwmod = { -+ .name = "mcspi3", -+ .class = &omap44xx_mcspi_hwmod_class, -+ .mpu_irqs = omap44xx_mcspi3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi3_irqs), -+ .sdma_reqs = omap44xx_mcspi3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi3_sdma_reqs), -+ .main_clk = "mcspi3_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI3_CLKCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi3_dev_attr, -+ .slaves = omap44xx_mcspi3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi3_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mcspi4 */ -+static struct omap_hwmod omap44xx_mcspi4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mcspi4_irqs[] = { -+ { .irq = 48 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mcspi4_sdma_reqs[] = { -+ { .name = "tx0", .dma_req = 69 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx0", .dma_req = 70 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mcspi4_addrs[] = { -+ { -+ .pa_start = 0x480ba000, -+ .pa_end = 0x480ba1ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mcspi4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mcspi4 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mcspi4_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mcspi4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mcspi4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mcspi4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mcspi4_slaves[] = { -+ &omap44xx_l4_per__mcspi4, -+}; -+ -+/* mcspi4 dev_attr */ -+static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { -+ .num_chipselect = 1, -+}; -+ -+static struct omap_hwmod omap44xx_mcspi4_hwmod = { -+ .name = "mcspi4", -+ .class = &omap44xx_mcspi_hwmod_class, -+ .mpu_irqs = omap44xx_mcspi4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mcspi4_irqs), -+ .sdma_reqs = omap44xx_mcspi4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mcspi4_sdma_reqs), -+ .main_clk = "mcspi4_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MCSPI4_CLKCTRL, -+ }, -+ }, -+ .dev_attr = &mcspi4_dev_attr, -+ .slaves = omap44xx_mcspi4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mcspi4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mmc' class -+ * multimedia card high-speed/sd/sdio (mmc/sd/sdio) host controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_mmc_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE | -+ SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type2, -+}; -+ -+static struct omap_hwmod_class omap44xx_mmc_hwmod_class = { -+ .name = "mmc", -+ .sysc = &omap44xx_mmc_sysc, -+}; -+ -+/* mmc1 */ -+ -+static struct omap_hwmod_irq_info omap44xx_mmc1_irqs[] = { -+ { .irq = 83 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mmc1_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 60 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 61 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+/* mmc1 master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc1_masters[] = { -+ &omap44xx_mmc1__l3_main_1, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mmc1_addrs[] = { -+ { -+ .pa_start = 0x4809c000, -+ .pa_end = 0x4809c3ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mmc1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc1 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mmc1_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mmc1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc1_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc1_slaves[] = { -+ &omap44xx_l4_per__mmc1, -+}; -+ -+/* mmc1 dev_attr */ -+static struct omap_mmc_dev_attr mmc1_dev_attr = { -+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT, -+}; -+ -+static struct omap_hwmod omap44xx_mmc1_hwmod = { -+ .name = "mmc1", -+ .class = &omap44xx_mmc_hwmod_class, -+ .mpu_irqs = omap44xx_mmc1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc1_irqs), -+ .sdma_reqs = omap44xx_mmc1_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc1_sdma_reqs), -+ .main_clk = "mmc1_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_MMC1_CLKCTRL, -+ }, -+ }, -+ .dev_attr = &mmc1_dev_attr, -+ .slaves = omap44xx_mmc1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc1_slaves), -+ .masters = omap44xx_mmc1_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_mmc1_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mmc2 */ -+static struct omap_hwmod_irq_info omap44xx_mmc2_irqs[] = { -+ { .irq = 86 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mmc2_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 46 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 47 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+/* mmc2 master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc2_masters[] = { -+ &omap44xx_mmc2__l3_main_1, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mmc2_addrs[] = { -+ { -+ .pa_start = 0x480b4000, -+ .pa_end = 0x480b43ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mmc2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc2 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mmc2_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mmc2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc2_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc2_slaves[] = { -+ &omap44xx_l4_per__mmc2, -+}; -+ -+static struct omap_hwmod omap44xx_mmc2_hwmod = { -+ .name = "mmc2", -+ .class = &omap44xx_mmc_hwmod_class, -+ .mpu_irqs = omap44xx_mmc2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc2_irqs), -+ .sdma_reqs = omap44xx_mmc2_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc2_sdma_reqs), -+ .main_clk = "mmc2_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_MMC2_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mmc2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc2_slaves), -+ .masters = omap44xx_mmc2_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_mmc2_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mmc3 */ -+static struct omap_hwmod omap44xx_mmc3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mmc3_irqs[] = { -+ { .irq = 94 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mmc3_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 76 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 77 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mmc3_addrs[] = { -+ { -+ .pa_start = 0x480ad000, -+ .pa_end = 0x480ad3ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mmc3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc3 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mmc3_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mmc3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc3_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc3_slaves[] = { -+ &omap44xx_l4_per__mmc3, -+}; -+ -+static struct omap_hwmod omap44xx_mmc3_hwmod = { -+ .name = "mmc3", -+ .class = &omap44xx_mmc_hwmod_class, -+ .mpu_irqs = omap44xx_mmc3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc3_irqs), -+ .sdma_reqs = omap44xx_mmc3_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc3_sdma_reqs), -+ .main_clk = "mmc3_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD3_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mmc3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc3_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mmc4 */ -+static struct omap_hwmod omap44xx_mmc4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mmc4_irqs[] = { -+ { .irq = 96 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mmc4_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 56 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 57 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mmc4_addrs[] = { -+ { -+ .pa_start = 0x480d1000, -+ .pa_end = 0x480d13ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mmc4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc4 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mmc4_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mmc4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc4_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc4_slaves[] = { -+ &omap44xx_l4_per__mmc4, -+}; -+ -+static struct omap_hwmod omap44xx_mmc4_hwmod = { -+ .name = "mmc4", -+ .class = &omap44xx_mmc_hwmod_class, -+ .mpu_irqs = omap44xx_mmc4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc4_irqs), -+ .sdma_reqs = omap44xx_mmc4_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc4_sdma_reqs), -+ .main_clk = "mmc4_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD4_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mmc4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc4_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* mmc5 */ -+static struct omap_hwmod omap44xx_mmc5_hwmod; -+static struct omap_hwmod_irq_info omap44xx_mmc5_irqs[] = { -+ { .irq = 59 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_dma_info omap44xx_mmc5_sdma_reqs[] = { -+ { .name = "tx", .dma_req = 58 + OMAP44XX_DMA_REQ_START }, -+ { .name = "rx", .dma_req = 59 + OMAP44XX_DMA_REQ_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_mmc5_addrs[] = { -+ { -+ .pa_start = 0x480d5000, -+ .pa_end = 0x480d53ff, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_per -> mmc5 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_mmc5_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_mmc5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_mmc5_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* mmc5 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mmc5_slaves[] = { -+ &omap44xx_l4_per__mmc5, -+}; -+ -+static struct omap_hwmod omap44xx_mmc5_hwmod = { -+ .name = "mmc5", -+ .class = &omap44xx_mmc_hwmod_class, -+ .mpu_irqs = omap44xx_mmc5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mmc5_irqs), -+ .sdma_reqs = omap44xx_mmc5_sdma_reqs, -+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_mmc5_sdma_reqs), -+ .main_clk = "mmc5_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L4PER_MMCSD5_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_mmc5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_mmc5_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'mpu' class -+ * mpu sub-system -+ */ -+ -+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = { -+ .name = "mpu", -+}; -+ -+/* mpu */ -+static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = { -+ { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+/* mpu master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = { -+ &omap44xx_mpu__l3_main_1, -+ &omap44xx_mpu__l4_abe, -+ &omap44xx_mpu__dmm, -+}; -+ -+static struct omap_hwmod omap44xx_mpu_hwmod = { -+ .name = "mpu", -+ .class = &omap44xx_mpu_hwmod_class, -+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -+ .mpu_irqs = omap44xx_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs), -+ .main_clk = "dpll_mpu_m2_ck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL, -+ }, -+ }, -+ .masters = omap44xx_mpu_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'smartreflex' class -+ * smartreflex module (monitor silicon performance and outputs a measure of -+ * performance error) -+ */ -+ -+/* The IP is not compliant to type1 / type2 scheme */ -+static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = { -+ .sidle_shift = 24, -+ .enwkup_shift = 26, -+}; -+ -+static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = { -+ .sysc_offs = 0x0038, -+ .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type_smartreflex, -+}; -+ -+static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { -+ .name = "smartreflex", -+ .sysc = &omap44xx_smartreflex_sysc, -+ .rev = 2, -+}; -+ -+/* smartreflex_core */ -+static struct omap_hwmod omap44xx_smartreflex_core_hwmod; -+static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { -+ { .irq = 19 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = { -+ { -+ .pa_start = 0x4a0dd000, -+ .pa_end = 0x4a0dd03f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> smartreflex_core */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_smartreflex_core_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_smartreflex_core_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* smartreflex_core slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = { -+ &omap44xx_l4_cfg__smartreflex_core, -+}; -+ -+static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { -+ .name = "smartreflex_core", -+ .class = &omap44xx_smartreflex_hwmod_class, -+ .mpu_irqs = omap44xx_smartreflex_core_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs), -+ .main_clk = "smartreflex_core_fck", -+ .vdd_name = "core", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_smartreflex_core_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* smartreflex_iva */ -+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; -+static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { -+ { .irq = 102 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = { -+ { -+ .pa_start = 0x4a0db000, -+ .pa_end = 0x4a0db03f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> smartreflex_iva */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_smartreflex_iva_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_smartreflex_iva_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* smartreflex_iva slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = { -+ &omap44xx_l4_cfg__smartreflex_iva, -+}; -+ -+static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { -+ .name = "smartreflex_iva", -+ .class = &omap44xx_smartreflex_hwmod_class, -+ .mpu_irqs = omap44xx_smartreflex_iva_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs), -+ .main_clk = "smartreflex_iva_fck", -+ .vdd_name = "iva", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_smartreflex_iva_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* smartreflex_mpu */ -+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; -+static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { -+ { .irq = 18 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = { -+ { -+ .pa_start = 0x4a0d9000, -+ .pa_end = 0x4a0d903f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> smartreflex_mpu */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_smartreflex_mpu_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_smartreflex_mpu_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* smartreflex_mpu slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = { -+ &omap44xx_l4_cfg__smartreflex_mpu, -+}; -+ -+static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { -+ .name = "smartreflex_mpu", -+ .class = &omap44xx_smartreflex_hwmod_class, -+ .mpu_irqs = omap44xx_smartreflex_mpu_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs), -+ .main_clk = "smartreflex_mpu_fck", -+ .vdd_name = "mpu", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_smartreflex_mpu_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* -+ * 'spinlock' class -+ * spinlock provides hardware assistance for synchronizing the processes -+ * running on multiple processors -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_spinlock_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .syss_offs = 0x0014, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_spinlock_hwmod_class = { -+ .name = "spinlock", -+ .sysc = &omap44xx_spinlock_sysc, - }; - --static struct omap_hwmod_addr_space omap44xx_gpio6_addrs[] = { -+/* spinlock */ -+static struct omap_hwmod omap44xx_spinlock_hwmod; -+static struct omap_hwmod_addr_space omap44xx_spinlock_addrs[] = { - { -- .pa_start = 0x4805d000, -- .pa_end = 0x4805d1ff, -+ .pa_start = 0x4a0f6000, -+ .pa_end = 0x4a0f6fff, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> gpio6 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = { -- .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_gpio6_hwmod, -+/* l4_cfg -> spinlock */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__spinlock = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_spinlock_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_gpio6_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_gpio6_addrs), -+ .addr = omap44xx_spinlock_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_spinlock_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* gpio6 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_gpio6_slaves[] = { -- &omap44xx_l4_per__gpio6, --}; -- --static struct omap_hwmod_opt_clk gpio6_opt_clks[] = { -- { .role = "dbclk", .clk = "gpio6_dbclk" }, -+/* spinlock slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_spinlock_slaves[] = { -+ &omap44xx_l4_cfg__spinlock, - }; - --static struct omap_hwmod omap44xx_gpio6_hwmod = { -- .name = "gpio6", -- .class = &omap44xx_gpio_hwmod_class, -- .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, -- .mpu_irqs = omap44xx_gpio6_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_gpio6_irqs), -- .main_clk = "gpio6_ick", -+static struct omap_hwmod omap44xx_spinlock_hwmod = { -+ .name = "spinlock", -+ .class = &omap44xx_spinlock_hwmod_class, - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_GPIO6_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4CFG_HW_SEM_CLKCTRL, - }, - }, -- .opt_clks = gpio6_opt_clks, -- .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), -- .dev_attr = &gpio_dev_attr, -- .slaves = omap44xx_gpio6_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves), -+ .slaves = omap44xx_spinlock_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_spinlock_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - - /* -- * 'i2c' class -- * multimaster high-speed i2c controller -+ * 'timer' class -+ * general purpose timer module with accurate 1ms tick -+ * This class contains several variants: ['timer_1ms', 'timer'] - */ - --static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { -+static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = { -+ .rev_offs = 0x0000, - .sysc_offs = 0x0010, -- .syss_offs = 0x0090, -+ .syss_offs = 0x0014, - .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | -- SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | -- SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -- SIDLE_SMART_WKUP), -+ SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | -+ SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), - .sysc_fields = &omap_hwmod_sysc_type1, - }; - --static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { -- .name = "i2c", -- .sysc = &omap44xx_i2c_sysc, -+static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap44xx_timer_1ms_sysc, - }; - --/* i2c1 */ --static struct omap_hwmod omap44xx_i2c1_hwmod; --static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = { -- { .irq = 56 + OMAP44XX_IRQ_GIC_START }, -+static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = { -+ .rev_offs = 0x0000, -+ .sysc_offs = 0x0010, -+ .sysc_flags = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS | -+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP), -+ .sysc_fields = &omap_hwmod_sysc_type2, - }; - --static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = { -- { .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START }, -- { .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START }, -+static struct omap_hwmod_class omap44xx_timer_hwmod_class = { -+ .name = "timer", -+ .sysc = &omap44xx_timer_sysc, - }; - --static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = { -+/* timer1 */ -+static struct omap_hwmod omap44xx_timer1_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = { -+ { .irq = 37 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_timer1_addrs[] = { - { -- .pa_start = 0x48070000, -- .pa_end = 0x480700ff, -+ .pa_start = 0x4a318000, -+ .pa_end = 0x4a31807f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> i2c1 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = { -- .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_i2c1_hwmod, -- .clk = "l4_div_ck", -- .addr = omap44xx_i2c1_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_i2c1_addrs), -+/* l4_wkup -> timer1 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = { -+ .master = &omap44xx_l4_wkup_hwmod, -+ .slave = &omap44xx_timer1_hwmod, -+ .clk = "l4_wkup_clk_mux_ck", -+ .addr = omap44xx_timer1_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer1_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* i2c1 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { -- &omap44xx_l4_per__i2c1, -+/* timer1 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer1_slaves[] = { -+ &omap44xx_l4_wkup__timer1, - }; - --static struct omap_hwmod omap44xx_i2c1_hwmod = { -- .name = "i2c1", -- .class = &omap44xx_i2c_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .mpu_irqs = omap44xx_i2c1_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs), -- .sdma_reqs = omap44xx_i2c1_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c1_sdma_reqs), -- .main_clk = "i2c1_fck", -+static struct omap_hwmod omap44xx_timer1_hwmod = { -+ .name = "timer1", -+ .class = &omap44xx_timer_1ms_hwmod_class, -+ .mpu_irqs = omap44xx_timer1_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer1_irqs), -+ .main_clk = "timer1_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_WKUP_TIMER1_CLKCTRL, - }, - }, -- .slaves = omap44xx_i2c1_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves), -+ .slaves = omap44xx_timer1_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer1_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* i2c2 */ --static struct omap_hwmod omap44xx_i2c2_hwmod; --static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = { -- { .irq = 57 + OMAP44XX_IRQ_GIC_START }, --}; -- --static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = { -- { .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START }, -- { .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START }, -+/* timer2 */ -+static struct omap_hwmod omap44xx_timer2_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer2_irqs[] = { -+ { .irq = 38 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_timer2_addrs[] = { - { -- .pa_start = 0x48072000, -- .pa_end = 0x480720ff, -+ .pa_start = 0x48032000, -+ .pa_end = 0x4803207f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> i2c2 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = { -+/* l4_per -> timer2 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer2 = { - .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_i2c2_hwmod, -+ .slave = &omap44xx_timer2_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_i2c2_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_i2c2_addrs), -+ .addr = omap44xx_timer2_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer2_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* i2c2 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { -- &omap44xx_l4_per__i2c2, -+/* timer2 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer2_slaves[] = { -+ &omap44xx_l4_per__timer2, - }; - --static struct omap_hwmod omap44xx_i2c2_hwmod = { -- .name = "i2c2", -- .class = &omap44xx_i2c_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .mpu_irqs = omap44xx_i2c2_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs), -- .sdma_reqs = omap44xx_i2c2_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c2_sdma_reqs), -- .main_clk = "i2c2_fck", -+static struct omap_hwmod omap44xx_timer2_hwmod = { -+ .name = "timer2", -+ .class = &omap44xx_timer_1ms_hwmod_class, -+ .mpu_irqs = omap44xx_timer2_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer2_irqs), -+ .main_clk = "timer2_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, - }, - }, -- .slaves = omap44xx_i2c2_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves), -+ .slaves = omap44xx_timer2_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer2_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* i2c3 */ --static struct omap_hwmod omap44xx_i2c3_hwmod; --static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = { -- { .irq = 61 + OMAP44XX_IRQ_GIC_START }, --}; -- --static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = { -- { .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START }, -- { .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START }, -+/* timer3 */ -+static struct omap_hwmod omap44xx_timer3_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer3_irqs[] = { -+ { .irq = 39 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_timer3_addrs[] = { - { -- .pa_start = 0x48060000, -- .pa_end = 0x480600ff, -+ .pa_start = 0x48034000, -+ .pa_end = 0x4803407f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> i2c3 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = { -+/* l4_per -> timer3 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer3 = { - .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_i2c3_hwmod, -+ .slave = &omap44xx_timer3_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_i2c3_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_i2c3_addrs), -+ .addr = omap44xx_timer3_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer3_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* i2c3 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { -- &omap44xx_l4_per__i2c3, -+/* timer3 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer3_slaves[] = { -+ &omap44xx_l4_per__timer3, - }; - --static struct omap_hwmod omap44xx_i2c3_hwmod = { -- .name = "i2c3", -- .class = &omap44xx_i2c_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .mpu_irqs = omap44xx_i2c3_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs), -- .sdma_reqs = omap44xx_i2c3_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c3_sdma_reqs), -- .main_clk = "i2c3_fck", -+static struct omap_hwmod omap44xx_timer3_hwmod = { -+ .name = "timer3", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer3_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer3_irqs), -+ .main_clk = "timer3_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, - }, - }, -- .slaves = omap44xx_i2c3_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves), -+ .slaves = omap44xx_timer3_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer3_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* i2c4 */ --static struct omap_hwmod omap44xx_i2c4_hwmod; --static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = { -- { .irq = 62 + OMAP44XX_IRQ_GIC_START }, --}; -- --static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = { -- { .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START }, -- { .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START }, -+/* timer4 */ -+static struct omap_hwmod omap44xx_timer4_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer4_irqs[] = { -+ { .irq = 40 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_timer4_addrs[] = { - { -- .pa_start = 0x48350000, -- .pa_end = 0x483500ff, -+ .pa_start = 0x48036000, -+ .pa_end = 0x4803607f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_per -> i2c4 */ --static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = { -+/* l4_per -> timer4 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer4 = { - .master = &omap44xx_l4_per_hwmod, -- .slave = &omap44xx_i2c4_hwmod, -+ .slave = &omap44xx_timer4_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_i2c4_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_i2c4_addrs), -+ .addr = omap44xx_timer4_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer4_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* i2c4 slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = { -- &omap44xx_l4_per__i2c4, -+/* timer4 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer4_slaves[] = { -+ &omap44xx_l4_per__timer4, - }; - --static struct omap_hwmod omap44xx_i2c4_hwmod = { -- .name = "i2c4", -- .class = &omap44xx_i2c_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .mpu_irqs = omap44xx_i2c4_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs), -- .sdma_reqs = omap44xx_i2c4_sdma_reqs, -- .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c4_sdma_reqs), -- .main_clk = "i2c4_fck", -+static struct omap_hwmod omap44xx_timer4_hwmod = { -+ .name = "timer4", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer4_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer4_irqs), -+ .main_clk = "timer4_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, - }, - }, -- .slaves = omap44xx_i2c4_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves), -+ .slaves = omap44xx_timer4_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer4_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* -- * 'iva' class -- * multi-standard video encoder/decoder hardware accelerator -- */ -+/* timer5 */ -+static struct omap_hwmod omap44xx_timer5_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer5_irqs[] = { -+ { .irq = 41 + OMAP44XX_IRQ_GIC_START }, -+}; - --static struct omap_hwmod_class omap44xx_iva_hwmod_class = { -- .name = "iva", -+static struct omap_hwmod_addr_space omap44xx_timer5_addrs[] = { -+ { -+ .pa_start = 0x40138000, -+ .pa_end = 0x4013807f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --/* iva */ --static struct omap_hwmod_irq_info omap44xx_iva_irqs[] = { -- { .name = "sync_1", .irq = 103 + OMAP44XX_IRQ_GIC_START }, -- { .name = "sync_0", .irq = 104 + OMAP44XX_IRQ_GIC_START }, -- { .name = "mailbox_0", .irq = 107 + OMAP44XX_IRQ_GIC_START }, -+/* l4_abe -> timer5 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer5_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer5_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer5_addrs), -+ .user = OCP_USER_MPU, - }; - --static struct omap_hwmod_rst_info omap44xx_iva_resets[] = { -- { .name = "logic", .rst_shift = 2 }, -+static struct omap_hwmod_addr_space omap44xx_timer5_dma_addrs[] = { -+ { -+ .pa_start = 0x49038000, -+ .pa_end = 0x4903807f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_rst_info omap44xx_iva_seq0_resets[] = { -- { .name = "seq0", .rst_shift = 0 }, -+/* l4_abe -> timer5 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer5_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer5_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer5_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --static struct omap_hwmod_rst_info omap44xx_iva_seq1_resets[] = { -- { .name = "seq1", .rst_shift = 1 }, -+/* timer5 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer5_slaves[] = { -+ &omap44xx_l4_abe__timer5, -+ &omap44xx_l4_abe__timer5_dma, - }; - --/* iva master ports */ --static struct omap_hwmod_ocp_if *omap44xx_iva_masters[] = { -- &omap44xx_iva__l3_main_2, -- &omap44xx_iva__l3_instr, -+static struct omap_hwmod omap44xx_timer5_hwmod = { -+ .name = "timer5", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer5_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer5_irqs), -+ .main_clk = "timer5_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER5_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_timer5_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer5_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = { -+/* timer6 */ -+static struct omap_hwmod omap44xx_timer6_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer6_irqs[] = { -+ { .irq = 42 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_timer6_addrs[] = { - { -- .pa_start = 0x5a000000, -- .pa_end = 0x5a07ffff, -+ .pa_start = 0x4013a000, -+ .pa_end = 0x4013a07f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l3_main_2 -> iva */ --static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = { -- .master = &omap44xx_l3_main_2_hwmod, -- .slave = &omap44xx_iva_hwmod, -- .clk = "l3_div_ck", -- .addr = omap44xx_iva_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_iva_addrs), -+/* l4_abe -> timer6 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer6_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer6_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer6_addrs), - .user = OCP_USER_MPU, - }; - --/* iva slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_iva_slaves[] = { -- &omap44xx_dsp__iva, -- &omap44xx_l3_main_2__iva, -+static struct omap_hwmod_addr_space omap44xx_timer6_dma_addrs[] = { -+ { -+ .pa_start = 0x4903a000, -+ .pa_end = 0x4903a07f, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_abe -> timer6 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer6_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer6_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer6_dma_addrs), -+ .user = OCP_USER_SDMA, -+}; -+ -+/* timer6 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer6_slaves[] = { -+ &omap44xx_l4_abe__timer6, -+ &omap44xx_l4_abe__timer6_dma, - }; - --/* Pseudo hwmod for reset control purpose only */ --static struct omap_hwmod omap44xx_iva_seq0_hwmod = { -- .name = "iva_seq0", -- .class = &omap44xx_iva_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .rst_lines = omap44xx_iva_seq0_resets, -- .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq0_resets), -+static struct omap_hwmod omap44xx_timer6_hwmod = { -+ .name = "timer6", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer6_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer6_irqs), -+ .main_clk = "timer6_fck", - .prcm = { - .omap4 = { -- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER6_CLKCTRL, - }, - }, -+ .slaves = omap44xx_timer6_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer6_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* Pseudo hwmod for reset control purpose only */ --static struct omap_hwmod omap44xx_iva_seq1_hwmod = { -- .name = "iva_seq1", -- .class = &omap44xx_iva_hwmod_class, -- .flags = HWMOD_INIT_NO_RESET, -- .rst_lines = omap44xx_iva_seq1_resets, -- .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_seq1_resets), -- .prcm = { -- .omap4 = { -- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -- }, -- }, -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+/* timer7 */ -+static struct omap_hwmod omap44xx_timer7_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer7_irqs[] = { -+ { .irq = 43 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod omap44xx_iva_hwmod = { -- .name = "iva", -- .class = &omap44xx_iva_hwmod_class, -- .mpu_irqs = omap44xx_iva_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_iva_irqs), -- .rst_lines = omap44xx_iva_resets, -- .rst_lines_cnt = ARRAY_SIZE(omap44xx_iva_resets), -- .main_clk = "iva_fck", -- .prcm = { -- .omap4 = { -- .clkctrl_reg = OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, -- .rstctrl_reg = OMAP4430_RM_IVAHD_RSTCTRL, -- }, -+static struct omap_hwmod_addr_space omap44xx_timer7_addrs[] = { -+ { -+ .pa_start = 0x4013c000, -+ .pa_end = 0x4013c07f, -+ .flags = ADDR_TYPE_RT - }, -- .slaves = omap44xx_iva_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves), -- .masters = omap44xx_iva_masters, -- .masters_cnt = ARRAY_SIZE(omap44xx_iva_masters), -- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* -- * 'mpu' class -- * mpu sub-system -- */ -+/* l4_abe -> timer7 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer7_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer7_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer7_addrs), -+ .user = OCP_USER_MPU, -+}; - --static struct omap_hwmod_class omap44xx_mpu_hwmod_class = { -- .name = "mpu", -+static struct omap_hwmod_addr_space omap44xx_timer7_dma_addrs[] = { -+ { -+ .pa_start = 0x4903c000, -+ .pa_end = 0x4903c07f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --/* mpu */ --static struct omap_hwmod_irq_info omap44xx_mpu_irqs[] = { -- { .name = "pl310", .irq = 0 + OMAP44XX_IRQ_GIC_START }, -- { .name = "cti0", .irq = 1 + OMAP44XX_IRQ_GIC_START }, -- { .name = "cti1", .irq = 2 + OMAP44XX_IRQ_GIC_START }, -+/* l4_abe -> timer7 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer7_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer7_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer7_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --/* mpu master ports */ --static struct omap_hwmod_ocp_if *omap44xx_mpu_masters[] = { -- &omap44xx_mpu__l3_main_1, -- &omap44xx_mpu__l4_abe, -- &omap44xx_mpu__dmm, -+/* timer7 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer7_slaves[] = { -+ &omap44xx_l4_abe__timer7, -+ &omap44xx_l4_abe__timer7_dma, - }; - --static struct omap_hwmod omap44xx_mpu_hwmod = { -- .name = "mpu", -- .class = &omap44xx_mpu_hwmod_class, -- .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), -- .mpu_irqs = omap44xx_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs), -- .main_clk = "dpll_mpu_m2_ck", -+static struct omap_hwmod omap44xx_timer7_hwmod = { -+ .name = "timer7", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer7_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer7_irqs), -+ .main_clk = "timer7_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER7_CLKCTRL, - }, - }, -- .masters = omap44xx_mpu_masters, -- .masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters), -+ .slaves = omap44xx_timer7_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer7_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* -- * 'smartreflex' class -- * smartreflex module (monitor silicon performance and outputs a measure of -- * performance error) -- */ -+/* timer8 */ -+static struct omap_hwmod omap44xx_timer8_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer8_irqs[] = { -+ { .irq = 44 + OMAP44XX_IRQ_GIC_START }, -+}; - --/* The IP is not compliant to type1 / type2 scheme */ --static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = { -- .sidle_shift = 24, -- .enwkup_shift = 26, -+static struct omap_hwmod_addr_space omap44xx_timer8_addrs[] = { -+ { -+ .pa_start = 0x4013e000, -+ .pa_end = 0x4013e07f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = { -- .sysc_offs = 0x0038, -- .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE), -- .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -- SIDLE_SMART_WKUP), -- .sysc_fields = &omap_hwmod_sysc_type_smartreflex, -+/* l4_abe -> timer8 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer8_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer8_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer8_addrs), -+ .user = OCP_USER_MPU, - }; - --static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = { -- .name = "smartreflex", -- .sysc = &omap44xx_smartreflex_sysc, -- .rev = 2, -+static struct omap_hwmod_addr_space omap44xx_timer8_dma_addrs[] = { -+ { -+ .pa_start = 0x4903e000, -+ .pa_end = 0x4903e07f, -+ .flags = ADDR_TYPE_RT -+ }, - }; - --/* smartreflex_core */ --static struct omap_hwmod omap44xx_smartreflex_core_hwmod; --static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = { -- { .irq = 19 + OMAP44XX_IRQ_GIC_START }, -+/* l4_abe -> timer8 (dma) */ -+static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8_dma = { -+ .master = &omap44xx_l4_abe_hwmod, -+ .slave = &omap44xx_timer8_hwmod, -+ .clk = "ocp_abe_iclk", -+ .addr = omap44xx_timer8_dma_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer8_dma_addrs), -+ .user = OCP_USER_SDMA, - }; - --static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = { -+/* timer8 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer8_slaves[] = { -+ &omap44xx_l4_abe__timer8, -+ &omap44xx_l4_abe__timer8_dma, -+}; -+ -+static struct omap_hwmod omap44xx_timer8_hwmod = { -+ .name = "timer8", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer8_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer8_irqs), -+ .main_clk = "timer8_fck", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM1_ABE_TIMER8_CLKCTRL, -+ }, -+ }, -+ .slaves = omap44xx_timer8_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer8_slaves), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* timer9 */ -+static struct omap_hwmod omap44xx_timer9_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer9_irqs[] = { -+ { .irq = 45 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_timer9_addrs[] = { - { -- .pa_start = 0x4a0dd000, -- .pa_end = 0x4a0dd03f, -+ .pa_start = 0x4803e000, -+ .pa_end = 0x4803e07f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_cfg -> smartreflex_core */ --static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = { -- .master = &omap44xx_l4_cfg_hwmod, -- .slave = &omap44xx_smartreflex_core_hwmod, -+/* l4_per -> timer9 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer9 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_timer9_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_smartreflex_core_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs), -+ .addr = omap44xx_timer9_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer9_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* smartreflex_core slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = { -- &omap44xx_l4_cfg__smartreflex_core, -+/* timer9 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer9_slaves[] = { -+ &omap44xx_l4_per__timer9, - }; - --static struct omap_hwmod omap44xx_smartreflex_core_hwmod = { -- .name = "smartreflex_core", -- .class = &omap44xx_smartreflex_hwmod_class, -- .mpu_irqs = omap44xx_smartreflex_core_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs), -- .main_clk = "smartreflex_core_fck", -- .vdd_name = "core", -+static struct omap_hwmod omap44xx_timer9_hwmod = { -+ .name = "timer9", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer9_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer9_irqs), -+ .main_clk = "timer9_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, - }, - }, -- .slaves = omap44xx_smartreflex_core_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves), -+ .slaves = omap44xx_timer9_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer9_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* smartreflex_iva */ --static struct omap_hwmod omap44xx_smartreflex_iva_hwmod; --static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = { -- { .irq = 102 + OMAP44XX_IRQ_GIC_START }, -+/* timer10 */ -+static struct omap_hwmod omap44xx_timer10_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer10_irqs[] = { -+ { .irq = 46 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_timer10_addrs[] = { - { -- .pa_start = 0x4a0db000, -- .pa_end = 0x4a0db03f, -+ .pa_start = 0x48086000, -+ .pa_end = 0x4808607f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_cfg -> smartreflex_iva */ --static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = { -- .master = &omap44xx_l4_cfg_hwmod, -- .slave = &omap44xx_smartreflex_iva_hwmod, -+/* l4_per -> timer10 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer10 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_timer10_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_smartreflex_iva_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs), -+ .addr = omap44xx_timer10_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer10_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* smartreflex_iva slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = { -- &omap44xx_l4_cfg__smartreflex_iva, -+/* timer10 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer10_slaves[] = { -+ &omap44xx_l4_per__timer10, - }; - --static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = { -- .name = "smartreflex_iva", -- .class = &omap44xx_smartreflex_hwmod_class, -- .mpu_irqs = omap44xx_smartreflex_iva_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs), -- .main_clk = "smartreflex_iva_fck", -- .vdd_name = "iva", -+static struct omap_hwmod omap44xx_timer10_hwmod = { -+ .name = "timer10", -+ .class = &omap44xx_timer_1ms_hwmod_class, -+ .mpu_irqs = omap44xx_timer10_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer10_irqs), -+ .main_clk = "timer10_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, - }, - }, -- .slaves = omap44xx_smartreflex_iva_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves), -+ .slaves = omap44xx_timer10_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer10_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - --/* smartreflex_mpu */ --static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod; --static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = { -- { .irq = 18 + OMAP44XX_IRQ_GIC_START }, -+/* timer11 */ -+static struct omap_hwmod omap44xx_timer11_hwmod; -+static struct omap_hwmod_irq_info omap44xx_timer11_irqs[] = { -+ { .irq = 47 + OMAP44XX_IRQ_GIC_START }, - }; - --static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = { -+static struct omap_hwmod_addr_space omap44xx_timer11_addrs[] = { - { -- .pa_start = 0x4a0d9000, -- .pa_end = 0x4a0d903f, -+ .pa_start = 0x48088000, -+ .pa_end = 0x4808807f, - .flags = ADDR_TYPE_RT - }, - }; - --/* l4_cfg -> smartreflex_mpu */ --static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = { -- .master = &omap44xx_l4_cfg_hwmod, -- .slave = &omap44xx_smartreflex_mpu_hwmod, -+/* l4_per -> timer11 */ -+static struct omap_hwmod_ocp_if omap44xx_l4_per__timer11 = { -+ .master = &omap44xx_l4_per_hwmod, -+ .slave = &omap44xx_timer11_hwmod, - .clk = "l4_div_ck", -- .addr = omap44xx_smartreflex_mpu_addrs, -- .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs), -+ .addr = omap44xx_timer11_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_timer11_addrs), - .user = OCP_USER_MPU | OCP_USER_SDMA, - }; - --/* smartreflex_mpu slave ports */ --static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = { -- &omap44xx_l4_cfg__smartreflex_mpu, -+/* timer11 slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_timer11_slaves[] = { -+ &omap44xx_l4_per__timer11, - }; - --static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = { -- .name = "smartreflex_mpu", -- .class = &omap44xx_smartreflex_hwmod_class, -- .mpu_irqs = omap44xx_smartreflex_mpu_irqs, -- .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs), -- .main_clk = "smartreflex_mpu_fck", -- .vdd_name = "mpu", -+static struct omap_hwmod omap44xx_timer11_hwmod = { -+ .name = "timer11", -+ .class = &omap44xx_timer_hwmod_class, -+ .mpu_irqs = omap44xx_timer11_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_timer11_irqs), -+ .main_clk = "timer11_fck", - .prcm = { - .omap4 = { -- .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL, -+ .clkctrl_reg = OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, - }, - }, -- .slaves = omap44xx_smartreflex_mpu_slaves, -- .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves), -+ .slaves = omap44xx_timer11_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_timer11_slaves), - .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), - }; - -@@ -1870,6 +4776,88 @@ - }; - - /* -+ * 'usb_otg_hs' class -+ * high-speed on-the-go universal serial bus (usb_otg_hs) controller -+ */ -+ -+static struct omap_hwmod_class_sysconfig omap44xx_usb_otg_hs_sysc = { -+ .rev_offs = 0x0400, -+ .sysc_offs = 0x0404, -+ .syss_offs = 0x0408, -+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP | -+ SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | -+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), -+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | -+ SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | -+ MSTANDBY_SMART), -+ .sysc_fields = &omap_hwmod_sysc_type1, -+}; -+ -+static struct omap_hwmod_class omap44xx_usb_otg_hs_hwmod_class = { -+ .name = "usb_otg_hs", -+ .sysc = &omap44xx_usb_otg_hs_sysc, -+}; -+ -+/* usb_otg_hs */ -+static struct omap_hwmod_irq_info omap44xx_usb_otg_hs_irqs[] = { -+ { .name = "mc", .irq = 92 + OMAP44XX_IRQ_GIC_START }, -+ { .name = "dma", .irq = 93 + OMAP44XX_IRQ_GIC_START }, -+}; -+ -+/* usb_otg_hs master ports */ -+static struct omap_hwmod_ocp_if *omap44xx_usb_otg_hs_masters[] = { -+ &omap44xx_usb_otg_hs__l3_main_2, -+}; -+ -+static struct omap_hwmod_addr_space omap44xx_usb_otg_hs_addrs[] = { -+ { -+ .pa_start = 0x4a0ab000, -+ .pa_end = 0x4a0ab003, -+ .flags = ADDR_TYPE_RT -+ }, -+}; -+ -+/* l4_cfg -> usb_otg_hs */ -+static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_otg_hs = { -+ .master = &omap44xx_l4_cfg_hwmod, -+ .slave = &omap44xx_usb_otg_hs_hwmod, -+ .clk = "l4_div_ck", -+ .addr = omap44xx_usb_otg_hs_addrs, -+ .addr_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_addrs), -+ .user = OCP_USER_MPU | OCP_USER_SDMA, -+}; -+ -+/* usb_otg_hs slave ports */ -+static struct omap_hwmod_ocp_if *omap44xx_usb_otg_hs_slaves[] = { -+ &omap44xx_l4_cfg__usb_otg_hs, -+}; -+ -+static struct omap_hwmod_opt_clk usb_otg_hs_opt_clks[] = { -+ { .role = "xclk", .clk = "usb_otg_hs_xclk" }, -+}; -+ -+static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = { -+ .name = "usb_otg_hs", -+ .class = &omap44xx_usb_otg_hs_hwmod_class, -+ .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, -+ .mpu_irqs = omap44xx_usb_otg_hs_irqs, -+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_irqs), -+ .main_clk = "usb_otg_hs_ick", -+ .prcm = { -+ .omap4 = { -+ .clkctrl_reg = OMAP4430_CM_L3INIT_USB_OTG_CLKCTRL, -+ }, -+ }, -+ .opt_clks = usb_otg_hs_opt_clks, -+ .opt_clks_cnt = ARRAY_SIZE(usb_otg_hs_opt_clks), -+ .slaves = omap44xx_usb_otg_hs_slaves, -+ .slaves_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_slaves), -+ .masters = omap44xx_usb_otg_hs_masters, -+ .masters_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_masters), -+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), -+}; -+ -+/* - * 'wd_timer' class - * 32-bit watchdog upward counter that generates a pulse on the reset pin on - * overflow condition -@@ -2024,13 +5012,34 @@ - /* mpu_bus class */ - &omap44xx_mpu_private_hwmod, - -+ /* aess class */ -+/* &omap44xx_aess_hwmod, */ -+ -+ /* bandgap class */ -+ &omap44xx_bandgap_hwmod, -+ -+ /* counter class */ -+/* &omap44xx_counter_32k_hwmod, */ -+ - /* dma class */ - &omap44xx_dma_system_hwmod, - -+ /* dmic class */ -+ &omap44xx_dmic_hwmod, -+ - /* dsp class */ - &omap44xx_dsp_hwmod, - &omap44xx_dsp_c0_hwmod, - -+ /* dss class */ -+ &omap44xx_dss_hwmod, -+ &omap44xx_dss_dispc_hwmod, -+ &omap44xx_dss_dsi1_hwmod, -+ &omap44xx_dss_dsi2_hwmod, -+ &omap44xx_dss_hdmi_hwmod, -+ &omap44xx_dss_rfbi_hwmod, -+ &omap44xx_dss_venc_hwmod, -+ - /* gpio class */ - &omap44xx_gpio1_hwmod, - &omap44xx_gpio2_hwmod, -@@ -2039,17 +5048,56 @@ - &omap44xx_gpio5_hwmod, - &omap44xx_gpio6_hwmod, - -+ /* hsi class */ -+/* &omap44xx_hsi_hwmod, */ -+ - /* i2c class */ - &omap44xx_i2c1_hwmod, - &omap44xx_i2c2_hwmod, - &omap44xx_i2c3_hwmod, - &omap44xx_i2c4_hwmod, - -+ /* ipu class */ -+ &omap44xx_ipu_hwmod, -+ &omap44xx_ipu_c0_hwmod, -+ &omap44xx_ipu_c1_hwmod, -+ -+ /* iss class */ -+/* &omap44xx_iss_hwmod, */ -+ - /* iva class */ - &omap44xx_iva_hwmod, - &omap44xx_iva_seq0_hwmod, - &omap44xx_iva_seq1_hwmod, - -+ /* kbd class */ -+/* &omap44xx_kbd_hwmod, */ -+ -+ /* mailbox class */ -+ &omap44xx_mailbox_hwmod, -+ -+ /* mcbsp class */ -+ &omap44xx_mcbsp1_hwmod, -+ &omap44xx_mcbsp2_hwmod, -+ &omap44xx_mcbsp3_hwmod, -+ &omap44xx_mcbsp4_hwmod, -+ -+ /* mcpdm class */ -+/* &omap44xx_mcpdm_hwmod, */ -+ -+ /* mcspi class */ -+ &omap44xx_mcspi1_hwmod, -+ &omap44xx_mcspi2_hwmod, -+ &omap44xx_mcspi3_hwmod, -+ &omap44xx_mcspi4_hwmod, -+ -+ /* mmc class */ -+ &omap44xx_mmc1_hwmod, -+ &omap44xx_mmc2_hwmod, -+ &omap44xx_mmc3_hwmod, -+ &omap44xx_mmc4_hwmod, -+ &omap44xx_mmc5_hwmod, -+ - /* mpu class */ - &omap44xx_mpu_hwmod, - -@@ -2058,12 +5106,31 @@ - &omap44xx_smartreflex_iva_hwmod, - &omap44xx_smartreflex_mpu_hwmod, - -+ /* spinlock class */ -+ &omap44xx_spinlock_hwmod, -+ -+ /* timer class */ -+ &omap44xx_timer1_hwmod, -+ &omap44xx_timer2_hwmod, -+ &omap44xx_timer3_hwmod, -+ &omap44xx_timer4_hwmod, -+ &omap44xx_timer5_hwmod, -+ &omap44xx_timer6_hwmod, -+ &omap44xx_timer7_hwmod, -+ &omap44xx_timer8_hwmod, -+ &omap44xx_timer9_hwmod, -+ &omap44xx_timer10_hwmod, -+ &omap44xx_timer11_hwmod, -+ - /* uart class */ - &omap44xx_uart1_hwmod, - &omap44xx_uart2_hwmod, - &omap44xx_uart3_hwmod, - &omap44xx_uart4_hwmod, - -+ /* usb_otg_hs class */ -+ &omap44xx_usb_otg_hs_hwmod, -+ - /* wd_timer class */ - &omap44xx_wd_timer2_hwmod, - &omap44xx_wd_timer3_hwmod, -@@ -2073,6 +5140,6 @@ - - int __init omap44xx_hwmod_init(void) - { -- return omap_hwmod_init(omap44xx_hwmods); -+ return omap_hwmod_register(omap44xx_hwmods); - } - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_hwmod.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_hwmod.c 2011-03-09 13:19:09.827507277 +0100 -@@ -1,7 +1,7 @@ - /* - * omap_hwmod implementation for OMAP2/3/4 - * -- * Copyright (C) 2009-2010 Nokia Corporation -+ * Copyright (C) 2009-2011 Nokia Corporation - * - * Paul Walmsley, Benoît Cousson, Kevin Hilman - * -@@ -162,9 +162,6 @@ - /* mpu_oh: used to add/remove MPU initiator from sleepdep list */ - static struct omap_hwmod *mpu_oh; - --/* inited: 0 if omap_hwmod_init() has not yet been called; 1 otherwise */ --static u8 inited; -- - - /* Private functions */ - -@@ -904,18 +901,16 @@ - * @oh: struct omap_hwmod * - * @data: not used; pass NULL - * -- * Called by omap_hwmod_late_init() (after omap2_clk_init()). -- * Resolves all clock names embedded in the hwmod. Returns -EINVAL if -- * the omap_hwmod has not yet been registered or if the clocks have -- * already been initialized, 0 on success, or a non-zero error on -- * failure. -+ * Called by omap_hwmod_setup_*() (after omap2_clk_init()). -+ * Resolves all clock names embedded in the hwmod. Returns 0 on -+ * success, or a negative error code on failure. - */ - static int _init_clocks(struct omap_hwmod *oh, void *data) - { - int ret = 0; - -- if (!oh || (oh->_state != _HWMOD_STATE_REGISTERED)) -- return -EINVAL; -+ if (oh->_state != _HWMOD_STATE_REGISTERED) -+ return 0; - - pr_debug("omap_hwmod: %s: looking up clocks\n", oh->name); - -@@ -1354,14 +1349,16 @@ - * @oh: struct omap_hwmod * - * - * Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh -- * OCP_SYSCONFIG register. Returns -EINVAL if the hwmod is in the -- * wrong state or returns 0. -+ * OCP_SYSCONFIG register. Returns 0. - */ - static int _setup(struct omap_hwmod *oh, void *data) - { - int i, r; - u8 postsetup_state; - -+ if (oh->_state != _HWMOD_STATE_CLKS_INITED) -+ return 0; -+ - /* Set iclk autoidle mode */ - if (oh->slaves_cnt > 0) { - for (i = 0; i < oh->slaves_cnt; i++) { -@@ -1455,7 +1452,7 @@ - */ - static int __init _register(struct omap_hwmod *oh) - { -- int ret, ms_id; -+ int ms_id; - - if (!oh || !oh->name || !oh->class || !oh->class->name || - (oh->_state != _HWMOD_STATE_UNKNOWN)) -@@ -1467,12 +1464,10 @@ - return -EEXIST; - - ms_id = _find_mpu_port_index(oh); -- if (!IS_ERR_VALUE(ms_id)) { -+ if (!IS_ERR_VALUE(ms_id)) - oh->_mpu_port_index = ms_id; -- oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); -- } else { -+ else - oh->_int_flags |= _HWMOD_NO_MPU_PORT; -- } - - list_add_tail(&oh->node, &omap_hwmod_list); - -@@ -1480,9 +1475,14 @@ - - oh->_state = _HWMOD_STATE_REGISTERED; - -- ret = 0; -+ /* -+ * XXX Rather than doing a strcmp(), this should test a flag -+ * set in the hwmod data, inserted by the autogenerator code. -+ */ -+ if (!strcmp(oh->name, MPU_INITIATOR_NAME)) -+ mpu_oh = oh; - -- return ret; -+ return 0; - } - - -@@ -1585,65 +1585,132 @@ - return ret; - } - -- - /** -- * omap_hwmod_init - init omap_hwmod code and register hwmods -+ * omap_hwmod_register - register an array of hwmods - * @ohs: pointer to an array of omap_hwmods to register - * - * Intended to be called early in boot before the clock framework is - * initialized. If @ohs is not null, will register all omap_hwmods -- * listed in @ohs that are valid for this chip. Returns -EINVAL if -- * omap_hwmod_init() has already been called or 0 otherwise. -+ * listed in @ohs that are valid for this chip. Returns 0. -+ */ -+int __init omap_hwmod_register(struct omap_hwmod **ohs) -+{ -+ int r, i; -+ -+ if (!ohs) -+ return 0; -+ -+ i = 0; -+ do { -+ if (!omap_chip_is(ohs[i]->omap_chip)) -+ continue; -+ -+ r = _register(ohs[i]); -+ WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name, -+ r); -+ } while (ohs[++i]); -+ -+ return 0; -+} -+ -+/* -+ * _populate_mpu_rt_base - populate the virtual address for a hwmod -+ * -+ * Must be called only from omap_hwmod_setup_*() so ioremap works properly. -+ * Assumes the caller takes care of locking if needed. - */ --int __init omap_hwmod_init(struct omap_hwmod **ohs) -+static int __init _populate_mpu_rt_base(struct omap_hwmod *oh, void *data) -+{ -+ if (oh->_state != _HWMOD_STATE_REGISTERED) -+ return 0; -+ -+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT) -+ return 0; -+ -+ oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index); -+ if (!oh->_mpu_rt_va) -+ pr_warning("omap_hwmod: %s found no _mpu_rt_va for %s\n", -+ __func__, oh->name); -+ -+ return 0; -+} -+ -+/** -+ * omap_hwmod_setup_one - set up a single hwmod -+ * @oh_name: const char * name of the already-registered hwmod to set up -+ * -+ * Must be called after omap2_clk_init(). Resolves the struct clk -+ * names to struct clk pointers for each registered omap_hwmod. Also -+ * calls _setup() on each hwmod. Returns -EINVAL upon error or 0 upon -+ * success. -+ */ -+int __init omap_hwmod_setup_one(const char *oh_name) - { - struct omap_hwmod *oh; - int r; - -- if (inited) -+ pr_debug("omap_hwmod: %s: %s\n", oh_name, __func__); -+ -+ if (!mpu_oh) { -+ pr_err("omap_hwmod: %s: cannot setup_one: MPU initiator hwmod %s not yet registered\n", -+ oh_name, MPU_INITIATOR_NAME); - return -EINVAL; -+ } - -- inited = 1; -+ oh = _lookup(oh_name); -+ if (!oh) { -+ WARN(1, "omap_hwmod: %s: hwmod not yet registered\n", oh_name); -+ return -EINVAL; -+ } - -- if (!ohs) -- return 0; -+ if (mpu_oh->_state == _HWMOD_STATE_REGISTERED && oh != mpu_oh) -+ omap_hwmod_setup_one(MPU_INITIATOR_NAME); - -- oh = *ohs; -- while (oh) { -- if (omap_chip_is(oh->omap_chip)) { -- r = _register(oh); -- WARN(r, "omap_hwmod: %s: _register returned " -- "%d\n", oh->name, r); -- } -- oh = *++ohs; -+ r = _populate_mpu_rt_base(oh, NULL); -+ if (IS_ERR_VALUE(r)) { -+ WARN(1, "omap_hwmod: %s: couldn't set mpu_rt_base\n", oh_name); -+ return -EINVAL; -+ } -+ -+ r = _init_clocks(oh, NULL); -+ if (IS_ERR_VALUE(r)) { -+ WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh_name); -+ return -EINVAL; - } - -+ _setup(oh, NULL); -+ - return 0; - } - - /** -- * omap_hwmod_late_init - do some post-clock framework initialization -+ * omap_hwmod_setup - do some post-clock framework initialization - * - * Must be called after omap2_clk_init(). Resolves the struct clk names - * to struct clk pointers for each registered omap_hwmod. Also calls -- * _setup() on each hwmod. Returns 0. -+ * _setup() on each hwmod. Returns 0 upon success. - */ --int omap_hwmod_late_init(void) -+static int __init omap_hwmod_setup_all(void) - { - int r; - -- /* XXX check return value */ -- r = omap_hwmod_for_each(_init_clocks, NULL); -- WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n"); -+ if (!mpu_oh) { -+ pr_err("omap_hwmod: %s: MPU initiator hwmod %s not yet registered\n", -+ __func__, MPU_INITIATOR_NAME); -+ return -EINVAL; -+ } -+ -+ r = omap_hwmod_for_each(_populate_mpu_rt_base, NULL); - -- mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME); -- WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n", -- MPU_INITIATOR_NAME); -+ r = omap_hwmod_for_each(_init_clocks, NULL); -+ WARN(IS_ERR_VALUE(r), -+ "omap_hwmod: %s: _init_clocks failed\n", __func__); - - omap_hwmod_for_each(_setup, NULL); - - return 0; - } -+core_initcall(omap_hwmod_setup_all); - - /** - * omap_hwmod_enable - enable an omap_hwmod -@@ -1862,6 +1929,7 @@ - os = oh->slaves[i]; - - for (j = 0; j < os->addr_cnt; j++) { -+ (res + r)->name = (os->addr + j)->name; - (res + r)->start = (os->addr + j)->pa_start; - (res + r)->end = (os->addr + j)->pa_end; - (res + r)->flags = IORESOURCE_MEM; -@@ -2162,11 +2230,11 @@ - * @oh: struct omap_hwmod * - * @state: state that _setup() should leave the hwmod in - * -- * Sets the hwmod state that @oh will enter at the end of _setup() (called by -- * omap_hwmod_late_init()). Only valid to call between calls to -- * omap_hwmod_init() and omap_hwmod_late_init(). Returns 0 upon success or -- * -EINVAL if there is a problem with the arguments or if the hwmod is -- * in the wrong state. -+ * Sets the hwmod state that @oh will enter at the end of _setup() -+ * (called by omap_hwmod_setup_*()). Only valid to call between -+ * calling omap_hwmod_register() and omap_hwmod_setup_*(). Returns -+ * 0 upon success or -EINVAL if there is a problem with the arguments -+ * or if the hwmod is in the wrong state. - */ - int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state) - { -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/omap_phy_internal.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_phy_internal.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/omap_phy_internal.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/omap_phy_internal.c 2011-03-09 13:19:09.830507217 +0100 -@@ -29,6 +29,7 @@ - #include - - #include -+#include "control.h" - - /* OMAP control module register for UTMI PHY */ - #define CONTROL_DEV_CONF 0x300 -@@ -147,3 +148,95 @@ - - return 0; - } -+ -+void am35x_musb_reset(void) -+{ -+ u32 regval; -+ -+ /* Reset the musb interface */ -+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); -+ -+ regval |= AM35XX_USBOTGSS_SW_RST; -+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); -+ -+ regval &= ~AM35XX_USBOTGSS_SW_RST; -+ omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); -+ -+ regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); -+} -+ -+void am35x_musb_phy_power(u8 on) -+{ -+ unsigned long timeout = jiffies + msecs_to_jiffies(100); -+ u32 devconf2; -+ -+ if (on) { -+ /* -+ * Start the on-chip PHY and its PLL. -+ */ -+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -+ -+ devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); -+ devconf2 |= CONF2_PHY_PLLON; -+ -+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -+ -+ pr_info(KERN_INFO "Waiting for PHY clock good...\n"); -+ while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) -+ & CONF2_PHYCLKGD)) { -+ cpu_relax(); -+ -+ if (time_after(jiffies, timeout)) { -+ pr_err(KERN_ERR "musb PHY clock good timed out\n"); -+ break; -+ } -+ } -+ } else { -+ /* -+ * Power down the on-chip PHY. -+ */ -+ devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -+ -+ devconf2 &= ~CONF2_PHY_PLLON; -+ devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; -+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -+ } -+} -+ -+void am35x_musb_clear_irq(void) -+{ -+ u32 regval; -+ -+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -+ regval |= AM35XX_USBOTGSS_INT_CLR; -+ omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); -+ regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -+} -+ -+void am35x_musb_set_mode(u8 musb_mode) -+{ -+ u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -+ -+ devconf2 &= ~CONF2_OTGMODE; -+ switch (musb_mode) { -+#ifdef CONFIG_USB_MUSB_HDRC_HCD -+ case MUSB_HOST: /* Force VBUS valid, ID = 0 */ -+ devconf2 |= CONF2_FORCE_HOST; -+ break; -+#endif -+#ifdef CONFIG_USB_GADGET_MUSB_HDRC -+ case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ -+ devconf2 |= CONF2_FORCE_DEVICE; -+ break; -+#endif -+#ifdef CONFIG_USB_MUSB_OTG -+ case MUSB_OTG: /* Don't override the VBUS/ID comparators */ -+ devconf2 |= CONF2_NO_OVERRIDE; -+ break; -+#endif -+ default: -+ pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); -+ } -+ -+ omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -+} -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/opp2xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/opp2xxx.h ---- linux-2.6.38-rc7/arch/arm/mach-omap2/opp2xxx.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/opp2xxx.h 2011-03-09 13:19:09.831507196 +0100 -@@ -418,7 +418,7 @@ - - extern const struct prcm_config omap2420_rate_table[]; - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - extern const struct prcm_config omap2430_rate_table[]; - #else - #define omap2430_rate_table NULL -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/powerdomains2xxx_data.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/powerdomains2xxx_data.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/powerdomains2xxx_data.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/powerdomains2xxx_data.c 2011-03-09 13:19:09.835507113 +0100 -@@ -78,7 +78,7 @@ - * 2430-specific powerdomains - */ - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - - /* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */ - -@@ -97,7 +97,7 @@ - }, - }; - --#endif /* CONFIG_ARCH_OMAP2430 */ -+#endif /* CONFIG_SOC_OMAP2430 */ - - /* As powerdomains are added or removed above, this list must also be changed */ - static struct powerdomain *powerdomains_omap2xxx[] __initdata = { -@@ -111,7 +111,7 @@ - &core_24xx_pwrdm, - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - &mdm_pwrdm, - #endif - NULL -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/prcm.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/prcm.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/prcm.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/prcm.c 2011-03-09 13:19:09.836507094 +0100 -@@ -24,6 +24,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -57,7 +58,7 @@ - EXPORT_SYMBOL(omap_prcm_get_reset_sources); - - /* Resets clock rates and reboots the system. Only called from system.h */ --void omap_prcm_arch_reset(char mode, const char *cmd) -+static void omap_prcm_arch_reset(char mode, const char *cmd) - { - s16 prcm_offs = 0; - -@@ -108,6 +109,8 @@ - omap2_prm_read_mod_reg(prcm_offs, OMAP2_RM_RSTCTRL); /* OCP barrier */ - } - -+void (*arch_reset)(char, const char *) = omap_prcm_arch_reset; -+ - /** - * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness - * @reg: physical address of module IDLEST register -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/prcm-common.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/prcm-common.h ---- linux-2.6.38-rc7/arch/arm/mach-omap2/prcm-common.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/prcm-common.h 2011-03-09 13:19:09.836507094 +0100 -@@ -121,6 +121,10 @@ - #define OMAP24XX_ST_MCSPI2_MASK (1 << 18) - #define OMAP24XX_ST_MCSPI1_SHIFT 17 - #define OMAP24XX_ST_MCSPI1_MASK (1 << 17) -+#define OMAP24XX_ST_MCBSP2_SHIFT 16 -+#define OMAP24XX_ST_MCBSP2_MASK (1 << 16) -+#define OMAP24XX_ST_MCBSP1_SHIFT 15 -+#define OMAP24XX_ST_MCBSP1_MASK (1 << 15) - #define OMAP24XX_ST_GPT12_SHIFT 14 - #define OMAP24XX_ST_GPT12_MASK (1 << 14) - #define OMAP24XX_ST_GPT11_SHIFT 13 -@@ -191,6 +195,8 @@ - #define OMAP3430_AUTOIDLE_MASK (1 << 0) - - /* CM_FCLKEN1_CORE, CM_ICLKEN1_CORE, PM_WKEN1_CORE shared bits */ -+#define OMAP3430_EN_MMC3_MASK (1 << 30) -+#define OMAP3430_EN_MMC3_SHIFT 30 - #define OMAP3430_EN_MMC2_MASK (1 << 25) - #define OMAP3430_EN_MMC2_SHIFT 25 - #define OMAP3430_EN_MMC1_MASK (1 << 24) -@@ -231,6 +237,8 @@ - #define OMAP3430_EN_HSOTGUSB_SHIFT 4 - - /* PM_WKST1_CORE, CM_IDLEST1_CORE shared bits */ -+#define OMAP3430_ST_MMC3_SHIFT 30 -+#define OMAP3430_ST_MMC3_MASK (1 << 30) - #define OMAP3430_ST_MMC2_SHIFT 25 - #define OMAP3430_ST_MMC2_MASK (1 << 25) - #define OMAP3430_ST_MMC1_SHIFT 24 -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/serial.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/serial.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/serial.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/serial.c 2011-03-09 13:19:09.841506993 +0100 -@@ -486,7 +486,7 @@ - mod_timer(&uart->timer, jiffies + uart->timeout); - omap_uart_smart_idle_enable(uart, 0); - -- if (cpu_is_omap34xx()) { -+ if (cpu_is_omap34xx() && !cpu_is_ti816x()) { - u32 mod = (uart->num > 1) ? OMAP3430_PER_MOD : CORE_MOD; - u32 wk_mask = 0; - u32 padconf = 0; -@@ -655,7 +655,7 @@ - } - #endif - --void __init omap_serial_early_init(void) -+static int __init omap_serial_early_init(void) - { - int i = 0; - -@@ -672,7 +672,7 @@ - - uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL); - if (WARN_ON(!uart)) -- return; -+ return -ENODEV; - - uart->oh = oh; - uart->num = i++; -@@ -680,7 +680,7 @@ - num_uarts++; - - /* -- * NOTE: omap_hwmod_init() has not yet been called, -+ * NOTE: omap_hwmod_setup*() has not yet been called, - * so no hwmod functions will work yet. - */ - -@@ -691,7 +691,10 @@ - */ - uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; - } while (1); -+ -+ return 0; - } -+core_initcall(omap_serial_early_init); - - /** - * omap_serial_init_port() - initialize single serial port -@@ -759,13 +762,13 @@ - p->private_data = uart; - - /* -- * omap44xx: Never read empty UART fifo -+ * omap44xx, ti816x: Never read empty UART fifo - * omap3xxx: Never read empty UART fifo on UARTs - * with IP rev >=0x52 - */ - uart->regshift = p->regshift; - uart->membase = p->membase; -- if (cpu_is_omap44xx()) -+ if (cpu_is_omap44xx() || cpu_is_ti816x()) - uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; - else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF) - >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) -@@ -847,7 +850,7 @@ - } - - /* Enable the MDR1 errata for OMAP3 */ -- if (cpu_is_omap34xx()) -+ if (cpu_is_omap34xx() && !cpu_is_ti816x()) - uart->errata |= UART_ERRATA_i202_MDR1_ACCESS; - } - -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/timer-gp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/timer-gp.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/timer-gp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/timer-gp.c 2011-03-09 13:19:09.844506932 +0100 -@@ -40,10 +40,11 @@ - #include - #include - #include -+#include -+#include - - #include "timer-gp.h" - --#include - - /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */ - #define MAX_GPTIMER_ID 12 -@@ -133,9 +134,13 @@ - { - u32 tick_rate; - int src; -+ char clockevent_hwmod_name[8]; /* 8 = sizeof("timerXX0") */ - - inited = 1; - -+ sprintf(clockevent_hwmod_name, "timer%d", gptimer_id); -+ omap_hwmod_setup_one(clockevent_hwmod_name); -+ - gptimer = omap_dm_timer_request_specific(gptimer_id); - BUG_ON(gptimer == NULL); - gptimer_wakeup = gptimer; -diff -Naur linux-2.6.38-rc7/arch/arm/mach-omap2/usb-musb.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/usb-musb.c ---- linux-2.6.38-rc7/arch/arm/mach-omap2/usb-musb.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/mach-omap2/usb-musb.c 2011-03-09 13:19:09.844506932 +0100 -@@ -30,118 +30,11 @@ - #include - #include - #include --#include "control.h" -+#include -+#include "mux.h" - - #if defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined (CONFIG_USB_MUSB_AM35X) - --static void am35x_musb_reset(void) --{ -- u32 regval; -- -- /* Reset the musb interface */ -- regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); -- -- regval |= AM35XX_USBOTGSS_SW_RST; -- omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); -- -- regval &= ~AM35XX_USBOTGSS_SW_RST; -- omap_ctrl_writel(regval, AM35XX_CONTROL_IP_SW_RESET); -- -- regval = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); --} -- --static void am35x_musb_phy_power(u8 on) --{ -- unsigned long timeout = jiffies + msecs_to_jiffies(100); -- u32 devconf2; -- -- if (on) { -- /* -- * Start the on-chip PHY and its PLL. -- */ -- devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -- -- devconf2 &= ~(CONF2_RESET | CONF2_PHYPWRDN | CONF2_OTGPWRDN); -- devconf2 |= CONF2_PHY_PLLON; -- -- omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -- -- pr_info(KERN_INFO "Waiting for PHY clock good...\n"); -- while (!(omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2) -- & CONF2_PHYCLKGD)) { -- cpu_relax(); -- -- if (time_after(jiffies, timeout)) { -- pr_err(KERN_ERR "musb PHY clock good timed out\n"); -- break; -- } -- } -- } else { -- /* -- * Power down the on-chip PHY. -- */ -- devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -- -- devconf2 &= ~CONF2_PHY_PLLON; -- devconf2 |= CONF2_PHYPWRDN | CONF2_OTGPWRDN; -- omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); -- } --} -- --static void am35x_musb_clear_irq(void) --{ -- u32 regval; -- -- regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); -- regval |= AM35XX_USBOTGSS_INT_CLR; -- omap_ctrl_writel(regval, AM35XX_CONTROL_LVL_INTR_CLEAR); -- regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); --} -- --static void am35x_musb_set_mode(u8 musb_mode) --{ -- u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2); -- -- devconf2 &= ~CONF2_OTGMODE; -- switch (musb_mode) { --#ifdef CONFIG_USB_MUSB_HDRC_HCD -- case MUSB_HOST: /* Force VBUS valid, ID = 0 */ -- devconf2 |= CONF2_FORCE_HOST; -- break; --#endif --#ifdef CONFIG_USB_GADGET_MUSB_HDRC -- case MUSB_PERIPHERAL: /* Force VBUS valid, ID = 1 */ -- devconf2 |= CONF2_FORCE_DEVICE; -- break; --#endif --#ifdef CONFIG_USB_MUSB_OTG -- case MUSB_OTG: /* Don't override the VBUS/ID comparators */ -- devconf2 |= CONF2_NO_OVERRIDE; -- break; --#endif -- default: -- pr_info(KERN_INFO "Unsupported mode %u\n", musb_mode); -- } -- -- omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2); --} -- --static struct resource musb_resources[] = { -- [0] = { /* start and end set dynamically */ -- .flags = IORESOURCE_MEM, -- }, -- [1] = { /* general IRQ */ -- .start = INT_243X_HS_USB_MC, -- .flags = IORESOURCE_IRQ, -- .name = "mc", -- }, -- [2] = { /* DMA IRQ */ -- .start = INT_243X_HS_USB_DMA, -- .flags = IORESOURCE_IRQ, -- .name = "dma", -- }, --}; -- - static struct musb_hdrc_config musb_config = { - .multipoint = 1, - .dyn_fifo = 1, -@@ -169,38 +62,65 @@ - - static u64 musb_dmamask = DMA_BIT_MASK(32); - --static struct platform_device musb_device = { -- .name = "musb-omap2430", -- .id = -1, -- .dev = { -- .dma_mask = &musb_dmamask, -- .coherent_dma_mask = DMA_BIT_MASK(32), -- .platform_data = &musb_plat, -+static struct omap_device_pm_latency omap_musb_latency[] = { -+ { -+ .deactivate_func = omap_device_idle_hwmods, -+ .activate_func = omap_device_enable_hwmods, -+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, - }, -- .num_resources = ARRAY_SIZE(musb_resources), -- .resource = musb_resources, - }; - -+static void usb_musb_mux_init(struct omap_musb_board_data *board_data) -+{ -+ switch (board_data->interface_type) { -+ case MUSB_INTERFACE_UTMI: -+ omap_mux_init_signal("usba0_otg_dp", OMAP_PIN_INPUT); -+ omap_mux_init_signal("usba0_otg_dm", OMAP_PIN_INPUT); -+ break; -+ case MUSB_INTERFACE_ULPI: -+ omap_mux_init_signal("usba0_ulpiphy_clk", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_stp", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dir", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_nxt", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat0", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat1", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat2", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat3", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat4", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat5", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat6", -+ OMAP_PIN_INPUT_PULLDOWN); -+ omap_mux_init_signal("usba0_ulpiphy_dat7", -+ OMAP_PIN_INPUT_PULLDOWN); -+ break; -+ default: -+ break; -+ } -+} -+ - void __init usb_musb_init(struct omap_musb_board_data *board_data) - { -- if (cpu_is_omap243x()) { -- musb_resources[0].start = OMAP243X_HS_BASE; -- } else if (cpu_is_omap3517() || cpu_is_omap3505()) { -- musb_device.name = "musb-am35x"; -- musb_resources[0].start = AM35XX_IPSS_USBOTGSS_BASE; -- musb_resources[1].start = INT_35XX_USBOTG_IRQ; -- board_data->set_phy_power = am35x_musb_phy_power; -- board_data->clear_irq = am35x_musb_clear_irq; -- board_data->set_mode = am35x_musb_set_mode; -- board_data->reset = am35x_musb_reset; -- } else if (cpu_is_omap34xx()) { -- musb_resources[0].start = OMAP34XX_HSUSB_OTG_BASE; -+ struct omap_hwmod *oh; -+ struct omap_device *od; -+ struct platform_device *pdev; -+ struct device *dev; -+ int bus_id = -1; -+ const char *oh_name, *name; -+ -+ if (cpu_is_omap3517() || cpu_is_omap3505()) { - } else if (cpu_is_omap44xx()) { -- musb_resources[0].start = OMAP44XX_HSUSB_OTG_BASE; -- musb_resources[1].start = OMAP44XX_IRQ_HS_USB_MC_N; -- musb_resources[2].start = OMAP44XX_IRQ_HS_USB_DMA_N; -+ usb_musb_mux_init(board_data); - } -- musb_resources[0].end = musb_resources[0].start + SZ_4K - 1; - - /* - * REVISIT: This line can be removed once all the platforms using -@@ -212,8 +132,35 @@ - musb_plat.mode = board_data->mode; - musb_plat.extvbus = board_data->extvbus; - -- if (platform_device_register(&musb_device) < 0) -- printk(KERN_ERR "Unable to register HS-USB (MUSB) device\n"); -+ if (cpu_is_omap3517() || cpu_is_omap3505()) { -+ oh_name = "am35x_otg_hs"; -+ name = "musb-am35x"; -+ } else { -+ oh_name = "usb_otg_hs"; -+ name = "musb-omap2430"; -+ } -+ -+ oh = omap_hwmod_lookup(oh_name); -+ if (!oh) { -+ pr_err("Could not look up %s\n", oh_name); -+ return; -+ } -+ -+ od = omap_device_build(name, bus_id, oh, &musb_plat, -+ sizeof(musb_plat), omap_musb_latency, -+ ARRAY_SIZE(omap_musb_latency), false); -+ if (IS_ERR(od)) { -+ pr_err("Could not build omap_device for %s %s\n", -+ name, oh_name); -+ return; -+ } -+ -+ pdev = &od->pdev; -+ dev = &pdev->dev; -+ get_device(dev); -+ dev->dma_mask = &musb_dmamask; -+ dev->coherent_dma_mask = musb_dmamask; -+ put_device(dev); - } - - #else -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/common.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/common.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/common.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/common.c 2011-03-09 13:19:10.088501983 +0100 -@@ -24,10 +24,11 @@ - - #define NO_LENGTH_CHECK 0xffffffff - --struct omap_board_config_kernel *omap_board_config; -+struct omap_board_config_kernel *omap_board_config __initdata; - int omap_board_config_size; - --static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out) -+static const void *__init get_config(u16 tag, size_t len, -+ int skip, size_t *len_out) - { - struct omap_board_config_kernel *kinfo = NULL; - int i; -@@ -49,17 +50,15 @@ - return kinfo->data; - } - --const void *__omap_get_config(u16 tag, size_t len, int nr) -+const void *__init __omap_get_config(u16 tag, size_t len, int nr) - { - return get_config(tag, len, nr, NULL); - } --EXPORT_SYMBOL(__omap_get_config); - --const void *omap_get_var_config(u16 tag, size_t *len) -+const void *__init omap_get_var_config(u16 tag, size_t *len) - { - return get_config(tag, NO_LENGTH_CHECK, 0, len); - } --EXPORT_SYMBOL(omap_get_var_config); - - void __init omap_reserve(void) - { -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/counter_32k.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/counter_32k.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/counter_32k.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/counter_32k.c 2011-03-09 13:19:10.088501983 +0100 -@@ -54,7 +54,7 @@ - #define omap16xx_32k_read NULL - #endif - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - static cycle_t notrace omap2420_32k_read(struct clocksource *cs) - { - return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k; -@@ -63,7 +63,7 @@ - #define omap2420_32k_read NULL - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - static cycle_t notrace omap2430_32k_read(struct clocksource *cs) - { - return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k; -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/cpu-omap.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/cpu-omap.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/cpu-omap.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/cpu-omap.c 2011-03-09 13:19:10.088501983 +0100 -@@ -101,7 +101,7 @@ - return ret; - } - --static int __init omap_cpu_init(struct cpufreq_policy *policy) -+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy) - { - int result = 0; - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/devices.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/devices.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/devices.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/devices.c 2011-03-09 13:19:10.089501963 +0100 -@@ -35,8 +35,8 @@ - - static struct platform_device **omap_mcbsp_devices; - --void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, -- int size) -+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, -+ struct omap_mcbsp_platform_data *config, int size) - { - int i; - -@@ -54,6 +54,8 @@ - new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1); - if (!new_mcbsp) - continue; -+ platform_device_add_resources(new_mcbsp, &res[i * res_count], -+ res_count); - new_mcbsp->dev.platform_data = &config[i]; - ret = platform_device_add(new_mcbsp); - if (ret) { -@@ -65,8 +67,8 @@ - } - - #else --void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, -- int size) -+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, -+ struct omap_mcbsp_platform_data *config, int size) - { } - #endif - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/dma.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/dma.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/dma.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/dma.c 2011-03-09 13:19:10.090501943 +0100 -@@ -134,7 +134,7 @@ - - #ifdef CONFIG_ARCH_OMAP15XX - /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */ --int omap_dma_in_1510_mode(void) -+static int omap_dma_in_1510_mode(void) - { - return enable_1510_mode; - } -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/i2c.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/i2c.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/i2c.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/i2c.c 2011-03-09 13:19:10.091501922 +0100 -@@ -112,6 +112,7 @@ - } - - -+#ifdef CONFIG_ARCH_OMAP2PLUS - /* - * XXX This function is a temporary compatibility wrapper - only - * needed until the I2C driver can be converted to call -@@ -130,7 +131,6 @@ - }, - }; - --#ifdef CONFIG_ARCH_OMAP2PLUS - static inline int omap2_i2c_add_bus(int bus_id) - { - int l; -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/board.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/board.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/board.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/board.h 2011-03-09 13:19:10.092501901 +0100 -@@ -151,14 +151,14 @@ - const void *data; - }; - --extern const void *__omap_get_config(u16 tag, size_t len, int nr); -+extern const void *__init __omap_get_config(u16 tag, size_t len, int nr); - - #define omap_get_config(tag, type) \ - ((const type *) __omap_get_config((tag), sizeof(type), 0)) - #define omap_get_nr_config(tag, type, nr) \ - ((const type *) __omap_get_config((tag), sizeof(type), (nr))) - --extern const void *omap_get_var_config(u16 tag, size_t *len); -+extern const void *__init omap_get_var_config(u16 tag, size_t *len); - - extern struct omap_board_config_kernel *omap_board_config; - extern int omap_board_config_size; -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/clkdev_omap.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/clkdev_omap.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/clkdev_omap.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/clkdev_omap.h 2011-03-09 13:19:10.093501880 +0100 -@@ -38,6 +38,7 @@ - #define CK_3517 (1 << 9) - #define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */ - #define CK_443X (1 << 11) -+#define CK_TI816X (1 << 12) - - - #define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/clock.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/clock.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/clock.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/clock.h 2011-03-09 13:19:10.093501880 +0100 -@@ -53,6 +53,7 @@ - #define RATE_IN_3430ES2PLUS (1 << 3) /* 3430 ES >= 2 rates only */ - #define RATE_IN_36XX (1 << 4) - #define RATE_IN_4430 (1 << 5) -+#define RATE_IN_TI816X (1 << 6) - - #define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X) - #define RATE_IN_34XX (RATE_IN_3430ES1 | RATE_IN_3430ES2PLUS) -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/common.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/common.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/common.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/common.h 2011-03-09 13:19:10.093501880 +0100 -@@ -66,6 +66,7 @@ - void omap2_set_globals_243x(void); - void omap2_set_globals_3xxx(void); - void omap2_set_globals_443x(void); -+void omap2_set_globals_ti816x(void); - - /* These get called from omap2_set_globals_xxxx(), do not call these */ - void omap2_set_globals_tap(struct omap_globals *); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/cpu.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/cpu.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/cpu.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/cpu.h 2011-03-09 13:19:10.093501880 +0100 -@@ -5,7 +5,7 @@ - * - * Copyright (C) 2004, 2008 Nokia Corporation - * -- * Copyright (C) 2009 Texas Instruments. -+ * Copyright (C) 2009-11 Texas Instruments. - * - * Written by Tony Lindgren - * -@@ -105,6 +105,12 @@ - return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ - } - -+#define IS_TI_SUBCLASS(subclass, id) \ -+static inline int is_ti ##subclass (void) \ -+{ \ -+ return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0; \ -+} -+ - IS_OMAP_CLASS(7xx, 0x07) - IS_OMAP_CLASS(15xx, 0x15) - IS_OMAP_CLASS(16xx, 0x16) -@@ -118,6 +124,8 @@ - IS_OMAP_SUBCLASS(363x, 0x363) - IS_OMAP_SUBCLASS(443x, 0x443) - -+IS_TI_SUBCLASS(816x, 0x816) -+ - #define cpu_is_omap7xx() 0 - #define cpu_is_omap15xx() 0 - #define cpu_is_omap16xx() 0 -@@ -126,6 +134,7 @@ - #define cpu_is_omap243x() 0 - #define cpu_is_omap34xx() 0 - #define cpu_is_omap343x() 0 -+#define cpu_is_ti816x() 0 - #define cpu_is_omap44xx() 0 - #define cpu_is_omap443x() 0 - -@@ -170,11 +179,11 @@ - # undef cpu_is_omap24xx - # define cpu_is_omap24xx() is_omap24xx() - # endif --# if defined (CONFIG_ARCH_OMAP2420) -+# if defined (CONFIG_SOC_OMAP2420) - # undef cpu_is_omap242x - # define cpu_is_omap242x() is_omap242x() - # endif --# if defined (CONFIG_ARCH_OMAP2430) -+# if defined (CONFIG_SOC_OMAP2430) - # undef cpu_is_omap243x - # define cpu_is_omap243x() is_omap243x() - # endif -@@ -189,11 +198,11 @@ - # undef cpu_is_omap24xx - # define cpu_is_omap24xx() 1 - # endif --# if defined(CONFIG_ARCH_OMAP2420) -+# if defined(CONFIG_SOC_OMAP2420) - # undef cpu_is_omap242x - # define cpu_is_omap242x() 1 - # endif --# if defined(CONFIG_ARCH_OMAP2430) -+# if defined(CONFIG_SOC_OMAP2430) - # undef cpu_is_omap243x - # define cpu_is_omap243x() 1 - # endif -@@ -201,7 +210,7 @@ - # undef cpu_is_omap34xx - # define cpu_is_omap34xx() 1 - # endif --# if defined(CONFIG_ARCH_OMAP3430) -+# if defined(CONFIG_SOC_OMAP3430) - # undef cpu_is_omap343x - # define cpu_is_omap343x() 1 - # endif -@@ -330,6 +339,7 @@ - # undef cpu_is_omap3530 - # undef cpu_is_omap3505 - # undef cpu_is_omap3517 -+# undef cpu_is_ti816x - # define cpu_is_omap3430() is_omap3430() - # define cpu_is_omap3503() (cpu_is_omap3430() && \ - (!omap3_has_iva()) && \ -@@ -345,6 +355,7 @@ - # define cpu_is_omap3517() is_omap3517() - # undef cpu_is_omap3630 - # define cpu_is_omap3630() is_omap363x() -+# define cpu_is_ti816x() is_ti816x() - #endif - - # if defined(CONFIG_ARCH_OMAP4) -@@ -389,9 +400,15 @@ - #define OMAP3505_REV(v) (OMAP35XX_CLASS | (0x3505 << 16) | (v << 8)) - #define OMAP3517_REV(v) (OMAP35XX_CLASS | (0x3517 << 16) | (v << 8)) - -+#define TI816X_CLASS 0x81600034 -+#define TI8168_REV_ES1_0 TI816X_CLASS -+#define TI8168_REV_ES1_1 (TI816X_CLASS | (OMAP_REVBITS_01 << 8)) -+ - #define OMAP443X_CLASS 0x44300044 --#define OMAP4430_REV_ES1_0 OMAP443X_CLASS --#define OMAP4430_REV_ES2_0 0x44301044 -+#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) -+#define OMAP4430_REV_ES2_0 (OMAP443X_CLASS | (0x20 << 8)) -+#define OMAP4430_REV_ES2_1 (OMAP443X_CLASS | (0x21 << 8)) -+#define OMAP4430_REV_ES2_2 (OMAP443X_CLASS | (0x22 << 8)) - - /* - * omap_chip bits -@@ -419,11 +436,16 @@ - #define CHIP_IS_OMAP3630ES1_1 (1 << 9) - #define CHIP_IS_OMAP3630ES1_2 (1 << 10) - #define CHIP_IS_OMAP4430ES2 (1 << 11) -+#define CHIP_IS_OMAP4430ES2_1 (1 << 12) -+#define CHIP_IS_OMAP4430ES2_2 (1 << 13) -+#define CHIP_IS_TI816X (1 << 14) - - #define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430) - --#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \ -- CHIP_IS_OMAP4430ES2) -+#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \ -+ CHIP_IS_OMAP4430ES2 | \ -+ CHIP_IS_OMAP4430ES2_1 | \ -+ CHIP_IS_OMAP4430ES2_2) - - /* - * "GE" here represents "greater than or equal to" in terms of ES -@@ -455,6 +477,7 @@ - #define OMAP3_HAS_ISP BIT(4) - #define OMAP3_HAS_192MHZ_CLK BIT(5) - #define OMAP3_HAS_IO_WAKEUP BIT(6) -+#define OMAP3_HAS_SDRC BIT(7) - - #define OMAP3_HAS_FEATURE(feat,flag) \ - static inline unsigned int omap3_has_ ##feat(void) \ -@@ -469,5 +492,6 @@ - OMAP3_HAS_FEATURE(isp, ISP) - OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK) - OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP) -+OMAP3_HAS_FEATURE(sdrc, SDRC) - - #endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/display.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/display.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/display.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/display.h 2011-03-09 13:19:10.094501859 +0100 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - - #define DISPC_IRQ_FRAMEDONE (1 << 0) -@@ -226,6 +227,23 @@ - struct omap_dss_device *default_device; - }; - -+#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS) -+/* Init with the board info */ -+extern int omap_display_init(struct omap_dss_board_info *board_data); -+#else -+static inline int omap_display_init(struct omap_dss_board_info *board_data) -+{ -+ return 0; -+} -+#endif -+ -+struct omap_display_platform_data { -+ struct omap_dss_board_info *board_data; -+ /* TODO: Additional members to be added when PM is considered */ -+ -+ bool (*opt_clock_available)(const char *clk_role); -+}; -+ - struct omap_video_timings { - /* Unit: pixels */ - u16 x_res; -@@ -385,8 +403,8 @@ - struct { - u16 regn; - u16 regm; -- u16 regm3; -- u16 regm4; -+ u16 regm_dispc; -+ u16 regm_dsi; - - u16 lp_clk_div; - -@@ -544,6 +562,9 @@ - int channel, - u16 x, u16 y, u16 w, u16 h, - void (*callback)(int, void *), void *data); -+int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel); -+int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id); -+void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel); - - int omapdss_dsi_display_enable(struct omap_dss_device *dssdev); - void omapdss_dsi_display_disable(struct omap_dss_device *dssdev); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/dmtimer.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/dmtimer.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/dmtimer.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/dmtimer.h 2011-03-09 13:19:10.094501859 +0100 -@@ -3,6 +3,12 @@ - * - * OMAP Dual-Mode Timers - * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ -+ * Tarun Kanti DebBarma -+ * Thara Gopinath -+ * -+ * Platform device conversion and hwmod support. -+ * - * Copyright (C) 2005 Nokia Corporation - * Author: Lauri Leukkunen - * PWM and clock framwork support by Timo Teras. -@@ -44,6 +50,11 @@ - #define OMAP_TIMER_TRIGGER_OVERFLOW 0x01 - #define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02 - -+/* -+ * IP revision identifier so that Highlander IP -+ * in OMAP4 can be distinguished. -+ */ -+#define OMAP_TIMER_IP_VERSION_1 0x1 - struct omap_dm_timer; - extern struct omap_dm_timer *gptimer_wakeup; - extern struct sys_timer omap_timer; -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/fpga.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/fpga.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/fpga.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/fpga.h 2011-03-09 13:19:10.095501839 +0100 -@@ -30,18 +30,18 @@ - * --------------------------------------------------------------------------- - */ - /* maps in the FPGA registers and the ETHR registers */ --#define H2P2_DBG_FPGA_BASE IOMEM(0xE8000000) /* VA */ -+#define H2P2_DBG_FPGA_BASE 0xE8000000 /* VA */ - #define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */ - #define H2P2_DBG_FPGA_START 0x04000000 /* PA */ - - #define H2P2_DBG_FPGA_ETHR_START (H2P2_DBG_FPGA_START + 0x300) --#define H2P2_DBG_FPGA_FPGA_REV (H2P2_DBG_FPGA_BASE + 0x10) /* FPGA Revision */ --#define H2P2_DBG_FPGA_BOARD_REV (H2P2_DBG_FPGA_BASE + 0x12) /* Board Revision */ --#define H2P2_DBG_FPGA_GPIO (H2P2_DBG_FPGA_BASE + 0x14) /* GPIO outputs */ --#define H2P2_DBG_FPGA_LEDS (H2P2_DBG_FPGA_BASE + 0x16) /* LEDs outputs */ --#define H2P2_DBG_FPGA_MISC_INPUTS (H2P2_DBG_FPGA_BASE + 0x18) /* Misc inputs */ --#define H2P2_DBG_FPGA_LAN_STATUS (H2P2_DBG_FPGA_BASE + 0x1A) /* LAN Status line */ --#define H2P2_DBG_FPGA_LAN_RESET (H2P2_DBG_FPGA_BASE + 0x1C) /* LAN Reset line */ -+#define H2P2_DBG_FPGA_FPGA_REV IOMEM(H2P2_DBG_FPGA_BASE + 0x10) /* FPGA Revision */ -+#define H2P2_DBG_FPGA_BOARD_REV IOMEM(H2P2_DBG_FPGA_BASE + 0x12) /* Board Revision */ -+#define H2P2_DBG_FPGA_GPIO IOMEM(H2P2_DBG_FPGA_BASE + 0x14) /* GPIO outputs */ -+#define H2P2_DBG_FPGA_LEDS IOMEM(H2P2_DBG_FPGA_BASE + 0x16) /* LEDs outputs */ -+#define H2P2_DBG_FPGA_MISC_INPUTS IOMEM(H2P2_DBG_FPGA_BASE + 0x18) /* Misc inputs */ -+#define H2P2_DBG_FPGA_LAN_STATUS IOMEM(H2P2_DBG_FPGA_BASE + 0x1A) /* LAN Status line */ -+#define H2P2_DBG_FPGA_LAN_RESET IOMEM(H2P2_DBG_FPGA_BASE + 0x1C) /* LAN Reset line */ - - /* NOTE: most boards don't have a static mapping for the FPGA ... */ - struct h2p2_dbg_fpga { -@@ -81,55 +81,55 @@ - * OMAP-1510 FPGA - * --------------------------------------------------------------------------- - */ --#define OMAP1510_FPGA_BASE IOMEM(0xE8000000) /* VA */ -+#define OMAP1510_FPGA_BASE 0xE8000000 /* VA */ - #define OMAP1510_FPGA_SIZE SZ_4K - #define OMAP1510_FPGA_START 0x08000000 /* PA */ - - /* Revision */ --#define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0) --#define OMAP1510_FPGA_REV_HIGH (OMAP1510_FPGA_BASE + 0x1) -+#define OMAP1510_FPGA_REV_LOW IOMEM(OMAP1510_FPGA_BASE + 0x0) -+#define OMAP1510_FPGA_REV_HIGH IOMEM(OMAP1510_FPGA_BASE + 0x1) - --#define OMAP1510_FPGA_LCD_PANEL_CONTROL (OMAP1510_FPGA_BASE + 0x2) --#define OMAP1510_FPGA_LED_DIGIT (OMAP1510_FPGA_BASE + 0x3) --#define INNOVATOR_FPGA_HID_SPI (OMAP1510_FPGA_BASE + 0x4) --#define OMAP1510_FPGA_POWER (OMAP1510_FPGA_BASE + 0x5) -+#define OMAP1510_FPGA_LCD_PANEL_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x2) -+#define OMAP1510_FPGA_LED_DIGIT IOMEM(OMAP1510_FPGA_BASE + 0x3) -+#define INNOVATOR_FPGA_HID_SPI IOMEM(OMAP1510_FPGA_BASE + 0x4) -+#define OMAP1510_FPGA_POWER IOMEM(OMAP1510_FPGA_BASE + 0x5) - - /* Interrupt status */ --#define OMAP1510_FPGA_ISR_LO (OMAP1510_FPGA_BASE + 0x6) --#define OMAP1510_FPGA_ISR_HI (OMAP1510_FPGA_BASE + 0x7) -+#define OMAP1510_FPGA_ISR_LO IOMEM(OMAP1510_FPGA_BASE + 0x6) -+#define OMAP1510_FPGA_ISR_HI IOMEM(OMAP1510_FPGA_BASE + 0x7) - - /* Interrupt mask */ --#define OMAP1510_FPGA_IMR_LO (OMAP1510_FPGA_BASE + 0x8) --#define OMAP1510_FPGA_IMR_HI (OMAP1510_FPGA_BASE + 0x9) -+#define OMAP1510_FPGA_IMR_LO IOMEM(OMAP1510_FPGA_BASE + 0x8) -+#define OMAP1510_FPGA_IMR_HI IOMEM(OMAP1510_FPGA_BASE + 0x9) - - /* Reset registers */ --#define OMAP1510_FPGA_HOST_RESET (OMAP1510_FPGA_BASE + 0xa) --#define OMAP1510_FPGA_RST (OMAP1510_FPGA_BASE + 0xb) -+#define OMAP1510_FPGA_HOST_RESET IOMEM(OMAP1510_FPGA_BASE + 0xa) -+#define OMAP1510_FPGA_RST IOMEM(OMAP1510_FPGA_BASE + 0xb) - --#define OMAP1510_FPGA_AUDIO (OMAP1510_FPGA_BASE + 0xc) --#define OMAP1510_FPGA_DIP (OMAP1510_FPGA_BASE + 0xe) --#define OMAP1510_FPGA_FPGA_IO (OMAP1510_FPGA_BASE + 0xf) --#define OMAP1510_FPGA_UART1 (OMAP1510_FPGA_BASE + 0x14) --#define OMAP1510_FPGA_UART2 (OMAP1510_FPGA_BASE + 0x15) --#define OMAP1510_FPGA_OMAP1510_STATUS (OMAP1510_FPGA_BASE + 0x16) --#define OMAP1510_FPGA_BOARD_REV (OMAP1510_FPGA_BASE + 0x18) --#define OMAP1510P1_PPT_DATA (OMAP1510_FPGA_BASE + 0x100) --#define OMAP1510P1_PPT_STATUS (OMAP1510_FPGA_BASE + 0x101) --#define OMAP1510P1_PPT_CONTROL (OMAP1510_FPGA_BASE + 0x102) -- --#define OMAP1510_FPGA_TOUCHSCREEN (OMAP1510_FPGA_BASE + 0x204) -- --#define INNOVATOR_FPGA_INFO (OMAP1510_FPGA_BASE + 0x205) --#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510_FPGA_BASE + 0x206) --#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510_FPGA_BASE + 0x207) --#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510_FPGA_BASE + 0x208) --#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510_FPGA_BASE + 0x209) --#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510_FPGA_BASE + 0x20a) --#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510_FPGA_BASE + 0x20b) --#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510_FPGA_BASE + 0x20c) --#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510_FPGA_BASE + 0x20d) --#define INNOVATOR_FPGA_ISR2 (OMAP1510_FPGA_BASE + 0x20e) --#define INNOVATOR_FPGA_IMR2 (OMAP1510_FPGA_BASE + 0x210) -+#define OMAP1510_FPGA_AUDIO IOMEM(OMAP1510_FPGA_BASE + 0xc) -+#define OMAP1510_FPGA_DIP IOMEM(OMAP1510_FPGA_BASE + 0xe) -+#define OMAP1510_FPGA_FPGA_IO IOMEM(OMAP1510_FPGA_BASE + 0xf) -+#define OMAP1510_FPGA_UART1 IOMEM(OMAP1510_FPGA_BASE + 0x14) -+#define OMAP1510_FPGA_UART2 IOMEM(OMAP1510_FPGA_BASE + 0x15) -+#define OMAP1510_FPGA_OMAP1510_STATUS IOMEM(OMAP1510_FPGA_BASE + 0x16) -+#define OMAP1510_FPGA_BOARD_REV IOMEM(OMAP1510_FPGA_BASE + 0x18) -+#define OMAP1510P1_PPT_DATA IOMEM(OMAP1510_FPGA_BASE + 0x100) -+#define OMAP1510P1_PPT_STATUS IOMEM(OMAP1510_FPGA_BASE + 0x101) -+#define OMAP1510P1_PPT_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x102) -+ -+#define OMAP1510_FPGA_TOUCHSCREEN IOMEM(OMAP1510_FPGA_BASE + 0x204) -+ -+#define INNOVATOR_FPGA_INFO IOMEM(OMAP1510_FPGA_BASE + 0x205) -+#define INNOVATOR_FPGA_LCD_BRIGHT_LO IOMEM(OMAP1510_FPGA_BASE + 0x206) -+#define INNOVATOR_FPGA_LCD_BRIGHT_HI IOMEM(OMAP1510_FPGA_BASE + 0x207) -+#define INNOVATOR_FPGA_LED_GRN_LO IOMEM(OMAP1510_FPGA_BASE + 0x208) -+#define INNOVATOR_FPGA_LED_GRN_HI IOMEM(OMAP1510_FPGA_BASE + 0x209) -+#define INNOVATOR_FPGA_LED_RED_LO IOMEM(OMAP1510_FPGA_BASE + 0x20a) -+#define INNOVATOR_FPGA_LED_RED_HI IOMEM(OMAP1510_FPGA_BASE + 0x20b) -+#define INNOVATOR_FPGA_CAM_USB_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x20c) -+#define INNOVATOR_FPGA_EXP_CONTROL IOMEM(OMAP1510_FPGA_BASE + 0x20d) -+#define INNOVATOR_FPGA_ISR2 IOMEM(OMAP1510_FPGA_BASE + 0x20e) -+#define INNOVATOR_FPGA_IMR2 IOMEM(OMAP1510_FPGA_BASE + 0x210) - - #define OMAP1510_FPGA_ETHR_START (OMAP1510_FPGA_START + 0x300) - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/gpmc.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/gpmc.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/gpmc.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/gpmc.h 2011-03-09 13:19:10.095501839 +0100 -@@ -41,6 +41,8 @@ - #define GPMC_NAND_ADDRESS 0x0000000b - #define GPMC_NAND_DATA 0x0000000c - -+#define GPMC_ENABLE_IRQ 0x0000000d -+ - /* ECC commands */ - #define GPMC_ECC_READ 0 /* Reset Hardware ECC for read */ - #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */ -@@ -78,6 +80,19 @@ - #define WR_RD_PIN_MONITORING 0x00600000 - #define GPMC_PREFETCH_STATUS_FIFO_CNT(val) ((val >> 24) & 0x7F) - #define GPMC_PREFETCH_STATUS_COUNT(val) (val & 0x00003fff) -+#define GPMC_IRQ_FIFOEVENTENABLE 0x01 -+#define GPMC_IRQ_COUNT_EVENT 0x02 -+ -+#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 -+#define PREFETCH_FIFOTHRESHOLD(val) ((val) << 8) -+ -+enum omap_ecc { -+ /* 1-bit ecc: stored at end of spare area */ -+ OMAP_ECC_HAMMING_CODE_DEFAULT = 0, /* Default, s/w method */ -+ OMAP_ECC_HAMMING_CODE_HW, /* gpmc to detect the error */ -+ /* 1-bit ecc: stored at begining of spare area as romcode */ -+ OMAP_ECC_HAMMING_CODE_HW_ROMCODE, /* gpmc method & romcode layout */ -+}; - - /* - * Note that all values in this struct are in nanoseconds except sync_clk -@@ -130,12 +145,11 @@ - extern void gpmc_cs_free(int cs); - extern int gpmc_cs_set_reserved(int cs, int reserved); - extern int gpmc_cs_reserved(int cs); --extern int gpmc_prefetch_enable(int cs, int dma_mode, -+extern int gpmc_prefetch_enable(int cs, int fifo_th, int dma_mode, - unsigned int u32_count, int is_write); - extern int gpmc_prefetch_reset(int cs); - extern void omap3_gpmc_save_context(void); - extern void omap3_gpmc_restore_context(void); --extern void gpmc_init(void); - extern int gpmc_read_status(int cmd); - extern int gpmc_cs_configure(int cs, int cmd, int wval); - extern int gpmc_nand_read(int cs, int cmd); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/hardware.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/hardware.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/hardware.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/hardware.h 2011-03-09 13:19:10.096501820 +0100 -@@ -286,5 +286,6 @@ - #include - #include - #include -+#include - - #endif /* __ASM_ARCH_OMAP_HARDWARE_H */ -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/io.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/io.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/io.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/io.h 2011-03-09 13:19:10.096501820 +0100 -@@ -259,7 +259,7 @@ - extern void omap1_map_common_io(void); - extern void omap1_init_common_hw(void); - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - extern void omap242x_map_common_io(void); - #else - static inline void omap242x_map_common_io(void) -@@ -267,7 +267,7 @@ - } - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - extern void omap243x_map_common_io(void); - #else - static inline void omap243x_map_common_io(void) -@@ -283,6 +283,14 @@ - } - #endif - -+#ifdef CONFIG_SOC_OMAPTI816X -+extern void omapti816x_map_common_io(void); -+#else -+static inline void omapti816x_map_common_io(void) -+{ -+} -+#endif -+ - #ifdef CONFIG_ARCH_OMAP4 - extern void omap44xx_map_common_io(void); - #else -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/iommu.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/iommu.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/iommu.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/iommu.h 2011-03-09 13:19:10.096501820 +0100 -@@ -31,6 +31,7 @@ - struct clk *clk; - void __iomem *regbase; - struct device *dev; -+ void *isr_priv; - - unsigned int refcount; - struct mutex iommu_lock; /* global for this whole object */ -@@ -47,7 +48,7 @@ - struct list_head mmap; - struct mutex mmap_lock; /* protect mmap */ - -- int (*isr)(struct iommu *obj); -+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, void *priv); - - void *ctx; /* iommu context: registres saved area */ - u32 da_start; -@@ -109,6 +110,13 @@ - u32 da_end; - }; - -+/* IOMMU errors */ -+#define OMAP_IOMMU_ERR_TLB_MISS (1 << 0) -+#define OMAP_IOMMU_ERR_TRANS_FAULT (1 << 1) -+#define OMAP_IOMMU_ERR_EMU_MISS (1 << 2) -+#define OMAP_IOMMU_ERR_TBLWALK_FAULT (1 << 3) -+#define OMAP_IOMMU_ERR_MULTIHIT_FAULT (1 << 4) -+ - #if defined(CONFIG_ARCH_OMAP1) - #error "iommu for this processor not implemented yet" - #else -@@ -154,11 +162,17 @@ - extern void flush_iotlb_all(struct iommu *obj); - - extern int iopgtable_store_entry(struct iommu *obj, struct iotlb_entry *e); -+extern void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, -+ u32 **ppte); - extern size_t iopgtable_clear_entry(struct iommu *obj, u32 iova); - - extern int iommu_set_da_range(struct iommu *obj, u32 start, u32 end); - extern struct iommu *iommu_get(const char *name); - extern void iommu_put(struct iommu *obj); -+extern int iommu_set_isr(const char *name, -+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, -+ void *priv), -+ void *isr_priv); - - extern void iommu_save_ctx(struct iommu *obj); - extern void iommu_restore_ctx(struct iommu *obj); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/irqs.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/irqs.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/irqs.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/irqs.h 2011-03-09 13:19:10.097501800 +0100 -@@ -318,6 +318,7 @@ - #define INT_34XX_PRCM_MPU_IRQ 11 - #define INT_34XX_MCBSP1_IRQ 16 - #define INT_34XX_MCBSP2_IRQ 17 -+#define INT_34XX_GPMC_IRQ 20 - #define INT_34XX_MCBSP3_IRQ 22 - #define INT_34XX_MCBSP4_IRQ 23 - #define INT_34XX_CAM_IRQ 24 -@@ -411,7 +412,13 @@ - #define TWL_IRQ_END TWL6030_IRQ_END - #endif - --#define NR_IRQS TWL_IRQ_END -+/* GPMC related */ -+#define OMAP_GPMC_IRQ_BASE (TWL_IRQ_END) -+#define OMAP_GPMC_NR_IRQS 7 -+#define OMAP_GPMC_IRQ_END (OMAP_GPMC_IRQ_BASE + OMAP_GPMC_NR_IRQS) -+ -+ -+#define NR_IRQS OMAP_GPMC_IRQ_END - - #define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32)) - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l3_2xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l3_2xxx.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l3_2xxx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l3_2xxx.h 2011-03-09 13:19:10.097501800 +0100 -@@ -0,0 +1,20 @@ -+/* -+ * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ -+ * Sumit Semwal -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H -+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H -+ -+/* L3 CONNIDs */ -+/* Display Sub system (DSS) */ -+#define OMAP2_L3_CORE_FW_CONNID_DSS 8 -+ -+#endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l3_3xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l3_3xxx.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l3_3xxx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l3_3xxx.h 2011-03-09 13:19:10.098501780 +0100 -@@ -0,0 +1,20 @@ -+/* -+ * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ -+ * Sumit Semwal -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H -+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H -+ -+/* L3 Initiator IDs */ -+/* Display Sub system (DSS) */ -+#define OMAP3_L3_CORE_FW_INIT_ID_DSS 29 -+ -+#endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l4_2xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l4_2xxx.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l4_2xxx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l4_2xxx.h 2011-03-09 13:19:10.098501780 +0100 -@@ -0,0 +1,24 @@ -+/* -+ * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ -+ * Sumit Semwal -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ */ -+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H -+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H -+ -+/* L4 CORE */ -+/* Display Sub system (DSS) */ -+#define OMAP2420_L4_CORE_FW_DSS_CORE_REGION 28 -+#define OMAP2420_L4_CORE_FW_DSS_DISPC_REGION 29 -+#define OMAP2420_L4_CORE_FW_DSS_RFBI_REGION 30 -+#define OMAP2420_L4_CORE_FW_DSS_VENC_REGION 31 -+#define OMAP2420_L4_CORE_FW_DSS_TA_REGION 32 -+ -+#endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l4_3xxx.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l4_3xxx.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/l4_3xxx.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/l4_3xxx.h 2011-03-09 13:19:10.098501780 +0100 -@@ -21,4 +21,14 @@ - #define OMAP3_L4_CORE_FW_I2C3_REGION 73 - #define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74 - -+/* Display Sub system (DSS) */ -+#define OMAP3_L4_CORE_FW_DSS_PROT_GROUP 2 -+ -+#define OMAP3_L4_CORE_FW_DSS_DSI_REGION 104 -+#define OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION 3 -+#define OMAP3_L4_CORE_FW_DSS_CORE_REGION 4 -+#define OMAP3_L4_CORE_FW_DSS_DISPC_REGION 4 -+#define OMAP3_L4_CORE_FW_DSS_RFBI_REGION 5 -+#define OMAP3_L4_CORE_FW_DSS_VENC_REGION 6 -+#define OMAP3_L4_CORE_FW_DSS_TA_REGION 7 - #endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mcbsp.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mcbsp.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mcbsp.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mcbsp.h 2011-03-09 13:19:10.098501780 +0100 -@@ -37,6 +37,10 @@ - .id = OMAP_MCBSP##port_nr, \ - } - -+#define MCBSP_CONFIG_TYPE2 0x2 -+#define MCBSP_CONFIG_TYPE3 0x3 -+#define MCBSP_CONFIG_TYPE4 0x4 -+ - #define OMAP7XX_MCBSP1_BASE 0xfffb1000 - #define OMAP7XX_MCBSP2_BASE 0xfffb1800 - -@@ -48,32 +52,14 @@ - #define OMAP1610_MCBSP2_BASE 0xfffb1000 - #define OMAP1610_MCBSP3_BASE 0xe1017000 - --#define OMAP24XX_MCBSP1_BASE 0x48074000 --#define OMAP24XX_MCBSP2_BASE 0x48076000 --#define OMAP2430_MCBSP3_BASE 0x4808c000 --#define OMAP2430_MCBSP4_BASE 0x4808e000 --#define OMAP2430_MCBSP5_BASE 0x48096000 -- --#define OMAP34XX_MCBSP1_BASE 0x48074000 --#define OMAP34XX_MCBSP2_BASE 0x49022000 --#define OMAP34XX_MCBSP2_ST_BASE 0x49028000 --#define OMAP34XX_MCBSP3_BASE 0x49024000 --#define OMAP34XX_MCBSP3_ST_BASE 0x4902A000 --#define OMAP34XX_MCBSP3_BASE 0x49024000 --#define OMAP34XX_MCBSP4_BASE 0x49026000 --#define OMAP34XX_MCBSP5_BASE 0x48096000 -- --#define OMAP44XX_MCBSP1_BASE 0x49022000 --#define OMAP44XX_MCBSP2_BASE 0x49024000 --#define OMAP44XX_MCBSP3_BASE 0x49026000 --#define OMAP44XX_MCBSP4_BASE 0x48096000 -- --#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) -+#ifdef CONFIG_ARCH_OMAP1 - - #define OMAP_MCBSP_REG_DRR2 0x00 - #define OMAP_MCBSP_REG_DRR1 0x02 - #define OMAP_MCBSP_REG_DXR2 0x04 - #define OMAP_MCBSP_REG_DXR1 0x06 -+#define OMAP_MCBSP_REG_DRR 0x02 -+#define OMAP_MCBSP_REG_DXR 0x06 - #define OMAP_MCBSP_REG_SPCR2 0x08 - #define OMAP_MCBSP_REG_SPCR1 0x0a - #define OMAP_MCBSP_REG_RCR2 0x0c -@@ -106,13 +92,6 @@ - #define OMAP_MCBSP_REG_XCCR 0x00 - #define OMAP_MCBSP_REG_RCCR 0x00 - --#define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1) --#define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1) -- --#define AUDIO_MCBSP OMAP_MCBSP1 --#define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX --#define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX -- - #else - - #define OMAP_MCBSP_REG_DRR2 0x00 -@@ -168,13 +147,6 @@ - #define OMAP_ST_REG_SFIRCR 0x28 - #define OMAP_ST_REG_SSELCR 0x2C - --#define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1) --#define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1) -- --#define AUDIO_MCBSP OMAP_MCBSP2 --#define AUDIO_DMA_TX OMAP24XX_DMA_MCBSP2_TX --#define AUDIO_DMA_RX OMAP24XX_DMA_MCBSP2_RX -- - #endif - - /************************** McBSP SPCR1 bit definitions ***********************/ -@@ -428,8 +400,9 @@ - #ifdef CONFIG_ARCH_OMAP3 - /* Sidetone block for McBSP 2 and 3 */ - unsigned long phys_base_st; -- u16 buffer_size; - #endif -+ u16 buffer_size; -+ unsigned int mcbsp_config_type; - }; - - struct omap_mcbsp_st_data { -@@ -445,6 +418,7 @@ - struct omap_mcbsp { - struct device *dev; - unsigned long phys_base; -+ unsigned long phys_dma_base; - void __iomem *io_base; - u8 id; - u8 free; -@@ -471,7 +445,6 @@ - /* Protect the field .free, while checking if the mcbsp is in use */ - spinlock_t lock; - struct omap_mcbsp_platform_data *pdata; -- struct clk *iclk; - struct clk *fclk; - #ifdef CONFIG_ARCH_OMAP3 - struct omap_mcbsp_st_data *st_data; -@@ -480,7 +453,17 @@ - u16 max_rx_thres; - #endif - void *reg_cache; -+ unsigned int mcbsp_config_type; -+}; -+ -+/** -+ * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod -+ * @sidetone: name of the sidetone device -+ */ -+struct omap_mcbsp_dev_attr { -+ const char *sidetone; - }; -+ - extern struct omap_mcbsp **mcbsp_ptr; - extern int omap_mcbsp_count, omap_mcbsp_cache_size; - -@@ -488,8 +471,8 @@ - #define id_to_mcbsp_ptr(id) mcbsp_ptr[id]; - - int omap_mcbsp_init(void); --void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, -- int size); -+void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, -+ struct omap_mcbsp_platform_data *config, int size); - void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); - #ifdef CONFIG_ARCH_OMAP3 - void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold); -@@ -539,6 +522,9 @@ - void omap2_mcbsp1_mux_clkr_src(u8 mux); - void omap2_mcbsp1_mux_fsr_src(u8 mux); - -+int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream); -+int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream); -+ - #ifdef CONFIG_ARCH_OMAP3 - /* Sidetone specific API */ - int omap_st_set_chgain(unsigned int id, int channel, s16 chgain); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mcspi.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mcspi.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mcspi.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mcspi.h 2011-03-09 13:19:10.098501780 +0100 -@@ -1,8 +1,19 @@ - #ifndef _OMAP2_MCSPI_H - #define _OMAP2_MCSPI_H - -+#define OMAP2_MCSPI_REV 0 -+#define OMAP3_MCSPI_REV 1 -+#define OMAP4_MCSPI_REV 2 -+ -+#define OMAP4_MCSPI_REG_OFFSET 0x100 -+ - struct omap2_mcspi_platform_config { - unsigned short num_cs; -+ unsigned int regs_offset; -+}; -+ -+struct omap2_mcspi_dev_attr { -+ unsigned short num_chipselect; - }; - - struct omap2_mcspi_device_config { -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mmc.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mmc.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/mmc.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/mmc.h 2011-03-09 13:19:10.099501760 +0100 -@@ -24,25 +24,19 @@ - #define OMAP1_MMC2_BASE 0xfffb7c00 /* omap16xx only */ - - #define OMAP24XX_NR_MMC 2 --#define OMAP34XX_NR_MMC 3 --#define OMAP44XX_NR_MMC 5 - #define OMAP2420_MMC_SIZE OMAP1_MMC_SIZE --#define OMAP3_HSMMC_SIZE 0x200 --#define OMAP4_HSMMC_SIZE 0x1000 - #define OMAP2_MMC1_BASE 0x4809c000 --#define OMAP2_MMC2_BASE 0x480b4000 --#define OMAP3_MMC3_BASE 0x480ad000 --#define OMAP4_MMC4_BASE 0x480d1000 --#define OMAP4_MMC5_BASE 0x480d5000 -+ - #define OMAP4_MMC_REG_OFFSET 0x100 --#define HSMMC5 (1 << 4) --#define HSMMC4 (1 << 3) --#define HSMMC3 (1 << 2) --#define HSMMC2 (1 << 1) --#define HSMMC1 (1 << 0) - - #define OMAP_MMC_MAX_SLOTS 2 - -+#define OMAP_HSMMC_SUPPORTS_DUAL_VOLT BIT(1) -+ -+struct omap_mmc_dev_attr { -+ u8 flags; -+}; -+ - struct omap_mmc_platform_data { - /* back-link to device */ - struct device *dev; -@@ -71,6 +65,9 @@ - - u64 dma_mask; - -+ /* Integrating attributes from the omap_hwmod layer */ -+ u8 controller_flags; -+ - /* Register offset deviation */ - u16 reg_offset; - -@@ -159,8 +156,7 @@ - defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) - void omap1_init_mmc(struct omap_mmc_platform_data **mmc_data, - int nr_controllers); --void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, -- int nr_controllers); -+void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data); - int omap_mmc_add(const char *name, int id, unsigned long base, - unsigned long size, unsigned int irq, - struct omap_mmc_platform_data *data); -@@ -169,8 +165,7 @@ - int nr_controllers) - { - } --static inline void omap2_init_mmc(struct omap_mmc_platform_data **mmc_data, -- int nr_controllers) -+static inline void omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data) - { - } - static inline int omap_mmc_add(const char *name, int id, unsigned long base, -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/multi.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/multi.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/multi.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/multi.h 2011-03-09 13:19:10.099501760 +0100 -@@ -66,7 +66,7 @@ - # error "OMAP1 and OMAP2PLUS can't be selected at the same time" - # endif - #endif --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - # ifdef OMAP_NAME - # undef MULTI_OMAP2 - # define MULTI_OMAP2 -@@ -74,7 +74,7 @@ - # define OMAP_NAME omap2420 - # endif - #endif --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - # ifdef OMAP_NAME - # undef MULTI_OMAP2 - # define MULTI_OMAP2 -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/nand.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/nand.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/nand.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/nand.h 2011-03-09 13:19:10.100501740 +0100 -@@ -8,8 +8,16 @@ - * published by the Free Software Foundation. - */ - -+#include - #include - -+enum nand_io { -+ NAND_OMAP_PREFETCH_POLLED = 0, /* prefetch polled mode, default */ -+ NAND_OMAP_POLLED, /* polled mode, without prefetch */ -+ NAND_OMAP_PREFETCH_DMA, /* prefetch enabled sDMA mode */ -+ NAND_OMAP_PREFETCH_IRQ /* prefetch enabled irq mode */ -+}; -+ - struct omap_nand_platform_data { - unsigned int options; - int cs; -@@ -20,8 +28,11 @@ - int (*nand_setup)(void); - int (*dev_ready)(struct omap_nand_platform_data *); - int dma_channel; -+ int gpmc_irq; -+ enum nand_io xfer_type; - unsigned long phys_base; - int devsize; -+ enum omap_ecc ecc_opt; - }; - - /* minimum size for IO mapping */ -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/omap_hwmod.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/omap_hwmod.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/omap_hwmod.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/omap_hwmod.h 2011-03-09 13:19:10.102501700 +0100 -@@ -1,7 +1,7 @@ - /* - * omap_hwmod macros, structures - * -- * Copyright (C) 2009-2010 Nokia Corporation -+ * Copyright (C) 2009-2011 Nokia Corporation - * Paul Walmsley - * - * Created in collaboration with (alphabetical order): Benoît Cousson, -@@ -30,6 +30,7 @@ - #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_HWMOD_H - - #include -+#include - #include - #include - #include -@@ -178,7 +179,8 @@ - #define ADDR_TYPE_RT (1 << 1) - - /** -- * struct omap_hwmod_addr_space - MPU address space handled by the hwmod -+ * struct omap_hwmod_addr_space - address space handled by the hwmod -+ * @name: name of the address space - * @pa_start: starting physical address - * @pa_end: ending physical address - * @flags: (see omap_hwmod_addr_space.flags macros above) -@@ -187,6 +189,7 @@ - * structure. GPMC is one example. - */ - struct omap_hwmod_addr_space { -+ const char *name; - u32 pa_start; - u32 pa_end; - u8 flags; -@@ -370,8 +373,10 @@ - * of standby, rather than relying on module smart-standby - * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for - * SDRAM controller, etc. XXX probably belongs outside the main hwmod file -+ * XXX Should be HWMOD_SETUP_NO_RESET - * HWMOD_INIT_NO_IDLE: don't idle this module at boot - important for SDRAM - * controller, etc. XXX probably belongs outside the main hwmod file -+ * XXX Should be HWMOD_SETUP_NO_IDLE - * HWMOD_NO_AUTOIDLE: disable module autoidle (OCP_SYSCONFIG.AUTOIDLE) - * when module is enabled, rather than the default, which is to - * enable autoidle -@@ -535,11 +540,12 @@ - const struct omap_chip_id omap_chip; - }; - --int omap_hwmod_init(struct omap_hwmod **ohs); -+int omap_hwmod_register(struct omap_hwmod **ohs); - struct omap_hwmod *omap_hwmod_lookup(const char *name); - int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data), - void *data); --int omap_hwmod_late_init(void); -+ -+int __init omap_hwmod_setup_one(const char *name); - - int omap_hwmod_enable(struct omap_hwmod *oh); - int _omap_hwmod_enable(struct omap_hwmod *oh); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/onenand.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/onenand.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/onenand.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/onenand.h 2011-03-09 13:19:10.102501700 +0100 -@@ -15,12 +15,20 @@ - #define ONENAND_SYNC_READ (1 << 0) - #define ONENAND_SYNC_READWRITE (1 << 1) - -+struct onenand_freq_info { -+ u16 maf_id; -+ u16 dev_id; -+ u16 ver_id; -+}; -+ - struct omap_onenand_platform_data { - int cs; - int gpio_irq; - struct mtd_partition *parts; - int nr_parts; -- int (*onenand_setup)(void __iomem *, int freq); -+ int (*onenand_setup)(void __iomem *, int *freq_ptr); -+ int (*get_freq)(const struct onenand_freq_info *freq_info, -+ bool *clk_dep); - int dma_channel; - u8 flags; - u8 regulator_can_sleep; -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/prcm.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/prcm.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/prcm.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/prcm.h 2011-03-09 13:19:10.102501700 +0100 -@@ -28,7 +28,6 @@ - #define __ASM_ARM_ARCH_OMAP_PRCM_H - - u32 omap_prcm_get_reset_sources(void); --void omap_prcm_arch_reset(char mode, const char *cmd); - int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, u8 idlest, - const char *name); - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/sdrc.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/sdrc.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/sdrc.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/sdrc.h 2011-03-09 13:19:10.102501700 +0100 -@@ -124,8 +124,14 @@ - u32 mr; - }; - --void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, -+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) -+void omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, - struct omap_sdrc_params *sdrc_cs1); -+#else -+static inline void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0, -+ struct omap_sdrc_params *sdrc_cs1) {}; -+#endif -+ - int omap2_sdrc_get_params(unsigned long r, - struct omap_sdrc_params **sdrc_cs0, - struct omap_sdrc_params **sdrc_cs1); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/serial.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/serial.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/serial.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/serial.h 2011-03-09 13:19:10.103501679 +0100 -@@ -51,6 +51,11 @@ - #define OMAP4_UART3_BASE 0x48020000 - #define OMAP4_UART4_BASE 0x4806e000 - -+/* TI816X serial ports */ -+#define TI816X_UART1_BASE 0x48020000 -+#define TI816X_UART2_BASE 0x48022000 -+#define TI816X_UART3_BASE 0x48024000 -+ - /* External port on Zoom2/3 */ - #define ZOOM_UART_BASE 0x10000000 - #define ZOOM_UART_VIRT 0xfa400000 -@@ -81,6 +86,9 @@ - #define OMAP4UART2 OMAP2UART2 - #define OMAP4UART3 43 - #define OMAP4UART4 44 -+#define TI816XUART1 81 -+#define TI816XUART2 82 -+#define TI816XUART3 83 - #define ZOOM_UART 95 /* Only on zoom2/3 */ - - /* This is only used by 8250.c for omap1510 */ -@@ -96,7 +104,6 @@ - - struct omap_board_data; - --extern void __init omap_serial_early_init(void); - extern void omap_serial_init(void); - extern void omap_serial_init_port(struct omap_board_data *bdata); - extern int omap_uart_can_sleep(void); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/system.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/system.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/system.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/system.h 2011-03-09 13:19:10.103501679 +0100 -@@ -4,48 +4,14 @@ - */ - #ifndef __ASM_ARCH_SYSTEM_H - #define __ASM_ARCH_SYSTEM_H --#include - --#include --#include -- --#include -- --#ifndef CONFIG_MACH_VOICEBLUE --#define voiceblue_reset() do {} while (0) --#else --extern void voiceblue_reset(void); --#endif -+#include - - static inline void arch_idle(void) - { - cpu_do_idle(); - } - --static inline void omap1_arch_reset(char mode, const char *cmd) --{ -- /* -- * Workaround for 5912/1611b bug mentioned in sprz209d.pdf p. 28 -- * "Global Software Reset Affects Traffic Controller Frequency". -- */ -- if (cpu_is_omap5912()) { -- omap_writew(omap_readw(DPLL_CTL) & ~(1 << 4), -- DPLL_CTL); -- omap_writew(0x8, ARM_RSTCT1); -- } -- -- if (machine_is_voiceblue()) -- voiceblue_reset(); -- else -- omap_writew(1, ARM_RSTCT1); --} -- --static inline void arch_reset(char mode, const char *cmd) --{ -- if (!cpu_class_is_omap2()) -- omap1_arch_reset(mode, cmd); -- else -- omap_prcm_arch_reset(mode, cmd); --} -+extern void (*arch_reset)(char, const char *); - - #endif -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/ti816x.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/ti816x.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/ti816x.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/ti816x.h 2011-03-09 13:19:10.103501679 +0100 -@@ -0,0 +1,27 @@ -+/* -+ * This file contains the address data for various TI816X modules. -+ * -+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.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 version 2. -+ * -+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any -+ * kind, whether express or implied; without even the implied warranty -+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __ASM_ARCH_TI816X_H -+#define __ASM_ARCH_TI816X_H -+ -+#define L4_SLOW_TI816X_BASE 0x48000000 -+ -+#define TI816X_SCM_BASE 0x48140000 -+#define TI816X_CTRL_BASE TI816X_SCM_BASE -+#define TI816X_PRCM_BASE 0x48180000 -+ -+#define TI816X_ARM_INTC_BASE 0x48200000 -+ -+#endif /* __ASM_ARCH_TI816X_H */ -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/uncompress.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/uncompress.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/uncompress.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/uncompress.h 2011-03-09 13:19:10.104501658 +0100 -@@ -93,6 +93,10 @@ - #define DEBUG_LL_ZOOM(mach) \ - _DEBUG_LL_ENTRY(mach, ZOOM_UART_BASE, ZOOM_PORT_SHIFT, ZOOM_UART) - -+#define DEBUG_LL_TI816X(p, mach) \ -+ _DEBUG_LL_ENTRY(mach, TI816X_UART##p##_BASE, OMAP_PORT_SHIFT, \ -+ TI816XUART##p) -+ - static inline void __arch_decomp_setup(unsigned long arch_id) - { - int port = 0; -@@ -166,6 +170,9 @@ - DEBUG_LL_ZOOM(omap_zoom2); - DEBUG_LL_ZOOM(omap_zoom3); - -+ /* TI8168 base boards using UART3 */ -+ DEBUG_LL_TI816X(3, ti8168evm); -+ - } while (0); - } - -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/usb.h linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/usb.h ---- linux-2.6.38-rc7/arch/arm/plat-omap/include/plat/usb.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/include/plat/usb.h 2011-03-09 13:19:10.104501658 +0100 -@@ -91,6 +91,10 @@ - - #endif - -+extern void am35x_musb_reset(void); -+extern void am35x_musb_phy_power(u8 on); -+extern void am35x_musb_clear_irq(void); -+extern void am35x_musb_set_mode(u8 musb_mode); - - /* - * FIXME correct answer depends on hmc_mode, -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/io.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/io.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/io.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/io.c 2011-03-09 13:19:10.104501658 +0100 -@@ -85,7 +85,10 @@ - } - #endif - #ifdef CONFIG_ARCH_OMAP3 -- if (cpu_is_omap34xx()) { -+ if (cpu_is_ti816x()) { -+ if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE)) -+ return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT); -+ } else if (cpu_is_omap34xx()) { - if (BETWEEN(p, L3_34XX_PHYS, L3_34XX_SIZE)) - return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT); - if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE)) -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/iommu.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/iommu.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/iommu.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/iommu.c 2011-03-09 13:19:10.105501637 +0100 -@@ -104,6 +104,9 @@ - if (!obj) - return -EINVAL; - -+ if (!arch_iommu) -+ return -ENODEV; -+ - clk_enable(obj->clk); - - err = arch_iommu->enable(obj); -@@ -780,25 +783,19 @@ - */ - static irqreturn_t iommu_fault_handler(int irq, void *data) - { -- u32 stat, da; -+ u32 da, errs; - u32 *iopgd, *iopte; -- int err = -EIO; - struct iommu *obj = data; - - if (!obj->refcount) - return IRQ_NONE; - -- /* Dynamic loading TLB or PTE */ -- if (obj->isr) -- err = obj->isr(obj); -- -- if (!err) -- return IRQ_HANDLED; -- - clk_enable(obj->clk); -- stat = iommu_report_fault(obj, &da); -+ errs = iommu_report_fault(obj, &da); - clk_disable(obj->clk); -- if (!stat) -+ -+ /* Fault callback or TLB/PTE Dynamic loading */ -+ if (obj->isr && !obj->isr(obj, da, errs, obj->isr_priv)) - return IRQ_HANDLED; - - iommu_disable(obj); -@@ -806,15 +803,16 @@ - iopgd = iopgd_offset(obj, da); - - if (!iopgd_is_table(*iopgd)) { -- dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__, -- da, iopgd, *iopgd); -+ dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p " -+ "*pgd:px%08x\n", obj->name, errs, da, iopgd, *iopgd); - return IRQ_NONE; - } - - iopte = iopte_offset(iopgd, da); - -- dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x pte:%p *pte:%08x\n", -- __func__, da, iopgd, *iopgd, iopte, *iopte); -+ dev_err(obj->dev, "%s: errs:0x%08x da:0x%08x pgd:0x%p *pgd:0x%08x " -+ "pte:0x%p *pte:0x%08x\n", obj->name, errs, da, iopgd, *iopgd, -+ iopte, *iopte); - - return IRQ_NONE; - } -@@ -917,6 +915,33 @@ - } - EXPORT_SYMBOL_GPL(iommu_put); - -+int iommu_set_isr(const char *name, -+ int (*isr)(struct iommu *obj, u32 da, u32 iommu_errs, -+ void *priv), -+ void *isr_priv) -+{ -+ struct device *dev; -+ struct iommu *obj; -+ -+ dev = driver_find_device(&omap_iommu_driver.driver, NULL, (void *)name, -+ device_match_by_alias); -+ if (!dev) -+ return -ENODEV; -+ -+ obj = to_iommu(dev); -+ mutex_lock(&obj->iommu_lock); -+ if (obj->refcount != 0) { -+ mutex_unlock(&obj->iommu_lock); -+ return -EBUSY; -+ } -+ obj->isr = isr; -+ obj->isr_priv = isr_priv; -+ mutex_unlock(&obj->iommu_lock); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(iommu_set_isr); -+ - /* - * OMAP Device MMU(IOMMU) detection - */ -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/mcbsp.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/mcbsp.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/mcbsp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/mcbsp.c 2011-03-09 13:19:10.106501616 +0100 -@@ -27,6 +27,8 @@ - - #include - #include -+#include -+#include - - /* XXX These "sideways" includes are a sign that something is wrong */ - #include "../mach-omap2/cm2xxx_3xxx.h" -@@ -227,10 +229,83 @@ - } - EXPORT_SYMBOL(omap_mcbsp_config); - -+/** -+ * omap_mcbsp_dma_params - returns the dma channel number -+ * @id - mcbsp id -+ * @stream - indicates the direction of data flow (rx or tx) -+ * -+ * Returns the dma channel number for the rx channel or tx channel -+ * based on the value of @stream for the requested mcbsp given by @id -+ */ -+int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream) -+{ -+ struct omap_mcbsp *mcbsp; -+ -+ if (!omap_mcbsp_check_valid_id(id)) { -+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); -+ return -ENODEV; -+ } -+ mcbsp = id_to_mcbsp_ptr(id); -+ -+ if (stream) -+ return mcbsp->dma_rx_sync; -+ else -+ return mcbsp->dma_tx_sync; -+} -+EXPORT_SYMBOL(omap_mcbsp_dma_ch_params); -+ -+/** -+ * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register -+ * @id - mcbsp id -+ * @stream - indicates the direction of data flow (rx or tx) -+ * -+ * Returns the address of mcbsp data transmit register or data receive register -+ * to be used by DMA for transferring/receiving data based on the value of -+ * @stream for the requested mcbsp given by @id -+ */ -+int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream) -+{ -+ struct omap_mcbsp *mcbsp; -+ int data_reg; -+ -+ if (!omap_mcbsp_check_valid_id(id)) { -+ printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1); -+ return -ENODEV; -+ } -+ mcbsp = id_to_mcbsp_ptr(id); -+ -+ data_reg = mcbsp->phys_dma_base; -+ -+ if (mcbsp->mcbsp_config_type < MCBSP_CONFIG_TYPE2) { -+ if (stream) -+ data_reg += OMAP_MCBSP_REG_DRR1; -+ else -+ data_reg += OMAP_MCBSP_REG_DXR1; -+ } else { -+ if (stream) -+ data_reg += OMAP_MCBSP_REG_DRR; -+ else -+ data_reg += OMAP_MCBSP_REG_DXR; -+ } -+ -+ return data_reg; -+} -+EXPORT_SYMBOL(omap_mcbsp_dma_reg_params); -+ - #ifdef CONFIG_ARCH_OMAP3 -+static struct omap_device *find_omap_device_by_dev(struct device *dev) -+{ -+ struct platform_device *pdev = container_of(dev, -+ struct platform_device, dev); -+ return container_of(pdev, struct omap_device, pdev); -+} -+ - static void omap_st_on(struct omap_mcbsp *mcbsp) - { - unsigned int w; -+ struct omap_device *od; -+ -+ od = find_omap_device_by_dev(mcbsp->dev); - - /* - * Sidetone uses McBSP ICLK - which must not idle when sidetones -@@ -244,9 +319,6 @@ - w = MCBSP_READ(mcbsp, SSELCR); - MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN); - -- w = MCBSP_ST_READ(mcbsp, SYSCONFIG); -- MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE)); -- - /* Enable Sidetone from Sidetone Core */ - w = MCBSP_ST_READ(mcbsp, SSELCR); - MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN); -@@ -255,13 +327,13 @@ - static void omap_st_off(struct omap_mcbsp *mcbsp) - { - unsigned int w; -+ struct omap_device *od; -+ -+ od = find_omap_device_by_dev(mcbsp->dev); - - w = MCBSP_ST_READ(mcbsp, SSELCR); - MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN)); - -- w = MCBSP_ST_READ(mcbsp, SYSCONFIG); -- MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE); -- - w = MCBSP_READ(mcbsp, SSELCR); - MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN)); - -@@ -273,9 +345,9 @@ - static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir) - { - u16 val, i; -+ struct omap_device *od; - -- val = MCBSP_ST_READ(mcbsp, SYSCONFIG); -- MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE)); -+ od = find_omap_device_by_dev(mcbsp->dev); - - val = MCBSP_ST_READ(mcbsp, SSELCR); - -@@ -303,9 +375,9 @@ - { - u16 w; - struct omap_mcbsp_st_data *st_data = mcbsp->st_data; -+ struct omap_device *od; - -- w = MCBSP_ST_READ(mcbsp, SYSCONFIG); -- MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE)); -+ od = find_omap_device_by_dev(mcbsp->dev); - - w = MCBSP_ST_READ(mcbsp, SSELCR); - -@@ -648,48 +720,33 @@ - - static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) - { -+ struct omap_device *od; -+ -+ od = find_omap_device_by_dev(mcbsp->dev); - /* - * Enable wakup behavior, smart idle and all wakeups - * REVISIT: some wakeups may be unnecessary - */ - if (cpu_is_omap34xx() || cpu_is_omap44xx()) { -- u16 syscon; -- -- syscon = MCBSP_READ(mcbsp, SYSCON); -- syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); -- -- if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { -- syscon |= (ENAWAKEUP | SIDLEMODE(0x02) | -- CLOCKACTIVITY(0x02)); -- MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN); -- } else { -- syscon |= SIDLEMODE(0x01); -- } -- -- MCBSP_WRITE(mcbsp, SYSCON, syscon); -+ MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN); - } - } - - static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) - { -+ struct omap_device *od; -+ -+ od = find_omap_device_by_dev(mcbsp->dev); -+ - /* - * Disable wakup behavior, smart idle and all wakeups - */ - if (cpu_is_omap34xx() || cpu_is_omap44xx()) { -- u16 syscon; -- -- syscon = MCBSP_READ(mcbsp, SYSCON); -- syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03)); - /* - * HW bug workaround - If no_idle mode is taken, we need to - * go to smart_idle before going to always_idle, or the - * device will not hit retention anymore. - */ -- syscon |= SIDLEMODE(0x02); -- MCBSP_WRITE(mcbsp, SYSCON, syscon); -- -- syscon &= ~(SIDLEMODE(0x03)); -- MCBSP_WRITE(mcbsp, SYSCON, syscon); - - MCBSP_WRITE(mcbsp, WAKEUPEN, 0); - } -@@ -764,8 +821,7 @@ - if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) - mcbsp->pdata->ops->request(id); - -- clk_enable(mcbsp->iclk); -- clk_enable(mcbsp->fclk); -+ pm_runtime_get_sync(mcbsp->dev); - - /* Do procedure specific to omap34xx arch, if applicable */ - omap34xx_mcbsp_request(mcbsp); -@@ -813,8 +869,7 @@ - /* Do procedure specific to omap34xx arch, if applicable */ - omap34xx_mcbsp_free(mcbsp); - -- clk_disable(mcbsp->fclk); -- clk_disable(mcbsp->iclk); -+ pm_runtime_put_sync(mcbsp->dev); - - spin_lock(&mcbsp->lock); - mcbsp->free = true; -@@ -844,8 +899,7 @@ - /* Do procedure specific to omap34xx arch, if applicable */ - omap34xx_mcbsp_free(mcbsp); - -- clk_disable(mcbsp->fclk); -- clk_disable(mcbsp->iclk); -+ pm_runtime_put_sync(mcbsp->dev); - - if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) { - /* Free IRQs */ -@@ -1649,7 +1703,8 @@ - - static int __devinit omap_st_add(struct omap_mcbsp *mcbsp) - { -- struct omap_mcbsp_platform_data *pdata = mcbsp->pdata; -+ struct platform_device *pdev; -+ struct resource *res; - struct omap_mcbsp_st_data *st_data; - int err; - -@@ -1659,7 +1714,10 @@ - goto err1; - } - -- st_data->io_base_st = ioremap(pdata->phys_base_st, SZ_4K); -+ pdev = container_of(mcbsp->dev, struct platform_device, dev); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone"); -+ st_data->io_base_st = ioremap(res->start, resource_size(res)); - if (!st_data->io_base_st) { - err = -ENOMEM; - goto err2; -@@ -1748,6 +1806,7 @@ - struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data; - struct omap_mcbsp *mcbsp; - int id = pdev->id - 1; -+ struct resource *res; - int ret = 0; - - if (!pdata) { -@@ -1777,47 +1836,78 @@ - mcbsp->dma_tx_lch = -1; - mcbsp->dma_rx_lch = -1; - -- mcbsp->phys_base = pdata->phys_base; -- mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K); -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); -+ if (!res) { -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) { -+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid memory" -+ "resource\n", __func__, pdev->id); -+ ret = -ENOMEM; -+ goto exit; -+ } -+ } -+ mcbsp->phys_base = res->start; -+ omap_mcbsp_cache_size = resource_size(res); -+ mcbsp->io_base = ioremap(res->start, resource_size(res)); - if (!mcbsp->io_base) { - ret = -ENOMEM; - goto err_ioremap; - } - -+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); -+ if (!res) -+ mcbsp->phys_dma_base = mcbsp->phys_base; -+ else -+ mcbsp->phys_dma_base = res->start; -+ - /* Default I/O is IRQ based */ - mcbsp->io_type = OMAP_MCBSP_IRQ_IO; -- mcbsp->tx_irq = pdata->tx_irq; -- mcbsp->rx_irq = pdata->rx_irq; -- mcbsp->dma_rx_sync = pdata->dma_rx_sync; -- mcbsp->dma_tx_sync = pdata->dma_tx_sync; -- -- mcbsp->iclk = clk_get(&pdev->dev, "ick"); -- if (IS_ERR(mcbsp->iclk)) { -- ret = PTR_ERR(mcbsp->iclk); -- dev_err(&pdev->dev, "unable to get ick: %d\n", ret); -- goto err_iclk; -+ -+ mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx"); -+ mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx"); -+ -+ /* From OMAP4 there will be a single irq line */ -+ if (mcbsp->tx_irq == -ENXIO) -+ mcbsp->tx_irq = platform_get_irq(pdev, 0); -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); -+ if (!res) { -+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid rx DMA channel\n", -+ __func__, pdev->id); -+ ret = -ENODEV; -+ goto err_res; -+ } -+ mcbsp->dma_rx_sync = res->start; -+ -+ res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); -+ if (!res) { -+ dev_err(&pdev->dev, "%s:mcbsp%d has invalid tx DMA channel\n", -+ __func__, pdev->id); -+ ret = -ENODEV; -+ goto err_res; - } -+ mcbsp->dma_tx_sync = res->start; - - mcbsp->fclk = clk_get(&pdev->dev, "fck"); - if (IS_ERR(mcbsp->fclk)) { - ret = PTR_ERR(mcbsp->fclk); - dev_err(&pdev->dev, "unable to get fck: %d\n", ret); -- goto err_fclk; -+ goto err_res; - } - - mcbsp->pdata = pdata; - mcbsp->dev = &pdev->dev; - mcbsp_ptr[id] = mcbsp; -+ mcbsp->mcbsp_config_type = pdata->mcbsp_config_type; - platform_set_drvdata(pdev, mcbsp); -+ pm_runtime_enable(mcbsp->dev); - - /* Initialize mcbsp properties for OMAP34XX if needed / applicable */ - omap34xx_device_init(mcbsp); - - return 0; - --err_fclk: -- clk_put(mcbsp->iclk); --err_iclk: -+err_res: - iounmap(mcbsp->io_base); - err_ioremap: - kfree(mcbsp); -@@ -1839,7 +1929,6 @@ - omap34xx_device_exit(mcbsp); - - clk_put(mcbsp->fclk); -- clk_put(mcbsp->iclk); - - iounmap(mcbsp->io_base); - kfree(mcbsp); -diff -Naur linux-2.6.38-rc7/arch/arm/plat-omap/sram.c linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/sram.c ---- linux-2.6.38-rc7/arch/arm/plat-omap/sram.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/arch/arm/plat-omap/sram.c 2011-03-09 13:19:10.107501596 +0100 -@@ -312,7 +312,7 @@ - } - #endif - --#ifdef CONFIG_ARCH_OMAP2420 -+#ifdef CONFIG_SOC_OMAP2420 - static int __init omap242x_sram_init(void) - { - _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, -@@ -333,7 +333,7 @@ - } - #endif - --#ifdef CONFIG_ARCH_OMAP2430 -+#ifdef CONFIG_SOC_OMAP2430 - static int __init omap243x_sram_init(void) - { - _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, -@@ -405,20 +405,6 @@ - } - #endif - --#ifdef CONFIG_ARCH_OMAP4 --static int __init omap44xx_sram_init(void) --{ -- printk(KERN_ERR "FIXME: %s not implemented\n", __func__); -- -- return -ENODEV; --} --#else --static inline int omap44xx_sram_init(void) --{ -- return 0; --} --#endif -- - int __init omap_sram_init(void) - { - omap_detect_sram(); -@@ -432,8 +418,6 @@ - omap243x_sram_init(); - else if (cpu_is_omap34xx()) - omap34xx_sram_init(); -- else if (cpu_is_omap44xx()) -- omap44xx_sram_init(); - - return 0; - } -diff -Naur linux-2.6.38-rc7/Documentation/hwspinlock.txt linux-2.6.38-rc7-linux-omap-dss2/Documentation/hwspinlock.txt ---- linux-2.6.38-rc7/Documentation/hwspinlock.txt 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/Documentation/hwspinlock.txt 2011-03-09 13:19:09.179520421 +0100 -@@ -0,0 +1,293 @@ -+Hardware Spinlock Framework -+ -+1. Introduction -+ -+Hardware spinlock modules provide hardware assistance for synchronization -+and mutual exclusion between heterogeneous processors and those not operating -+under a single, shared operating system. -+ -+For example, OMAP4 has dual Cortex-A9, dual Cortex-M3 and a C64x+ DSP, -+each of which is running a different Operating System (the master, A9, -+is usually running Linux and the slave processors, the M3 and the DSP, -+are running some flavor of RTOS). -+ -+A generic hwspinlock framework allows platform-independent drivers to use -+the hwspinlock device in order to access data structures that are shared -+between remote processors, that otherwise have no alternative mechanism -+to accomplish synchronization and mutual exclusion operations. -+ -+This is necessary, for example, for Inter-processor communications: -+on OMAP4, cpu-intensive multimedia tasks are offloaded by the host to the -+remote M3 and/or C64x+ slave processors (by an IPC subsystem called Syslink). -+ -+To achieve fast message-based communications, a minimal kernel support -+is needed to deliver messages arriving from a remote processor to the -+appropriate user process. -+ -+This communication is based on simple data structures that is shared between -+the remote processors, and access to it is synchronized using the hwspinlock -+module (remote processor directly places new messages in this shared data -+structure). -+ -+A common hwspinlock interface makes it possible to have generic, platform- -+independent, drivers. -+ -+2. User API -+ -+ struct hwspinlock *hwspin_lock_request(void); -+ - dynamically assign an hwspinlock and return its address, or NULL -+ in case an unused hwspinlock isn't available. Users of this -+ API will usually want to communicate the lock's id to the remote core -+ before it can be used to achieve synchronization. -+ Can be called from an atomic context (this function will not sleep) but -+ not from within interrupt context. -+ -+ struct hwspinlock *hwspin_lock_request_specific(unsigned int id); -+ - assign a specific hwspinlock id and return its address, or NULL -+ if that hwspinlock is already in use. Usually board code will -+ be calling this function in order to reserve specific hwspinlock -+ ids for predefined purposes. -+ Can be called from an atomic context (this function will not sleep) but -+ not from within interrupt context. -+ -+ int hwspin_lock_free(struct hwspinlock *hwlock); -+ - free a previously-assigned hwspinlock; returns 0 on success, or an -+ appropriate error code on failure (e.g. -EINVAL if the hwspinlock -+ is already free). -+ Can be called from an atomic context (this function will not sleep) but -+ not from within interrupt context. -+ -+ int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout); -+ - lock a previously-assigned hwspinlock with a timeout limit (specified in -+ msecs). If the hwspinlock is already taken, the function will busy loop -+ waiting for it to be released, but give up when the timeout elapses. -+ Upon a successful return from this function, preemption is disabled so -+ the caller must not sleep, and is advised to release the hwspinlock as -+ soon as possible, in order to minimize remote cores polling on the -+ hardware interconnect. -+ Returns 0 when successful and an appropriate error code otherwise (most -+ notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). -+ The function will never sleep. -+ -+ int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int timeout); -+ - lock a previously-assigned hwspinlock with a timeout limit (specified in -+ msecs). If the hwspinlock is already taken, the function will busy loop -+ waiting for it to be released, but give up when the timeout elapses. -+ Upon a successful return from this function, preemption and the local -+ interrupts are disabled, so the caller must not sleep, and is advised to -+ release the hwspinlock as soon as possible. -+ Returns 0 when successful and an appropriate error code otherwise (most -+ notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). -+ The function will never sleep. -+ -+ int hwspin_lock_timeout_irqsave(struct hwspinlock *hwlock, unsigned int to, -+ unsigned long *flags); -+ - lock a previously-assigned hwspinlock with a timeout limit (specified in -+ msecs). If the hwspinlock is already taken, the function will busy loop -+ waiting for it to be released, but give up when the timeout elapses. -+ Upon a successful return from this function, preemption is disabled, -+ local interrupts are disabled and their previous state is saved at the -+ given flags placeholder. The caller must not sleep, and is advised to -+ release the hwspinlock as soon as possible. -+ Returns 0 when successful and an appropriate error code otherwise (most -+ notably -ETIMEDOUT if the hwspinlock is still busy after timeout msecs). -+ The function will never sleep. -+ -+ int hwspin_trylock(struct hwspinlock *hwlock); -+ - attempt to lock a previously-assigned hwspinlock, but immediately fail if -+ it is already taken. -+ Upon a successful return from this function, preemption is disabled so -+ caller must not sleep, and is advised to release the hwspinlock as soon as -+ possible, in order to minimize remote cores polling on the hardware -+ interconnect. -+ Returns 0 on success and an appropriate error code otherwise (most -+ notably -EBUSY if the hwspinlock was already taken). -+ The function will never sleep. -+ -+ int hwspin_trylock_irq(struct hwspinlock *hwlock); -+ - attempt to lock a previously-assigned hwspinlock, but immediately fail if -+ it is already taken. -+ Upon a successful return from this function, preemption and the local -+ interrupts are disabled so caller must not sleep, and is advised to -+ release the hwspinlock as soon as possible. -+ Returns 0 on success and an appropriate error code otherwise (most -+ notably -EBUSY if the hwspinlock was already taken). -+ The function will never sleep. -+ -+ int hwspin_trylock_irqsave(struct hwspinlock *hwlock, unsigned long *flags); -+ - attempt to lock a previously-assigned hwspinlock, but immediately fail if -+ it is already taken. -+ Upon a successful return from this function, preemption is disabled, -+ the local interrupts are disabled and their previous state is saved -+ at the given flags placeholder. The caller must not sleep, and is advised -+ to release the hwspinlock as soon as possible. -+ Returns 0 on success and an appropriate error code otherwise (most -+ notably -EBUSY if the hwspinlock was already taken). -+ The function will never sleep. -+ -+ void hwspin_unlock(struct hwspinlock *hwlock); -+ - unlock a previously-locked hwspinlock. Always succeed, and can be called -+ from any context (the function never sleeps). Note: code should _never_ -+ unlock an hwspinlock which is already unlocked (there is no protection -+ against this). -+ -+ void hwspin_unlock_irq(struct hwspinlock *hwlock); -+ - unlock a previously-locked hwspinlock and enable local interrupts. -+ The caller should _never_ unlock an hwspinlock which is already unlocked. -+ Doing so is considered a bug (there is no protection against this). -+ Upon a successful return from this function, preemption and local -+ interrupts are enabled. This function will never sleep. -+ -+ void -+ hwspin_unlock_irqrestore(struct hwspinlock *hwlock, unsigned long *flags); -+ - unlock a previously-locked hwspinlock. -+ The caller should _never_ unlock an hwspinlock which is already unlocked. -+ Doing so is considered a bug (there is no protection against this). -+ Upon a successful return from this function, preemption is reenabled, -+ and the state of the local interrupts is restored to the state saved at -+ the given flags. This function will never sleep. -+ -+ int hwspin_lock_get_id(struct hwspinlock *hwlock); -+ - retrieve id number of a given hwspinlock. This is needed when an -+ hwspinlock is dynamically assigned: before it can be used to achieve -+ mutual exclusion with a remote cpu, the id number should be communicated -+ to the remote task with which we want to synchronize. -+ Returns the hwspinlock id number, or -EINVAL if hwlock is null. -+ -+3. Typical usage -+ -+#include -+#include -+ -+int hwspinlock_example1(void) -+{ -+ struct hwspinlock *hwlock; -+ int ret; -+ -+ /* dynamically assign a hwspinlock */ -+ hwlock = hwspin_lock_request(); -+ if (!hwlock) -+ ... -+ -+ id = hwspin_lock_get_id(hwlock); -+ /* probably need to communicate id to a remote processor now */ -+ -+ /* take the lock, spin for 1 sec if it's already taken */ -+ ret = hwspin_lock_timeout(hwlock, 1000); -+ if (ret) -+ ... -+ -+ /* -+ * we took the lock, do our thing now, but do NOT sleep -+ */ -+ -+ /* release the lock */ -+ hwspin_unlock(hwlock); -+ -+ /* free the lock */ -+ ret = hwspin_lock_free(hwlock); -+ if (ret) -+ ... -+ -+ return ret; -+} -+ -+int hwspinlock_example2(void) -+{ -+ struct hwspinlock *hwlock; -+ int ret; -+ -+ /* -+ * assign a specific hwspinlock id - this should be called early -+ * by board init code. -+ */ -+ hwlock = hwspin_lock_request_specific(PREDEFINED_LOCK_ID); -+ if (!hwlock) -+ ... -+ -+ /* try to take it, but don't spin on it */ -+ ret = hwspin_trylock(hwlock); -+ if (!ret) { -+ pr_info("lock is already taken\n"); -+ return -EBUSY; -+ } -+ -+ /* -+ * we took the lock, do our thing now, but do NOT sleep -+ */ -+ -+ /* release the lock */ -+ hwspin_unlock(hwlock); -+ -+ /* free the lock */ -+ ret = hwspin_lock_free(hwlock); -+ if (ret) -+ ... -+ -+ return ret; -+} -+ -+ -+4. API for implementors -+ -+ int hwspin_lock_register(struct hwspinlock *hwlock); -+ - to be called from the underlying platform-specific implementation, in -+ order to register a new hwspinlock instance. Can be called from an atomic -+ context (this function will not sleep) but not from within interrupt -+ context. Returns 0 on success, or appropriate error code on failure. -+ -+ struct hwspinlock *hwspin_lock_unregister(unsigned int id); -+ - to be called from the underlying vendor-specific implementation, in order -+ to unregister an existing (and unused) hwspinlock instance. -+ Can be called from an atomic context (will not sleep) but not from -+ within interrupt context. -+ Returns the address of hwspinlock on success, or NULL on error (e.g. -+ if the hwspinlock is sill in use). -+ -+5. struct hwspinlock -+ -+This struct represents an hwspinlock instance. It is registered by the -+underlying hwspinlock implementation using the hwspin_lock_register() API. -+ -+/** -+ * struct hwspinlock - vendor-specific hwspinlock implementation -+ * -+ * @dev: underlying device, will be used with runtime PM api -+ * @ops: vendor-specific hwspinlock handlers -+ * @id: a global, unique, system-wide, index of the lock. -+ * @lock: initialized and used by hwspinlock core -+ * @owner: underlying implementation module, used to maintain module ref count -+ */ -+struct hwspinlock { -+ struct device *dev; -+ const struct hwspinlock_ops *ops; -+ int id; -+ spinlock_t lock; -+ struct module *owner; -+}; -+ -+The underlying implementation is responsible to assign the dev, ops, id and -+owner members. The lock member, OTOH, is initialized and used by the hwspinlock -+core. -+ -+6. Implementation callbacks -+ -+There are three possible callbacks defined in 'struct hwspinlock_ops': -+ -+struct hwspinlock_ops { -+ int (*trylock)(struct hwspinlock *lock); -+ void (*unlock)(struct hwspinlock *lock); -+ void (*relax)(struct hwspinlock *lock); -+}; -+ -+The first two callbacks are mandatory: -+ -+The ->trylock() callback should make a single attempt to take the lock, and -+return 0 on failure and 1 on success. This callback may _not_ sleep. -+ -+The ->unlock() callback releases the lock. It always succeed, and it, too, -+may _not_ sleep. -+ -+The ->relax() callback is optional. It is called by hwspinlock core while -+spinning on a lock, and can be used by the underlying implementation to force -+a delay between two successive invocations of ->trylock(). It may _not_ sleep. -diff -Naur linux-2.6.38-rc7/drivers/hwspinlock/hwspinlock_core.c linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/hwspinlock_core.c ---- linux-2.6.38-rc7/drivers/hwspinlock/hwspinlock_core.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/hwspinlock_core.c 2011-03-09 13:19:13.374435328 +0100 -@@ -0,0 +1,548 @@ -+/* -+ * Hardware spinlock framework -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Contact: Ohad Ben-Cohen -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#define pr_fmt(fmt) "%s: " fmt, __func__ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "hwspinlock_internal.h" -+ -+/* radix tree tags */ -+#define HWSPINLOCK_UNUSED (0) /* tags an hwspinlock as unused */ -+ -+/* -+ * A radix tree is used to maintain the available hwspinlock instances. -+ * The tree associates hwspinlock pointers with their integer key id, -+ * and provides easy-to-use API which makes the hwspinlock core code simple -+ * and easy to read. -+ * -+ * Radix trees are quick on lookups, and reasonably efficient in terms of -+ * storage, especially with high density usages such as this framework -+ * requires (a continuous range of integer keys, beginning with zero, is -+ * used as the ID's of the hwspinlock instances). -+ * -+ * The radix tree API supports tagging items in the tree, which this -+ * framework uses to mark unused hwspinlock instances (see the -+ * HWSPINLOCK_UNUSED tag above). As a result, the process of querying the -+ * tree, looking for an unused hwspinlock instance, is now reduced to a -+ * single radix tree API call. -+ */ -+static RADIX_TREE(hwspinlock_tree, GFP_KERNEL); -+ -+/* -+ * Synchronization of access to the tree is achieved using this spinlock, -+ * as the radix-tree API requires that users provide all synchronisation. -+ */ -+static DEFINE_SPINLOCK(hwspinlock_tree_lock); -+ -+/** -+ * __hwspin_trylock() - attempt to lock a specific hwspinlock -+ * @hwlock: an hwspinlock which we want to trylock -+ * @mode: controls whether local interrupts are disabled or not -+ * @flags: a pointer where the caller's interrupt state will be saved at (if -+ * requested) -+ * -+ * This function attempts to lock an hwspinlock, and will immediately -+ * fail if the hwspinlock is already taken. -+ * -+ * Upon a successful return from this function, preemption (and possibly -+ * interrupts) is disabled, so the caller must not sleep, and is advised to -+ * release the hwspinlock as soon as possible. This is required in order to -+ * minimize remote cores polling on the hardware interconnect. -+ * -+ * The user decides whether local interrupts are disabled or not, and if yes, -+ * whether he wants their previous state to be saved. It is up to the user -+ * to choose the appropriate @mode of operation, exactly the same way users -+ * should decide between spin_trylock, spin_trylock_irq and -+ * spin_trylock_irqsave. -+ * -+ * Returns 0 if we successfully locked the hwspinlock or -EBUSY if -+ * the hwspinlock was already taken. -+ * This function will never sleep. -+ */ -+int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) -+{ -+ int ret; -+ -+ BUG_ON(!hwlock); -+ BUG_ON(!flags && mode == HWLOCK_IRQSTATE); -+ -+ /* -+ * This spin_lock{_irq, _irqsave} serves three purposes: -+ * -+ * 1. Disable preemption, in order to minimize the period of time -+ * in which the hwspinlock is taken. This is important in order -+ * to minimize the possible polling on the hardware interconnect -+ * by a remote user of this lock. -+ * 2. Make the hwspinlock SMP-safe (so we can take it from -+ * additional contexts on the local host). -+ * 3. Ensure that in_atomic/might_sleep checks catch potential -+ * problems with hwspinlock usage (e.g. scheduler checks like -+ * 'scheduling while atomic' etc.) -+ */ -+ if (mode == HWLOCK_IRQSTATE) -+ ret = spin_trylock_irqsave(&hwlock->lock, *flags); -+ else if (mode == HWLOCK_IRQ) -+ ret = spin_trylock_irq(&hwlock->lock); -+ else -+ ret = spin_trylock(&hwlock->lock); -+ -+ /* is lock already taken by another context on the local cpu ? */ -+ if (!ret) -+ return -EBUSY; -+ -+ /* try to take the hwspinlock device */ -+ ret = hwlock->ops->trylock(hwlock); -+ -+ /* if hwlock is already taken, undo spin_trylock_* and exit */ -+ if (!ret) { -+ if (mode == HWLOCK_IRQSTATE) -+ spin_unlock_irqrestore(&hwlock->lock, *flags); -+ else if (mode == HWLOCK_IRQ) -+ spin_unlock_irq(&hwlock->lock); -+ else -+ spin_unlock(&hwlock->lock); -+ -+ return -EBUSY; -+ } -+ -+ /* -+ * We can be sure the other core's memory operations -+ * are observable to us only _after_ we successfully take -+ * the hwspinlock, and we must make sure that subsequent memory -+ * operations (both reads and writes) will not be reordered before -+ * we actually took the hwspinlock. -+ * -+ * Note: the implicit memory barrier of the spinlock above is too -+ * early, so we need this additional explicit memory barrier. -+ */ -+ mb(); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(__hwspin_trylock); -+ -+/** -+ * __hwspin_lock_timeout() - lock an hwspinlock with timeout limit -+ * @hwlock: the hwspinlock to be locked -+ * @timeout: timeout value in msecs -+ * @mode: mode which controls whether local interrupts are disabled or not -+ * @flags: a pointer to where the caller's interrupt state will be saved at (if -+ * requested) -+ * -+ * This function locks the given @hwlock. If the @hwlock -+ * is already taken, the function will busy loop waiting for it to -+ * be released, but give up after @timeout msecs have elapsed. -+ * -+ * Upon a successful return from this function, preemption is disabled -+ * (and possibly local interrupts, too), so the caller must not sleep, -+ * and is advised to release the hwspinlock as soon as possible. -+ * This is required in order to minimize remote cores polling on the -+ * hardware interconnect. -+ * -+ * The user decides whether local interrupts are disabled or not, and if yes, -+ * whether he wants their previous state to be saved. It is up to the user -+ * to choose the appropriate @mode of operation, exactly the same way users -+ * should decide between spin_lock, spin_lock_irq and spin_lock_irqsave. -+ * -+ * Returns 0 when the @hwlock was successfully taken, and an appropriate -+ * error code otherwise (most notably -ETIMEDOUT if the @hwlock is still -+ * busy after @timeout msecs). The function will never sleep. -+ */ -+int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to, -+ int mode, unsigned long *flags) -+{ -+ int ret; -+ unsigned long expire; -+ -+ expire = msecs_to_jiffies(to) + jiffies; -+ -+ for (;;) { -+ /* Try to take the hwspinlock */ -+ ret = __hwspin_trylock(hwlock, mode, flags); -+ if (ret != -EBUSY) -+ break; -+ -+ /* -+ * The lock is already taken, let's check if the user wants -+ * us to try again -+ */ -+ if (time_is_before_eq_jiffies(expire)) -+ return -ETIMEDOUT; -+ -+ /* -+ * Allow platform-specific relax handlers to prevent -+ * hogging the interconnect (no sleeping, though) -+ */ -+ if (hwlock->ops->relax) -+ hwlock->ops->relax(hwlock); -+ } -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(__hwspin_lock_timeout); -+ -+/** -+ * __hwspin_unlock() - unlock a specific hwspinlock -+ * @hwlock: a previously-acquired hwspinlock which we want to unlock -+ * @mode: controls whether local interrupts needs to be restored or not -+ * @flags: previous caller's interrupt state to restore (if requested) -+ * -+ * This function will unlock a specific hwspinlock, enable preemption and -+ * (possibly) enable interrupts or restore their previous state. -+ * @hwlock must be already locked before calling this function: it is a bug -+ * to call unlock on a @hwlock that is already unlocked. -+ * -+ * The user decides whether local interrupts should be enabled or not, and -+ * if yes, whether he wants their previous state to be restored. It is up -+ * to the user to choose the appropriate @mode of operation, exactly the -+ * same way users decide between spin_unlock, spin_unlock_irq and -+ * spin_unlock_irqrestore. -+ * -+ * The function will never sleep. -+ */ -+void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) -+{ -+ BUG_ON(!hwlock); -+ BUG_ON(!flags && mode == HWLOCK_IRQSTATE); -+ -+ /* -+ * We must make sure that memory operations (both reads and writes), -+ * done before unlocking the hwspinlock, will not be reordered -+ * after the lock is released. -+ * -+ * That's the purpose of this explicit memory barrier. -+ * -+ * Note: the memory barrier induced by the spin_unlock below is too -+ * late; the other core is going to access memory soon after it will -+ * take the hwspinlock, and by then we want to be sure our memory -+ * operations are already observable. -+ */ -+ mb(); -+ -+ hwlock->ops->unlock(hwlock); -+ -+ /* Undo the spin_trylock{_irq, _irqsave} called while locking */ -+ if (mode == HWLOCK_IRQSTATE) -+ spin_unlock_irqrestore(&hwlock->lock, *flags); -+ else if (mode == HWLOCK_IRQ) -+ spin_unlock_irq(&hwlock->lock); -+ else -+ spin_unlock(&hwlock->lock); -+} -+EXPORT_SYMBOL_GPL(__hwspin_unlock); -+ -+/** -+ * hwspin_lock_register() - register a new hw spinlock -+ * @hwlock: hwspinlock to register. -+ * -+ * This function should be called from the underlying platform-specific -+ * implementation, to register a new hwspinlock instance. -+ * -+ * Can be called from an atomic context (will not sleep) but not from -+ * within interrupt context. -+ * -+ * Returns 0 on success, or an appropriate error code on failure -+ */ -+int hwspin_lock_register(struct hwspinlock *hwlock) -+{ -+ struct hwspinlock *tmp; -+ int ret; -+ -+ if (!hwlock || !hwlock->ops || -+ !hwlock->ops->trylock || !hwlock->ops->unlock) { -+ pr_err("invalid parameters\n"); -+ return -EINVAL; -+ } -+ -+ spin_lock_init(&hwlock->lock); -+ -+ spin_lock(&hwspinlock_tree_lock); -+ -+ ret = radix_tree_insert(&hwspinlock_tree, hwlock->id, hwlock); -+ if (ret) -+ goto out; -+ -+ /* mark this hwspinlock as available */ -+ tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id, -+ HWSPINLOCK_UNUSED); -+ -+ /* self-sanity check which should never fail */ -+ WARN_ON(tmp != hwlock); -+ -+out: -+ spin_unlock(&hwspinlock_tree_lock); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_register); -+ -+/** -+ * hwspin_lock_unregister() - unregister an hw spinlock -+ * @id: index of the specific hwspinlock to unregister -+ * -+ * This function should be called from the underlying platform-specific -+ * implementation, to unregister an existing (and unused) hwspinlock. -+ * -+ * Can be called from an atomic context (will not sleep) but not from -+ * within interrupt context. -+ * -+ * Returns the address of hwspinlock @id on success, or NULL on failure -+ */ -+struct hwspinlock *hwspin_lock_unregister(unsigned int id) -+{ -+ struct hwspinlock *hwlock = NULL; -+ int ret; -+ -+ spin_lock(&hwspinlock_tree_lock); -+ -+ /* make sure the hwspinlock is not in use (tag is set) */ -+ ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED); -+ if (ret == 0) { -+ pr_err("hwspinlock %d still in use (or not present)\n", id); -+ goto out; -+ } -+ -+ hwlock = radix_tree_delete(&hwspinlock_tree, id); -+ if (!hwlock) { -+ pr_err("failed to delete hwspinlock %d\n", id); -+ goto out; -+ } -+ -+out: -+ spin_unlock(&hwspinlock_tree_lock); -+ return hwlock; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_unregister); -+ -+/** -+ * __hwspin_lock_request() - tag an hwspinlock as used and power it up -+ * -+ * This is an internal function that prepares an hwspinlock instance -+ * before it is given to the user. The function assumes that -+ * hwspinlock_tree_lock is taken. -+ * -+ * Returns 0 or positive to indicate success, and a negative value to -+ * indicate an error (with the appropriate error code) -+ */ -+static int __hwspin_lock_request(struct hwspinlock *hwlock) -+{ -+ struct hwspinlock *tmp; -+ int ret; -+ -+ /* prevent underlying implementation from being removed */ -+ if (!try_module_get(hwlock->owner)) { -+ dev_err(hwlock->dev, "%s: can't get owner\n", __func__); -+ return -EINVAL; -+ } -+ -+ /* notify PM core that power is now needed */ -+ ret = pm_runtime_get_sync(hwlock->dev); -+ if (ret < 0) { -+ dev_err(hwlock->dev, "%s: can't power on device\n", __func__); -+ return ret; -+ } -+ -+ /* mark hwspinlock as used, should not fail */ -+ tmp = radix_tree_tag_clear(&hwspinlock_tree, hwlock->id, -+ HWSPINLOCK_UNUSED); -+ -+ /* self-sanity check that should never fail */ -+ WARN_ON(tmp != hwlock); -+ -+ return ret; -+} -+ -+/** -+ * hwspin_lock_get_id() - retrieve id number of a given hwspinlock -+ * @hwlock: a valid hwspinlock instance -+ * -+ * Returns the id number of a given @hwlock, or -EINVAL if @hwlock is invalid. -+ */ -+int hwspin_lock_get_id(struct hwspinlock *hwlock) -+{ -+ if (!hwlock) { -+ pr_err("invalid hwlock\n"); -+ return -EINVAL; -+ } -+ -+ return hwlock->id; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_get_id); -+ -+/** -+ * hwspin_lock_request() - request an hwspinlock -+ * -+ * This function should be called by users of the hwspinlock device, -+ * in order to dynamically assign them an unused hwspinlock. -+ * Usually the user of this lock will then have to communicate the lock's id -+ * to the remote core before it can be used for synchronization (to get the -+ * id of a given hwlock, use hwspin_lock_get_id()). -+ * -+ * Can be called from an atomic context (will not sleep) but not from -+ * within interrupt context (simply because there is no use case for -+ * that yet). -+ * -+ * Returns the address of the assigned hwspinlock, or NULL on error -+ */ -+struct hwspinlock *hwspin_lock_request(void) -+{ -+ struct hwspinlock *hwlock; -+ int ret; -+ -+ spin_lock(&hwspinlock_tree_lock); -+ -+ /* look for an unused lock */ -+ ret = radix_tree_gang_lookup_tag(&hwspinlock_tree, (void **)&hwlock, -+ 0, 1, HWSPINLOCK_UNUSED); -+ if (ret == 0) { -+ pr_warn("a free hwspinlock is not available\n"); -+ hwlock = NULL; -+ goto out; -+ } -+ -+ /* sanity check that should never fail */ -+ WARN_ON(ret > 1); -+ -+ /* mark as used and power up */ -+ ret = __hwspin_lock_request(hwlock); -+ if (ret < 0) -+ hwlock = NULL; -+ -+out: -+ spin_unlock(&hwspinlock_tree_lock); -+ return hwlock; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_request); -+ -+/** -+ * hwspin_lock_request_specific() - request for a specific hwspinlock -+ * @id: index of the specific hwspinlock that is requested -+ * -+ * This function should be called by users of the hwspinlock module, -+ * in order to assign them a specific hwspinlock. -+ * Usually early board code will be calling this function in order to -+ * reserve specific hwspinlock ids for predefined purposes. -+ * -+ * Can be called from an atomic context (will not sleep) but not from -+ * within interrupt context (simply because there is no use case for -+ * that yet). -+ * -+ * Returns the address of the assigned hwspinlock, or NULL on error -+ */ -+struct hwspinlock *hwspin_lock_request_specific(unsigned int id) -+{ -+ struct hwspinlock *hwlock; -+ int ret; -+ -+ spin_lock(&hwspinlock_tree_lock); -+ -+ /* make sure this hwspinlock exists */ -+ hwlock = radix_tree_lookup(&hwspinlock_tree, id); -+ if (!hwlock) { -+ pr_warn("hwspinlock %u does not exist\n", id); -+ goto out; -+ } -+ -+ /* sanity check (this shouldn't happen) */ -+ WARN_ON(hwlock->id != id); -+ -+ /* make sure this hwspinlock is unused */ -+ ret = radix_tree_tag_get(&hwspinlock_tree, id, HWSPINLOCK_UNUSED); -+ if (ret == 0) { -+ pr_warn("hwspinlock %u is already in use\n", id); -+ hwlock = NULL; -+ goto out; -+ } -+ -+ /* mark as used and power up */ -+ ret = __hwspin_lock_request(hwlock); -+ if (ret < 0) -+ hwlock = NULL; -+ -+out: -+ spin_unlock(&hwspinlock_tree_lock); -+ return hwlock; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_request_specific); -+ -+/** -+ * hwspin_lock_free() - free a specific hwspinlock -+ * @hwlock: the specific hwspinlock to free -+ * -+ * This function mark @hwlock as free again. -+ * Should only be called with an @hwlock that was retrieved from -+ * an earlier call to omap_hwspin_lock_request{_specific}. -+ * -+ * Can be called from an atomic context (will not sleep) but not from -+ * within interrupt context (simply because there is no use case for -+ * that yet). -+ * -+ * Returns 0 on success, or an appropriate error code on failure -+ */ -+int hwspin_lock_free(struct hwspinlock *hwlock) -+{ -+ struct hwspinlock *tmp; -+ int ret; -+ -+ if (!hwlock) { -+ pr_err("invalid hwlock\n"); -+ return -EINVAL; -+ } -+ -+ spin_lock(&hwspinlock_tree_lock); -+ -+ /* make sure the hwspinlock is used */ -+ ret = radix_tree_tag_get(&hwspinlock_tree, hwlock->id, -+ HWSPINLOCK_UNUSED); -+ if (ret == 1) { -+ dev_err(hwlock->dev, "%s: hwlock is already free\n", __func__); -+ dump_stack(); -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* notify the underlying device that power is not needed */ -+ ret = pm_runtime_put(hwlock->dev); -+ if (ret < 0) -+ goto out; -+ -+ /* mark this hwspinlock as available */ -+ tmp = radix_tree_tag_set(&hwspinlock_tree, hwlock->id, -+ HWSPINLOCK_UNUSED); -+ -+ /* sanity check (this shouldn't happen) */ -+ WARN_ON(tmp != hwlock); -+ -+ module_put(hwlock->owner); -+ -+out: -+ spin_unlock(&hwspinlock_tree_lock); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(hwspin_lock_free); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Hardware spinlock interface"); -+MODULE_AUTHOR("Ohad Ben-Cohen "); -diff -Naur linux-2.6.38-rc7/drivers/hwspinlock/hwspinlock_internal.h linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/hwspinlock_internal.h ---- linux-2.6.38-rc7/drivers/hwspinlock/hwspinlock_internal.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/hwspinlock_internal.h 2011-03-09 13:19:13.374435328 +0100 -@@ -0,0 +1,61 @@ -+/* -+ * Hardware spinlocks internal header -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Contact: Ohad Ben-Cohen -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __HWSPINLOCK_HWSPINLOCK_H -+#define __HWSPINLOCK_HWSPINLOCK_H -+ -+#include -+#include -+ -+/** -+ * struct hwspinlock_ops - platform-specific hwspinlock handlers -+ * -+ * @trylock: make a single attempt to take the lock. returns 0 on -+ * failure and true on success. may _not_ sleep. -+ * @unlock: release the lock. always succeed. may _not_ sleep. -+ * @relax: optional, platform-specific relax handler, called by hwspinlock -+ * core while spinning on a lock, between two successive -+ * invocations of @trylock. may _not_ sleep. -+ */ -+struct hwspinlock_ops { -+ int (*trylock)(struct hwspinlock *lock); -+ void (*unlock)(struct hwspinlock *lock); -+ void (*relax)(struct hwspinlock *lock); -+}; -+ -+/** -+ * struct hwspinlock - this struct represents a single hwspinlock instance -+ * -+ * @dev: underlying device, will be used to invoke runtime PM api -+ * @ops: platform-specific hwspinlock handlers -+ * @id: a global, unique, system-wide, index of the lock. -+ * @lock: initialized and used by hwspinlock core -+ * @owner: underlying implementation module, used to maintain module ref count -+ * -+ * Note: currently simplicity was opted for, but later we can squeeze some -+ * memory bytes by grouping the dev, ops and owner members in a single -+ * per-platform struct, and have all hwspinlocks point at it. -+ */ -+struct hwspinlock { -+ struct device *dev; -+ const struct hwspinlock_ops *ops; -+ int id; -+ spinlock_t lock; -+ struct module *owner; -+}; -+ -+#endif /* __HWSPINLOCK_HWSPINLOCK_H */ -diff -Naur linux-2.6.38-rc7/drivers/hwspinlock/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/Kconfig ---- linux-2.6.38-rc7/drivers/hwspinlock/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/Kconfig 2011-03-09 13:19:13.373435348 +0100 -@@ -0,0 +1,22 @@ -+# -+# Generic HWSPINLOCK framework -+# -+ -+config HWSPINLOCK -+ tristate "Generic Hardware Spinlock framework" -+ help -+ Say y here to support the generic hardware spinlock framework. -+ You only need to enable this if you have hardware spinlock module -+ on your system (usually only relevant if your system has remote slave -+ coprocessors). -+ -+ If unsure, say N. -+ -+config HWSPINLOCK_OMAP -+ tristate "OMAP Hardware Spinlock device" -+ depends on HWSPINLOCK && ARCH_OMAP4 -+ help -+ Say y here to support the OMAP Hardware Spinlock device (firstly -+ introduced in OMAP4). -+ -+ If unsure, say N. -diff -Naur linux-2.6.38-rc7/drivers/hwspinlock/Makefile linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/Makefile ---- linux-2.6.38-rc7/drivers/hwspinlock/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/Makefile 2011-03-09 13:19:13.374435328 +0100 -@@ -0,0 +1,6 @@ -+# -+# Generic Hardware Spinlock framework -+# -+ -+obj-$(CONFIG_HWSPINLOCK) += hwspinlock_core.o -+obj-$(CONFIG_HWSPINLOCK_OMAP) += omap_hwspinlock.o -diff -Naur linux-2.6.38-rc7/drivers/hwspinlock/omap_hwspinlock.c linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/omap_hwspinlock.c ---- linux-2.6.38-rc7/drivers/hwspinlock/omap_hwspinlock.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/hwspinlock/omap_hwspinlock.c 2011-03-09 13:19:13.374435328 +0100 -@@ -0,0 +1,231 @@ -+/* -+ * OMAP hardware spinlock driver -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Contact: Simon Que -+ * Hari Kanigeri -+ * Ohad Ben-Cohen -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * version 2 as published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "hwspinlock_internal.h" -+ -+/* Spinlock register offsets */ -+#define SYSSTATUS_OFFSET 0x0014 -+#define LOCK_BASE_OFFSET 0x0800 -+ -+#define SPINLOCK_NUMLOCKS_BIT_OFFSET (24) -+ -+/* Possible values of SPINLOCK_LOCK_REG */ -+#define SPINLOCK_NOTTAKEN (0) /* free */ -+#define SPINLOCK_TAKEN (1) /* locked */ -+ -+#define to_omap_hwspinlock(lock) \ -+ container_of(lock, struct omap_hwspinlock, lock) -+ -+struct omap_hwspinlock { -+ struct hwspinlock lock; -+ void __iomem *addr; -+}; -+ -+struct omap_hwspinlock_state { -+ int num_locks; /* Total number of locks in system */ -+ void __iomem *io_base; /* Mapped base address */ -+}; -+ -+static int omap_hwspinlock_trylock(struct hwspinlock *lock) -+{ -+ struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock); -+ -+ /* attempt to acquire the lock by reading its value */ -+ return (SPINLOCK_NOTTAKEN == readl(omap_lock->addr)); -+} -+ -+static void omap_hwspinlock_unlock(struct hwspinlock *lock) -+{ -+ struct omap_hwspinlock *omap_lock = to_omap_hwspinlock(lock); -+ -+ /* release the lock by writing 0 to it */ -+ writel(SPINLOCK_NOTTAKEN, omap_lock->addr); -+} -+ -+/* -+ * relax the OMAP interconnect while spinning on it. -+ * -+ * The specs recommended that the retry delay time will be -+ * just over half of the time that a requester would be -+ * expected to hold the lock. -+ * -+ * The number below is taken from an hardware specs example, -+ * obviously it is somewhat arbitrary. -+ */ -+static void omap_hwspinlock_relax(struct hwspinlock *lock) -+{ -+ ndelay(50); -+} -+ -+static const struct hwspinlock_ops omap_hwspinlock_ops = { -+ .trylock = omap_hwspinlock_trylock, -+ .unlock = omap_hwspinlock_unlock, -+ .relax = omap_hwspinlock_relax, -+}; -+ -+static int __devinit omap_hwspinlock_probe(struct platform_device *pdev) -+{ -+ struct omap_hwspinlock *omap_lock; -+ struct omap_hwspinlock_state *state; -+ struct hwspinlock *lock; -+ struct resource *res; -+ void __iomem *io_base; -+ int i, ret; -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res) -+ return -ENODEV; -+ -+ state = kzalloc(sizeof(*state), GFP_KERNEL); -+ if (!state) -+ return -ENOMEM; -+ -+ io_base = ioremap(res->start, resource_size(res)); -+ if (!io_base) { -+ ret = -ENOMEM; -+ goto free_state; -+ } -+ -+ /* Determine number of locks */ -+ i = readl(io_base + SYSSTATUS_OFFSET); -+ i >>= SPINLOCK_NUMLOCKS_BIT_OFFSET; -+ -+ /* one of the four lsb's must be set, and nothing else */ -+ if (hweight_long(i & 0xf) != 1 || i > 8) { -+ ret = -EINVAL; -+ goto iounmap_base; -+ } -+ -+ state->num_locks = i * 32; -+ state->io_base = io_base; -+ -+ platform_set_drvdata(pdev, state); -+ -+ /* -+ * runtime PM will make sure the clock of this module is -+ * enabled iff at least one lock is requested -+ */ -+ pm_runtime_enable(&pdev->dev); -+ -+ for (i = 0; i < state->num_locks; i++) { -+ omap_lock = kzalloc(sizeof(*omap_lock), GFP_KERNEL); -+ if (!omap_lock) { -+ ret = -ENOMEM; -+ goto free_locks; -+ } -+ -+ omap_lock->lock.dev = &pdev->dev; -+ omap_lock->lock.owner = THIS_MODULE; -+ omap_lock->lock.id = i; -+ omap_lock->lock.ops = &omap_hwspinlock_ops; -+ omap_lock->addr = io_base + LOCK_BASE_OFFSET + sizeof(u32) * i; -+ -+ ret = hwspin_lock_register(&omap_lock->lock); -+ if (ret) { -+ kfree(omap_lock); -+ goto free_locks; -+ } -+ } -+ -+ return 0; -+ -+free_locks: -+ while (--i >= 0) { -+ lock = hwspin_lock_unregister(i); -+ /* this should't happen, but let's give our best effort */ -+ if (!lock) { -+ dev_err(&pdev->dev, "%s: cleanups failed\n", __func__); -+ continue; -+ } -+ omap_lock = to_omap_hwspinlock(lock); -+ kfree(omap_lock); -+ } -+ pm_runtime_disable(&pdev->dev); -+iounmap_base: -+ iounmap(io_base); -+free_state: -+ kfree(state); -+ return ret; -+} -+ -+static int omap_hwspinlock_remove(struct platform_device *pdev) -+{ -+ struct omap_hwspinlock_state *state = platform_get_drvdata(pdev); -+ struct hwspinlock *lock; -+ struct omap_hwspinlock *omap_lock; -+ int i; -+ -+ for (i = 0; i < state->num_locks; i++) { -+ lock = hwspin_lock_unregister(i); -+ /* this shouldn't happen at this point. if it does, at least -+ * don't continue with the remove */ -+ if (!lock) { -+ dev_err(&pdev->dev, "%s: failed on %d\n", __func__, i); -+ return -EBUSY; -+ } -+ -+ omap_lock = to_omap_hwspinlock(lock); -+ kfree(omap_lock); -+ } -+ -+ pm_runtime_disable(&pdev->dev); -+ iounmap(state->io_base); -+ kfree(state); -+ -+ return 0; -+} -+ -+static struct platform_driver omap_hwspinlock_driver = { -+ .probe = omap_hwspinlock_probe, -+ .remove = omap_hwspinlock_remove, -+ .driver = { -+ .name = "omap_hwspinlock", -+ }, -+}; -+ -+static int __init omap_hwspinlock_init(void) -+{ -+ return platform_driver_register(&omap_hwspinlock_driver); -+} -+/* board init code might need to reserve hwspinlocks for predefined purposes */ -+postcore_initcall(omap_hwspinlock_init); -+ -+static void __exit omap_hwspinlock_exit(void) -+{ -+ platform_driver_unregister(&omap_hwspinlock_driver); -+} -+module_exit(omap_hwspinlock_exit); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("Hardware spinlock driver for OMAP"); -+MODULE_AUTHOR("Simon Que "); -+MODULE_AUTHOR("Hari Kanigeri "); -+MODULE_AUTHOR("Ohad Ben-Cohen "); -diff -Naur linux-2.6.38-rc7/drivers/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/Kconfig ---- linux-2.6.38-rc7/drivers/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/Kconfig 2011-03-09 13:19:12.865445652 +0100 -@@ -117,4 +117,6 @@ - source "drivers/platform/Kconfig" - - source "drivers/clk/Kconfig" -+ -+source "drivers/hwspinlock/Kconfig" - endmenu -diff -Naur linux-2.6.38-rc7/drivers/Makefile linux-2.6.38-rc7-linux-omap-dss2/drivers/Makefile ---- linux-2.6.38-rc7/drivers/Makefile 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/Makefile 2011-03-09 13:19:12.865445652 +0100 -@@ -117,3 +117,5 @@ - obj-y += ieee802154/ - #common clk code - obj-y += clk/ -+ -+obj-$(CONFIG_HWSPINLOCK) += hwspinlock/ -diff -Naur linux-2.6.38-rc7/drivers/mmc/host/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/mmc/host/Kconfig ---- linux-2.6.38-rc7/drivers/mmc/host/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/mmc/host/Kconfig 2011-03-09 13:19:15.003402284 +0100 -@@ -225,7 +225,7 @@ - - config MMC_OMAP_HS - tristate "TI OMAP High Speed Multimedia Card Interface support" -- depends on ARCH_OMAP2430 || ARCH_OMAP3 || ARCH_OMAP4 -+ depends on SOC_OMAP2430 || ARCH_OMAP3 || ARCH_OMAP4 - help - This selects the TI OMAP High Speed Multimedia card Interface. - If you have an OMAP2430 or OMAP3 board or OMAP4 board with a -diff -Naur linux-2.6.38-rc7/drivers/mmc/host/omap_hsmmc.c linux-2.6.38-rc7-linux-omap-dss2/drivers/mmc/host/omap_hsmmc.c ---- linux-2.6.38-rc7/drivers/mmc/host/omap_hsmmc.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/mmc/host/omap_hsmmc.c 2011-03-09 13:19:15.011402121 +0100 -@@ -118,7 +118,7 @@ - - #define MMC_TIMEOUT_MS 20 - #define OMAP_MMC_MASTER_CLOCK 96000000 --#define DRIVER_NAME "mmci-omap-hs" -+#define DRIVER_NAME "omap_hsmmc" - - /* Timeouts for entering power saving states on inactivity, msec */ - #define OMAP_MMC_DISABLED_TIMEOUT 100 -@@ -260,7 +260,7 @@ - return ret; - } - --static int omap_hsmmc_23_set_power(struct device *dev, int slot, int power_on, -+static int omap_hsmmc_235_set_power(struct device *dev, int slot, int power_on, - int vdd) - { - struct omap_hsmmc_host *host = -@@ -316,6 +316,12 @@ - return ret; - } - -+static int omap_hsmmc_4_set_power(struct device *dev, int slot, int power_on, -+ int vdd) -+{ -+ return 0; -+} -+ - static int omap_hsmmc_1_set_sleep(struct device *dev, int slot, int sleep, - int vdd, int cardsleep) - { -@@ -326,7 +332,7 @@ - return regulator_set_mode(host->vcc, mode); - } - --static int omap_hsmmc_23_set_sleep(struct device *dev, int slot, int sleep, -+static int omap_hsmmc_235_set_sleep(struct device *dev, int slot, int sleep, - int vdd, int cardsleep) - { - struct omap_hsmmc_host *host = -@@ -365,6 +371,12 @@ - return regulator_enable(host->vcc_aux); - } - -+static int omap_hsmmc_4_set_sleep(struct device *dev, int slot, int sleep, -+ int vdd, int cardsleep) -+{ -+ return 0; -+} -+ - static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) - { - struct regulator *reg; -@@ -379,10 +391,14 @@ - break; - case OMAP_MMC2_DEVID: - case OMAP_MMC3_DEVID: -+ case OMAP_MMC5_DEVID: - /* Off-chip level shifting, or none */ -- mmc_slot(host).set_power = omap_hsmmc_23_set_power; -- mmc_slot(host).set_sleep = omap_hsmmc_23_set_sleep; -+ mmc_slot(host).set_power = omap_hsmmc_235_set_power; -+ mmc_slot(host).set_sleep = omap_hsmmc_235_set_sleep; - break; -+ case OMAP_MMC4_DEVID: -+ mmc_slot(host).set_power = omap_hsmmc_4_set_power; -+ mmc_slot(host).set_sleep = omap_hsmmc_4_set_sleep; - default: - pr_err("MMC%d configuration not supported!\n", host->id); - return -EINVAL; -@@ -1555,7 +1571,7 @@ - break; - } - -- if (host->id == OMAP_MMC1_DEVID) { -+ if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { - /* Only MMC1 can interface at 3V without some flavor - * of external transceiver; but they all handle 1.8V. - */ -@@ -1647,7 +1663,7 @@ - u32 hctl, capa, value; - - /* Only MMC1 supports 3.0V */ -- if (host->id == OMAP_MMC1_DEVID) { -+ if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) { - hctl = SDVS30; - capa = VS30 | VS18; - } else { -diff -Naur linux-2.6.38-rc7/drivers/mtd/nand/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/nand/Kconfig ---- linux-2.6.38-rc7/drivers/mtd/nand/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/nand/Kconfig 2011-03-09 13:19:15.269396887 +0100 -@@ -106,23 +106,6 @@ - help - Support for NAND flash on Texas Instruments OMAP2 and OMAP3 platforms. - --config MTD_NAND_OMAP_PREFETCH -- bool "GPMC prefetch support for NAND Flash device" -- depends on MTD_NAND_OMAP2 -- default y -- help -- The NAND device can be accessed for Read/Write using GPMC PREFETCH engine -- to improve the performance. -- --config MTD_NAND_OMAP_PREFETCH_DMA -- depends on MTD_NAND_OMAP_PREFETCH -- bool "DMA mode" -- default n -- help -- The GPMC PREFETCH engine can be configured eigther in MPU interrupt mode -- or in DMA interrupt mode. -- Say y for DMA mode or MPU mode will be used -- - config MTD_NAND_IDS - tristate - -diff -Naur linux-2.6.38-rc7/drivers/mtd/nand/omap2.c linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/nand/omap2.c ---- linux-2.6.38-rc7/drivers/mtd/nand/omap2.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/nand/omap2.c 2011-03-09 13:19:15.281396643 +0100 -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -24,6 +25,7 @@ - #include - - #define DRIVER_NAME "omap2-nand" -+#define OMAP_NAND_TIMEOUT_MS 5000 - - #define NAND_Ecc_P1e (1 << 0) - #define NAND_Ecc_P2e (1 << 1) -@@ -96,26 +98,19 @@ - static const char *part_probes[] = { "cmdlinepart", NULL }; - #endif - --#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH --static int use_prefetch = 1; -+/* oob info generated runtime depending on ecc algorithm and layout selected */ -+static struct nand_ecclayout omap_oobinfo; -+/* Define some generic bad / good block scan pattern which are used -+ * while scanning a device for factory marked good / bad blocks -+ */ -+static uint8_t scan_ff_pattern[] = { 0xff }; -+static struct nand_bbt_descr bb_descrip_flashbased = { -+ .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, -+ .offs = 0, -+ .len = 1, -+ .pattern = scan_ff_pattern, -+}; - --/* "modprobe ... use_prefetch=0" etc */ --module_param(use_prefetch, bool, 0); --MODULE_PARM_DESC(use_prefetch, "enable/disable use of PREFETCH"); -- --#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA --static int use_dma = 1; -- --/* "modprobe ... use_dma=0" etc */ --module_param(use_dma, bool, 0); --MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); --#else --static const int use_dma; --#endif --#else --const int use_prefetch; --static const int use_dma; --#endif - - struct omap_nand_info { - struct nand_hw_control controller; -@@ -129,6 +124,13 @@ - unsigned long phys_base; - struct completion comp; - int dma_ch; -+ int gpmc_irq; -+ enum { -+ OMAP_NAND_IO_READ = 0, /* read */ -+ OMAP_NAND_IO_WRITE, /* write */ -+ } iomode; -+ u_char *buf; -+ int buf_len; - }; - - /** -@@ -256,7 +258,8 @@ - } - - /* configure and start prefetch transfer */ -- ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x0); -+ ret = gpmc_prefetch_enable(info->gpmc_cs, -+ PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); - if (ret) { - /* PFPW engine is busy, use cpu copy method */ - if (info->nand.options & NAND_BUSWIDTH_16) -@@ -288,9 +291,10 @@ - { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); -- uint32_t pref_count = 0, w_count = 0; -+ uint32_t w_count = 0; - int i = 0, ret = 0; - u16 *p; -+ unsigned long tim, limit; - - /* take care of subpage writes */ - if (len % 2 != 0) { -@@ -300,7 +304,8 @@ - } - - /* configure and start prefetch transfer */ -- ret = gpmc_prefetch_enable(info->gpmc_cs, 0x0, len, 0x1); -+ ret = gpmc_prefetch_enable(info->gpmc_cs, -+ PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); - if (ret) { - /* PFPW engine is busy, use cpu copy method */ - if (info->nand.options & NAND_BUSWIDTH_16) -@@ -316,15 +321,17 @@ - iowrite16(*p++, info->nand.IO_ADDR_W); - } - /* wait for data to flushed-out before reset the prefetch */ -- do { -- pref_count = gpmc_read_status(GPMC_PREFETCH_COUNT); -- } while (pref_count); -+ tim = 0; -+ limit = (loops_per_jiffy * -+ msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); -+ while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) -+ cpu_relax(); -+ - /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); - } - } - --#ifdef CONFIG_MTD_NAND_OMAP_PREFETCH_DMA - /* - * omap_nand_dma_cb: callback on the completion of dma transfer - * @lch: logical channel -@@ -348,14 +355,15 @@ - { - struct omap_nand_info *info = container_of(mtd, - struct omap_nand_info, mtd); -- uint32_t prefetch_status = 0; - enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : - DMA_FROM_DEVICE; - dma_addr_t dma_addr; - int ret; -+ unsigned long tim, limit; - -- /* The fifo depth is 64 bytes. We have a sync at each frame and frame -- * length is 64 bytes. -+ /* The fifo depth is 64 bytes max. -+ * But configure the FIFO-threahold to 32 to get a sync at each frame -+ * and frame length is 32 bytes. - */ - int buf_len = len >> 6; - -@@ -396,9 +404,10 @@ - OMAP24XX_DMA_GPMC, OMAP_DMA_SRC_SYNC); - } - /* configure and start prefetch transfer */ -- ret = gpmc_prefetch_enable(info->gpmc_cs, 0x1, len, is_write); -+ ret = gpmc_prefetch_enable(info->gpmc_cs, -+ PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); - if (ret) -- /* PFPW engine is busy, use cpu copy methode */ -+ /* PFPW engine is busy, use cpu copy method */ - goto out_copy; - - init_completion(&info->comp); -@@ -407,10 +416,11 @@ - - /* setup and start DMA using dma_addr */ - wait_for_completion(&info->comp); -+ tim = 0; -+ limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); -+ while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) -+ cpu_relax(); - -- do { -- prefetch_status = gpmc_read_status(GPMC_PREFETCH_COUNT); -- } while (prefetch_status); - /* disable and stop the PFPW engine */ - gpmc_prefetch_reset(info->gpmc_cs); - -@@ -426,14 +436,6 @@ - : omap_write_buf8(mtd, (u_char *) addr, len); - return 0; - } --#else --static void omap_nand_dma_cb(int lch, u16 ch_status, void *data) {} --static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, -- unsigned int len, int is_write) --{ -- return 0; --} --#endif - - /** - * omap_read_buf_dma_pref - read data from NAND controller into buffer -@@ -466,6 +468,157 @@ - omap_nand_dma_transfer(mtd, (u_char *) buf, len, 0x1); - } - -+/* -+ * omap_nand_irq - GMPC irq handler -+ * @this_irq: gpmc irq number -+ * @dev: omap_nand_info structure pointer is passed here -+ */ -+static irqreturn_t omap_nand_irq(int this_irq, void *dev) -+{ -+ struct omap_nand_info *info = (struct omap_nand_info *) dev; -+ u32 bytes; -+ u32 irq_stat; -+ -+ irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); -+ bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); -+ bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ -+ if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ -+ if (irq_stat & 0x2) -+ goto done; -+ -+ if (info->buf_len && (info->buf_len < bytes)) -+ bytes = info->buf_len; -+ else if (!info->buf_len) -+ bytes = 0; -+ iowrite32_rep(info->nand.IO_ADDR_W, -+ (u32 *)info->buf, bytes >> 2); -+ info->buf = info->buf + bytes; -+ info->buf_len -= bytes; -+ -+ } else { -+ ioread32_rep(info->nand.IO_ADDR_R, -+ (u32 *)info->buf, bytes >> 2); -+ info->buf = info->buf + bytes; -+ -+ if (irq_stat & 0x2) -+ goto done; -+ } -+ gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); -+ -+ return IRQ_HANDLED; -+ -+done: -+ complete(&info->comp); -+ /* disable irq */ -+ gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0); -+ -+ /* clear status */ -+ gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); -+ -+ return IRQ_HANDLED; -+} -+ -+/* -+ * omap_read_buf_irq_pref - read data from NAND controller into buffer -+ * @mtd: MTD device structure -+ * @buf: buffer to store date -+ * @len: number of bytes to read -+ */ -+static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) -+{ -+ struct omap_nand_info *info = container_of(mtd, -+ struct omap_nand_info, mtd); -+ int ret = 0; -+ -+ if (len <= mtd->oobsize) { -+ omap_read_buf_pref(mtd, buf, len); -+ return; -+ } -+ -+ info->iomode = OMAP_NAND_IO_READ; -+ info->buf = buf; -+ init_completion(&info->comp); -+ -+ /* configure and start prefetch transfer */ -+ ret = gpmc_prefetch_enable(info->gpmc_cs, -+ PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0); -+ if (ret) -+ /* PFPW engine is busy, use cpu copy method */ -+ goto out_copy; -+ -+ info->buf_len = len; -+ /* enable irq */ -+ gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, -+ (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); -+ -+ /* waiting for read to complete */ -+ wait_for_completion(&info->comp); -+ -+ /* disable and stop the PFPW engine */ -+ gpmc_prefetch_reset(info->gpmc_cs); -+ return; -+ -+out_copy: -+ if (info->nand.options & NAND_BUSWIDTH_16) -+ omap_read_buf16(mtd, buf, len); -+ else -+ omap_read_buf8(mtd, buf, len); -+} -+ -+/* -+ * omap_write_buf_irq_pref - write buffer to NAND controller -+ * @mtd: MTD device structure -+ * @buf: data buffer -+ * @len: number of bytes to write -+ */ -+static void omap_write_buf_irq_pref(struct mtd_info *mtd, -+ const u_char *buf, int len) -+{ -+ struct omap_nand_info *info = container_of(mtd, -+ struct omap_nand_info, mtd); -+ int ret = 0; -+ unsigned long tim, limit; -+ -+ if (len <= mtd->oobsize) { -+ omap_write_buf_pref(mtd, buf, len); -+ return; -+ } -+ -+ info->iomode = OMAP_NAND_IO_WRITE; -+ info->buf = (u_char *) buf; -+ init_completion(&info->comp); -+ -+ /* configure and start prefetch transfer : size=24 */ -+ ret = gpmc_prefetch_enable(info->gpmc_cs, -+ (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1); -+ if (ret) -+ /* PFPW engine is busy, use cpu copy method */ -+ goto out_copy; -+ -+ info->buf_len = len; -+ /* enable irq */ -+ gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, -+ (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); -+ -+ /* waiting for write to complete */ -+ wait_for_completion(&info->comp); -+ /* wait for data to flushed-out before reset the prefetch */ -+ tim = 0; -+ limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); -+ while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) -+ cpu_relax(); -+ -+ /* disable and stop the PFPW engine */ -+ gpmc_prefetch_reset(info->gpmc_cs); -+ return; -+ -+out_copy: -+ if (info->nand.options & NAND_BUSWIDTH_16) -+ omap_write_buf16(mtd, buf, len); -+ else -+ omap_write_buf8(mtd, buf, len); -+} -+ - /** - * omap_verify_buf - Verify chip data against buffer - * @mtd: MTD device structure -@@ -487,8 +640,6 @@ - return 0; - } - --#ifdef CONFIG_MTD_NAND_OMAP_HWECC -- - /** - * gen_true_ecc - This function will generate true ECC value - * @ecc_buf: buffer to store ecc code -@@ -708,8 +859,6 @@ - gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); - } - --#endif -- - /** - * omap_wait - wait until the command is done - * @mtd: MTD device structure -@@ -779,6 +928,7 @@ - struct omap_nand_info *info; - struct omap_nand_platform_data *pdata; - int err; -+ int i, offset; - - pdata = pdev->dev.platform_data; - if (pdata == NULL) { -@@ -804,7 +954,7 @@ - info->mtd.name = dev_name(&pdev->dev); - info->mtd.owner = THIS_MODULE; - -- info->nand.options |= pdata->devsize ? NAND_BUSWIDTH_16 : 0; -+ info->nand.options = pdata->devsize; - info->nand.options |= NAND_SKIP_BBTSCAN; - - /* NAND write protect off */ -@@ -842,28 +992,13 @@ - info->nand.chip_delay = 50; - } - -- if (use_prefetch) { -- -+ switch (pdata->xfer_type) { -+ case NAND_OMAP_PREFETCH_POLLED: - info->nand.read_buf = omap_read_buf_pref; - info->nand.write_buf = omap_write_buf_pref; -- if (use_dma) { -- err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", -- omap_nand_dma_cb, &info->comp, &info->dma_ch); -- if (err < 0) { -- info->dma_ch = -1; -- printk(KERN_WARNING "DMA request failed." -- " Non-dma data transfer mode\n"); -- } else { -- omap_set_dma_dest_burst_mode(info->dma_ch, -- OMAP_DMA_DATA_BURST_16); -- omap_set_dma_src_burst_mode(info->dma_ch, -- OMAP_DMA_DATA_BURST_16); -- -- info->nand.read_buf = omap_read_buf_dma_pref; -- info->nand.write_buf = omap_write_buf_dma_pref; -- } -- } -- } else { -+ break; -+ -+ case NAND_OMAP_POLLED: - if (info->nand.options & NAND_BUSWIDTH_16) { - info->nand.read_buf = omap_read_buf16; - info->nand.write_buf = omap_write_buf16; -@@ -871,20 +1006,61 @@ - info->nand.read_buf = omap_read_buf8; - info->nand.write_buf = omap_write_buf8; - } -+ break; -+ -+ case NAND_OMAP_PREFETCH_DMA: -+ err = omap_request_dma(OMAP24XX_DMA_GPMC, "NAND", -+ omap_nand_dma_cb, &info->comp, &info->dma_ch); -+ if (err < 0) { -+ info->dma_ch = -1; -+ dev_err(&pdev->dev, "DMA request failed!\n"); -+ goto out_release_mem_region; -+ } else { -+ omap_set_dma_dest_burst_mode(info->dma_ch, -+ OMAP_DMA_DATA_BURST_16); -+ omap_set_dma_src_burst_mode(info->dma_ch, -+ OMAP_DMA_DATA_BURST_16); -+ -+ info->nand.read_buf = omap_read_buf_dma_pref; -+ info->nand.write_buf = omap_write_buf_dma_pref; -+ } -+ break; -+ -+ case NAND_OMAP_PREFETCH_IRQ: -+ err = request_irq(pdata->gpmc_irq, -+ omap_nand_irq, IRQF_SHARED, "gpmc-nand", info); -+ if (err) { -+ dev_err(&pdev->dev, "requesting irq(%d) error:%d", -+ pdata->gpmc_irq, err); -+ goto out_release_mem_region; -+ } else { -+ info->gpmc_irq = pdata->gpmc_irq; -+ info->nand.read_buf = omap_read_buf_irq_pref; -+ info->nand.write_buf = omap_write_buf_irq_pref; -+ } -+ break; -+ -+ default: -+ dev_err(&pdev->dev, -+ "xfer_type(%d) not supported!\n", pdata->xfer_type); -+ err = -EINVAL; -+ goto out_release_mem_region; - } -- info->nand.verify_buf = omap_verify_buf; - --#ifdef CONFIG_MTD_NAND_OMAP_HWECC -- info->nand.ecc.bytes = 3; -- info->nand.ecc.size = 512; -- info->nand.ecc.calculate = omap_calculate_ecc; -- info->nand.ecc.hwctl = omap_enable_hwecc; -- info->nand.ecc.correct = omap_correct_data; -- info->nand.ecc.mode = NAND_ECC_HW; -+ info->nand.verify_buf = omap_verify_buf; - --#else -- info->nand.ecc.mode = NAND_ECC_SOFT; --#endif -+ /* selsect the ecc type */ -+ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT) -+ info->nand.ecc.mode = NAND_ECC_SOFT; -+ else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) || -+ (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) { -+ info->nand.ecc.bytes = 3; -+ info->nand.ecc.size = 512; -+ info->nand.ecc.calculate = omap_calculate_ecc; -+ info->nand.ecc.hwctl = omap_enable_hwecc; -+ info->nand.ecc.correct = omap_correct_data; -+ info->nand.ecc.mode = NAND_ECC_HW; -+ } - - /* DIP switches on some boards change between 8 and 16 bit - * bus widths for flash. Try the other width if the first try fails. -@@ -897,6 +1073,26 @@ - } - } - -+ /* rom code layout */ -+ if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) { -+ -+ if (info->nand.options & NAND_BUSWIDTH_16) -+ offset = 2; -+ else { -+ offset = 1; -+ info->nand.badblock_pattern = &bb_descrip_flashbased; -+ } -+ omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16); -+ for (i = 0; i < omap_oobinfo.eccbytes; i++) -+ omap_oobinfo.eccpos[i] = i+offset; -+ -+ omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes; -+ omap_oobinfo.oobfree->length = info->mtd.oobsize - -+ (offset + omap_oobinfo.eccbytes); -+ -+ info->nand.ecc.layout = &omap_oobinfo; -+ } -+ - #ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); - if (err > 0) -@@ -926,9 +1122,12 @@ - mtd); - - platform_set_drvdata(pdev, NULL); -- if (use_dma) -+ if (info->dma_ch != -1) - omap_free_dma(info->dma_ch); - -+ if (info->gpmc_irq) -+ free_irq(info->gpmc_irq, info); -+ - /* Release NAND device, its internal structures and partitions */ - nand_release(&info->mtd); - iounmap(info->nand.IO_ADDR_R); -@@ -947,16 +1146,8 @@ - - static int __init omap_nand_init(void) - { -- printk(KERN_INFO "%s driver initializing\n", DRIVER_NAME); -+ pr_info("%s driver initializing\n", DRIVER_NAME); - -- /* This check is required if driver is being -- * loaded run time as a module -- */ -- if ((1 == use_dma) && (0 == use_prefetch)) { -- printk(KERN_INFO"Wrong parameters: 'use_dma' can not be 1 " -- "without use_prefetch'. Prefetch will not be" -- " used in either mode (mpu or dma)\n"); -- } - return platform_driver_register(&omap_nand_driver); - } - -diff -Naur linux-2.6.38-rc7/drivers/mtd/onenand/omap2.c linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/onenand/omap2.c ---- linux-2.6.38-rc7/drivers/mtd/onenand/omap2.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/mtd/onenand/omap2.c 2011-03-09 13:19:15.286396542 +0100 -@@ -63,7 +63,7 @@ - struct completion dma_done; - int dma_channel; - int freq; -- int (*setup)(void __iomem *base, int freq); -+ int (*setup)(void __iomem *base, int *freq_ptr); - struct regulator *regulator; - }; - -@@ -148,11 +148,9 @@ - wait_err("controller error", state, ctrl, intr); - return -EIO; - } -- if ((intr & intr_flags) != intr_flags) { -- wait_err("timeout", state, ctrl, intr); -- return -EIO; -- } -- return 0; -+ if ((intr & intr_flags) == intr_flags) -+ return 0; -+ /* Continue in wait for interrupt branch */ - } - - if (state != FL_READING) { -@@ -581,7 +579,7 @@ - - /* DMA is not in use so this is all that is needed */ - /* Revisit for OMAP3! */ -- ret = c->setup(c->onenand.base, c->freq); -+ ret = c->setup(c->onenand.base, &c->freq); - - return ret; - } -@@ -673,7 +671,7 @@ - } - - if (pdata->onenand_setup != NULL) { -- r = pdata->onenand_setup(c->onenand.base, c->freq); -+ r = pdata->onenand_setup(c->onenand.base, &c->freq); - if (r < 0) { - dev_err(&pdev->dev, "Onenand platform setup failed: " - "%d\n", r); -@@ -718,8 +716,8 @@ - } - - dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " -- "base %p\n", c->gpmc_cs, c->phys_base, -- c->onenand.base); -+ "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base, -+ c->onenand.base, c->freq); - - c->pdev = pdev; - c->mtd.name = dev_name(&pdev->dev); -@@ -754,24 +752,6 @@ - if ((r = onenand_scan(&c->mtd, 1)) < 0) - goto err_release_regulator; - -- switch ((c->onenand.version_id >> 4) & 0xf) { -- case 0: -- c->freq = 40; -- break; -- case 1: -- c->freq = 54; -- break; -- case 2: -- c->freq = 66; -- break; -- case 3: -- c->freq = 83; -- break; -- case 4: -- c->freq = 104; -- break; -- } -- - #ifdef CONFIG_MTD_PARTITIONS - r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0); - if (r > 0) -diff -Naur linux-2.6.38-rc7/drivers/spi/omap2_mcspi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/spi/omap2_mcspi.c ---- linux-2.6.38-rc7/drivers/spi/omap2_mcspi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/spi/omap2_mcspi.c 2011-03-09 13:19:17.550350615 +0100 -@@ -3,7 +3,7 @@ - * - * Copyright (C) 2005, 2006 Nokia Corporation - * Author: Samuel Ortiz and -- * Juha Yrjölä -+ * Juha Yrj�l� - * - * 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 -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - #include - -@@ -46,7 +47,6 @@ - #define OMAP2_MCSPI_MAX_CTRL 4 - - #define OMAP2_MCSPI_REVISION 0x00 --#define OMAP2_MCSPI_SYSCONFIG 0x10 - #define OMAP2_MCSPI_SYSSTATUS 0x14 - #define OMAP2_MCSPI_IRQSTATUS 0x18 - #define OMAP2_MCSPI_IRQENABLE 0x1c -@@ -63,13 +63,6 @@ - - /* per-register bitmasks: */ - --#define OMAP2_MCSPI_SYSCONFIG_SMARTIDLE BIT(4) --#define OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) --#define OMAP2_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) --#define OMAP2_MCSPI_SYSCONFIG_SOFTRESET BIT(1) -- --#define OMAP2_MCSPI_SYSSTATUS_RESETDONE BIT(0) -- - #define OMAP2_MCSPI_MODULCTRL_SINGLE BIT(0) - #define OMAP2_MCSPI_MODULCTRL_MS BIT(2) - #define OMAP2_MCSPI_MODULCTRL_STEST BIT(3) -@@ -122,13 +115,12 @@ - spinlock_t lock; - struct list_head msg_queue; - struct spi_master *master; -- struct clk *ick; -- struct clk *fck; - /* Virtual base address of the controller */ - void __iomem *base; - unsigned long phys; - /* SPI1 has 4 channels, while SPI2 has 2 */ - struct omap2_mcspi_dma *dma_channels; -+ struct device *dev; - }; - - struct omap2_mcspi_cs { -@@ -144,7 +136,6 @@ - * corresponding registers are modified. - */ - struct omap2_mcspi_regs { -- u32 sysconfig; - u32 modulctrl; - u32 wakeupenable; - struct list_head cs; -@@ -268,9 +259,6 @@ - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_MODULCTRL, - omap2_mcspi_ctx[spi_cntrl->bus_num - 1].modulctrl); - -- mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_SYSCONFIG, -- omap2_mcspi_ctx[spi_cntrl->bus_num - 1].sysconfig); -- - mcspi_write_reg(spi_cntrl, OMAP2_MCSPI_WAKEUPENABLE, - omap2_mcspi_ctx[spi_cntrl->bus_num - 1].wakeupenable); - -@@ -280,20 +268,12 @@ - } - static void omap2_mcspi_disable_clocks(struct omap2_mcspi *mcspi) - { -- clk_disable(mcspi->ick); -- clk_disable(mcspi->fck); -+ pm_runtime_put_sync(mcspi->dev); - } - - static int omap2_mcspi_enable_clocks(struct omap2_mcspi *mcspi) - { -- if (clk_enable(mcspi->ick)) -- return -ENODEV; -- if (clk_enable(mcspi->fck)) -- return -ENODEV; -- -- omap2_mcspi_restore_ctx(mcspi); -- -- return 0; -+ return pm_runtime_get_sync(mcspi->dev); - } - - static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit) -@@ -819,8 +799,9 @@ - return ret; - } - -- if (omap2_mcspi_enable_clocks(mcspi)) -- return -ENODEV; -+ ret = omap2_mcspi_enable_clocks(mcspi); -+ if (ret < 0) -+ return ret; - - ret = omap2_mcspi_setup_transfer(spi, NULL); - omap2_mcspi_disable_clocks(mcspi); -@@ -863,10 +844,11 @@ - struct omap2_mcspi *mcspi; - - mcspi = container_of(work, struct omap2_mcspi, work); -- spin_lock_irq(&mcspi->lock); - -- if (omap2_mcspi_enable_clocks(mcspi)) -- goto out; -+ if (omap2_mcspi_enable_clocks(mcspi) < 0) -+ return; -+ -+ spin_lock_irq(&mcspi->lock); - - /* We only enable one channel at a time -- the one whose message is - * at the head of the queue -- although this controller would gladly -@@ -979,10 +961,9 @@ - spin_lock_irq(&mcspi->lock); - } - -- omap2_mcspi_disable_clocks(mcspi); -- --out: - spin_unlock_irq(&mcspi->lock); -+ -+ omap2_mcspi_disable_clocks(mcspi); - } - - static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) -@@ -1058,25 +1039,15 @@ - return 0; - } - --static int __init omap2_mcspi_reset(struct omap2_mcspi *mcspi) -+static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) - { - struct spi_master *master = mcspi->master; - u32 tmp; -+ int ret = 0; - -- if (omap2_mcspi_enable_clocks(mcspi)) -- return -1; -- -- mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, -- OMAP2_MCSPI_SYSCONFIG_SOFTRESET); -- do { -- tmp = mcspi_read_reg(master, OMAP2_MCSPI_SYSSTATUS); -- } while (!(tmp & OMAP2_MCSPI_SYSSTATUS_RESETDONE)); -- -- tmp = OMAP2_MCSPI_SYSCONFIG_AUTOIDLE | -- OMAP2_MCSPI_SYSCONFIG_ENAWAKEUP | -- OMAP2_MCSPI_SYSCONFIG_SMARTIDLE; -- mcspi_write_reg(master, OMAP2_MCSPI_SYSCONFIG, tmp); -- omap2_mcspi_ctx[master->bus_num - 1].sysconfig = tmp; -+ ret = omap2_mcspi_enable_clocks(mcspi); -+ if (ret < 0) -+ return ret; - - tmp = OMAP2_MCSPI_WAKEUPENABLE_WKEN; - mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, tmp); -@@ -1087,91 +1058,26 @@ - return 0; - } - --static u8 __initdata spi1_rxdma_id [] = { -- OMAP24XX_DMA_SPI1_RX0, -- OMAP24XX_DMA_SPI1_RX1, -- OMAP24XX_DMA_SPI1_RX2, -- OMAP24XX_DMA_SPI1_RX3, --}; -- --static u8 __initdata spi1_txdma_id [] = { -- OMAP24XX_DMA_SPI1_TX0, -- OMAP24XX_DMA_SPI1_TX1, -- OMAP24XX_DMA_SPI1_TX2, -- OMAP24XX_DMA_SPI1_TX3, --}; -- --static u8 __initdata spi2_rxdma_id[] = { -- OMAP24XX_DMA_SPI2_RX0, -- OMAP24XX_DMA_SPI2_RX1, --}; -- --static u8 __initdata spi2_txdma_id[] = { -- OMAP24XX_DMA_SPI2_TX0, -- OMAP24XX_DMA_SPI2_TX1, --}; -- --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ -- || defined(CONFIG_ARCH_OMAP4) --static u8 __initdata spi3_rxdma_id[] = { -- OMAP24XX_DMA_SPI3_RX0, -- OMAP24XX_DMA_SPI3_RX1, --}; -+static int omap_mcspi_runtime_resume(struct device *dev) -+{ -+ struct omap2_mcspi *mcspi; -+ struct spi_master *master; - --static u8 __initdata spi3_txdma_id[] = { -- OMAP24XX_DMA_SPI3_TX0, -- OMAP24XX_DMA_SPI3_TX1, --}; --#endif -+ master = dev_get_drvdata(dev); -+ mcspi = spi_master_get_devdata(master); -+ omap2_mcspi_restore_ctx(mcspi); - --#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) --static u8 __initdata spi4_rxdma_id[] = { -- OMAP34XX_DMA_SPI4_RX0, --}; -+ return 0; -+} - --static u8 __initdata spi4_txdma_id[] = { -- OMAP34XX_DMA_SPI4_TX0, --}; --#endif - - static int __init omap2_mcspi_probe(struct platform_device *pdev) - { - struct spi_master *master; -+ struct omap2_mcspi_platform_config *pdata = pdev->dev.platform_data; - struct omap2_mcspi *mcspi; - struct resource *r; - int status = 0, i; -- const u8 *rxdma_id, *txdma_id; -- unsigned num_chipselect; -- -- switch (pdev->id) { -- case 1: -- rxdma_id = spi1_rxdma_id; -- txdma_id = spi1_txdma_id; -- num_chipselect = 4; -- break; -- case 2: -- rxdma_id = spi2_rxdma_id; -- txdma_id = spi2_txdma_id; -- num_chipselect = 2; -- break; --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) \ -- || defined(CONFIG_ARCH_OMAP4) -- case 3: -- rxdma_id = spi3_rxdma_id; -- txdma_id = spi3_txdma_id; -- num_chipselect = 2; -- break; --#endif --#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) -- case 4: -- rxdma_id = spi4_rxdma_id; -- txdma_id = spi4_txdma_id; -- num_chipselect = 1; -- break; --#endif -- default: -- return -EINVAL; -- } - - master = spi_alloc_master(&pdev->dev, sizeof *mcspi); - if (master == NULL) { -@@ -1188,7 +1094,7 @@ - master->setup = omap2_mcspi_setup; - master->transfer = omap2_mcspi_transfer; - master->cleanup = omap2_mcspi_cleanup; -- master->num_chipselect = num_chipselect; -+ master->num_chipselect = pdata->num_cs; - - dev_set_drvdata(&pdev->dev, master); - -@@ -1206,49 +1112,62 @@ - goto err1; - } - -+ r->start += pdata->regs_offset; -+ r->end += pdata->regs_offset; - mcspi->phys = r->start; - mcspi->base = ioremap(r->start, r->end - r->start + 1); - if (!mcspi->base) { - dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); - status = -ENOMEM; -- goto err1aa; -+ goto err2; - } - -+ mcspi->dev = &pdev->dev; - INIT_WORK(&mcspi->work, omap2_mcspi_work); - - spin_lock_init(&mcspi->lock); - INIT_LIST_HEAD(&mcspi->msg_queue); - INIT_LIST_HEAD(&omap2_mcspi_ctx[master->bus_num - 1].cs); - -- mcspi->ick = clk_get(&pdev->dev, "ick"); -- if (IS_ERR(mcspi->ick)) { -- dev_dbg(&pdev->dev, "can't get mcspi_ick\n"); -- status = PTR_ERR(mcspi->ick); -- goto err1a; -- } -- mcspi->fck = clk_get(&pdev->dev, "fck"); -- if (IS_ERR(mcspi->fck)) { -- dev_dbg(&pdev->dev, "can't get mcspi_fck\n"); -- status = PTR_ERR(mcspi->fck); -- goto err2; -- } -- - mcspi->dma_channels = kcalloc(master->num_chipselect, - sizeof(struct omap2_mcspi_dma), - GFP_KERNEL); - - if (mcspi->dma_channels == NULL) -- goto err3; -+ goto err2; -+ -+ for (i = 0; i < master->num_chipselect; i++) { -+ char dma_ch_name[14]; -+ struct resource *dma_res; -+ -+ sprintf(dma_ch_name, "rx%d", i); -+ dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, -+ dma_ch_name); -+ if (!dma_res) { -+ dev_dbg(&pdev->dev, "cannot get DMA RX channel\n"); -+ status = -ENODEV; -+ break; -+ } - -- for (i = 0; i < num_chipselect; i++) { - mcspi->dma_channels[i].dma_rx_channel = -1; -- mcspi->dma_channels[i].dma_rx_sync_dev = rxdma_id[i]; -+ mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; -+ sprintf(dma_ch_name, "tx%d", i); -+ dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, -+ dma_ch_name); -+ if (!dma_res) { -+ dev_dbg(&pdev->dev, "cannot get DMA TX channel\n"); -+ status = -ENODEV; -+ break; -+ } -+ - mcspi->dma_channels[i].dma_tx_channel = -1; -- mcspi->dma_channels[i].dma_tx_sync_dev = txdma_id[i]; -+ mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start; - } - -- if (omap2_mcspi_reset(mcspi) < 0) -- goto err4; -+ pm_runtime_enable(&pdev->dev); -+ -+ if (status || omap2_mcspi_master_setup(mcspi) < 0) -+ goto err3; - - status = spi_register_master(master); - if (status < 0) -@@ -1257,17 +1176,13 @@ - return status; - - err4: -- kfree(mcspi->dma_channels); -+ spi_master_put(master); - err3: -- clk_put(mcspi->fck); -+ kfree(mcspi->dma_channels); - err2: -- clk_put(mcspi->ick); --err1a: -- iounmap(mcspi->base); --err1aa: - release_mem_region(r->start, (r->end - r->start) + 1); -+ iounmap(mcspi->base); - err1: -- spi_master_put(master); - return status; - } - -@@ -1283,9 +1198,7 @@ - mcspi = spi_master_get_devdata(master); - dma_channels = mcspi->dma_channels; - -- clk_put(mcspi->fck); -- clk_put(mcspi->ick); -- -+ omap2_mcspi_disable_clocks(mcspi); - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(r->start, (r->end - r->start) + 1); - -@@ -1336,6 +1249,7 @@ - - static const struct dev_pm_ops omap2_mcspi_pm_ops = { - .resume = omap2_mcspi_resume, -+ .runtime_resume = omap_mcspi_runtime_resume, - }; - - static struct platform_driver omap2_mcspi_driver = { -diff -Naur linux-2.6.38-rc7/drivers/usb/musb/musb_core.c linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musb_core.c ---- linux-2.6.38-rc7/drivers/usb/musb/musb_core.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musb_core.c 2011-03-09 13:19:19.480311463 +0100 -@@ -1530,7 +1530,7 @@ - - /*-------------------------------------------------------------------------*/ - --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) || \ -+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ - defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \ - defined(CONFIG_ARCH_U5500) - -diff -Naur linux-2.6.38-rc7/drivers/usb/musb/musb_core.h linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musb_core.h ---- linux-2.6.38-rc7/drivers/usb/musb/musb_core.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musb_core.h 2011-03-09 13:19:19.480311463 +0100 -@@ -212,8 +212,8 @@ - * directly with the "flat" model, or after setting up an index register. - */ - --#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_ARCH_OMAP2430) \ -- || defined(CONFIG_ARCH_OMAP3430) || defined(CONFIG_BLACKFIN) \ -+#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_SOC_OMAP2430) \ -+ || defined(CONFIG_SOC_OMAP3430) || defined(CONFIG_BLACKFIN) \ - || defined(CONFIG_ARCH_OMAP4) - /* REVISIT indexed access seemed to - * misbehave (on DaVinci) for at least peripheral IN ... -@@ -358,7 +358,7 @@ - - struct musb_context_registers { - --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ -+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ - defined(CONFIG_ARCH_OMAP4) - u32 otg_sysconfig, otg_forcestandby; - #endif -diff -Naur linux-2.6.38-rc7/drivers/usb/musb/musbhsdma.h linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musbhsdma.h ---- linux-2.6.38-rc7/drivers/usb/musb/musbhsdma.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/musb/musbhsdma.h 2011-03-09 13:19:19.484311381 +0100 -@@ -31,7 +31,7 @@ - * - */ - --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -+#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) - #include "omap2430.h" - #endif - -diff -Naur linux-2.6.38-rc7/drivers/usb/otg/isp1301_omap.c linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/otg/isp1301_omap.c ---- linux-2.6.38-rc7/drivers/usb/otg/isp1301_omap.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/usb/otg/isp1301_omap.c 2011-03-09 13:19:19.487311321 +0100 -@@ -1510,7 +1510,7 @@ - - /*-------------------------------------------------------------------------*/ - --static int __init -+static int __devinit - isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id) - { - int status; -diff -Naur linux-2.6.38-rc7/drivers/video/omap/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap/Kconfig ---- linux-2.6.38-rc7/drivers/video/omap/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap/Kconfig 2011-03-09 13:19:21.072279166 +0100 -@@ -5,13 +5,18 @@ - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT -+ select TWL4030_CORE if MACH_OMAP_2430SDP - help - Frame buffer driver for OMAP based boards. - - config FB_OMAP_LCD_VGA - bool "Use LCD in VGA mode" - depends on MACH_OMAP_3430SDP || MACH_OMAP_LDP -- -+ help -+ Set LCD resolution as VGA (640 X 480). -+ Default resolution without this option is QVGA(320 X 240). -+ Please take a look at drivers/video/omap/lcd_ldp.c file -+ for lcd driver code. - choice - depends on FB_OMAP && MACH_OVERO - prompt "Screen resolution" -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/displays/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/Kconfig ---- linux-2.6.38-rc7/drivers/video/omap2/displays/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/Kconfig 2011-03-09 13:19:21.079279025 +0100 -@@ -9,6 +9,12 @@ - Supports LCD Panel used in TI SDP3430 and EVM boards, - OMAP3517 EVM boards and CM-T35. - -+config PANEL_LGPHILIPS_LB035Q02 -+ tristate "LG.Philips LB035Q02 LCD Panel" -+ depends on OMAP2_DSS && SPI -+ help -+ LCD Panel used on the Gumstix Overo Palo35 -+ - config PANEL_SHARP_LS037V7DW01 - tristate "Sharp LS037V7DW01 LCD Panel" - depends on OMAP2_DSS -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/displays/Makefile linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/Makefile ---- linux-2.6.38-rc7/drivers/video/omap2/displays/Makefile 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/Makefile 2011-03-09 13:19:21.079279025 +0100 -@@ -1,4 +1,5 @@ - obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o -+obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o - obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o - obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o - -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/displays/panel-generic-dpi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-generic-dpi.c ---- linux-2.6.38-rc7/drivers/video/omap2/displays/panel-generic-dpi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-generic-dpi.c 2011-03-09 13:19:21.080279004 +0100 -@@ -156,6 +156,31 @@ - .power_off_delay = 0, - .name = "toppoly_tdo35s", - }, -+ -+ /* Samsung LTE430WQ-F0C */ -+ { -+ { -+ .x_res = 480, -+ .y_res = 272, -+ -+ .pixel_clock = 9200, -+ -+ .hfp = 8, -+ .hsw = 41, -+ .hbp = 45 - 41, -+ -+ .vfp = 4, -+ .vsw = 10, -+ .vbp = 12 - 10, -+ }, -+ .acbi = 0x0, -+ .acb = 0x0, -+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | -+ OMAP_DSS_LCD_IHS, -+ .power_on_delay = 0, -+ .power_off_delay = 0, -+ .name = "samsung_lte430wq_f0c", -+ }, - }; - - struct panel_drv_data { -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c ---- linux-2.6.38-rc7/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c 2011-03-09 13:19:21.080279004 +0100 -@@ -0,0 +1,279 @@ -+/* -+ * LCD panel driver for LG.Philips LB035Q02 -+ * -+ * Author: Steve Sakoman -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+struct lb035q02_data { -+ struct mutex lock; -+}; -+ -+static struct omap_video_timings lb035q02_timings = { -+ .x_res = 320, -+ .y_res = 240, -+ -+ .pixel_clock = 6500, -+ -+ .hsw = 2, -+ .hfp = 20, -+ .hbp = 68, -+ -+ .vsw = 2, -+ .vfp = 4, -+ .vbp = 18, -+}; -+ -+static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) -+{ -+ int r; -+ -+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) -+ return 0; -+ -+ r = omapdss_dpi_display_enable(dssdev); -+ if (r) -+ goto err0; -+ -+ if (dssdev->platform_enable) { -+ r = dssdev->platform_enable(dssdev); -+ if (r) -+ goto err1; -+ } -+ -+ return 0; -+err1: -+ omapdss_dpi_display_disable(dssdev); -+err0: -+ return r; -+} -+ -+static void lb035q02_panel_power_off(struct omap_dss_device *dssdev) -+{ -+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) -+ return; -+ -+ if (dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+ -+ omapdss_dpi_display_disable(dssdev); -+} -+ -+static int lb035q02_panel_probe(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld; -+ int r; -+ -+ dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | -+ OMAP_DSS_LCD_IHS; -+ dssdev->panel.timings = lb035q02_timings; -+ -+ ld = kzalloc(sizeof(*ld), GFP_KERNEL); -+ if (!ld) { -+ r = -ENOMEM; -+ goto err; -+ } -+ mutex_init(&ld->lock); -+ dev_set_drvdata(&dssdev->dev, ld); -+ return 0; -+err: -+ return r; -+} -+ -+static void lb035q02_panel_remove(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); -+ -+ kfree(ld); -+} -+ -+static int lb035q02_panel_enable(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); -+ int r; -+ -+ mutex_lock(&ld->lock); -+ -+ r = lb035q02_panel_power_on(dssdev); -+ if (r) -+ goto err; -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+ mutex_unlock(&ld->lock); -+ return 0; -+err: -+ mutex_unlock(&ld->lock); -+ return r; -+} -+ -+static void lb035q02_panel_disable(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); -+ -+ mutex_lock(&ld->lock); -+ -+ lb035q02_panel_power_off(dssdev); -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+ -+ mutex_unlock(&ld->lock); -+} -+ -+static int lb035q02_panel_suspend(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); -+ -+ mutex_lock(&ld->lock); -+ -+ lb035q02_panel_power_off(dssdev); -+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; -+ -+ mutex_unlock(&ld->lock); -+ return 0; -+} -+ -+static int lb035q02_panel_resume(struct omap_dss_device *dssdev) -+{ -+ struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); -+ int r; -+ -+ mutex_lock(&ld->lock); -+ -+ r = lb035q02_panel_power_on(dssdev); -+ if (r) -+ goto err; -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+ mutex_unlock(&ld->lock); -+ return 0; -+err: -+ mutex_unlock(&ld->lock); -+ return r; -+} -+ -+static struct omap_dss_driver lb035q02_driver = { -+ .probe = lb035q02_panel_probe, -+ .remove = lb035q02_panel_remove, -+ -+ .enable = lb035q02_panel_enable, -+ .disable = lb035q02_panel_disable, -+ .suspend = lb035q02_panel_suspend, -+ .resume = lb035q02_panel_resume, -+ -+ .driver = { -+ .name = "lgphilips_lb035q02_panel", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int lb035q02_write_reg(struct spi_device *spi, u8 reg, u16 val) -+{ -+ struct spi_message msg; -+ struct spi_transfer index_xfer = { -+ .len = 3, -+ .cs_change = 1, -+ }; -+ struct spi_transfer value_xfer = { -+ .len = 3, -+ }; -+ u8 buffer[16]; -+ -+ spi_message_init(&msg); -+ -+ /* register index */ -+ buffer[0] = 0x70; -+ buffer[1] = 0x00; -+ buffer[2] = reg & 0x7f; -+ index_xfer.tx_buf = buffer; -+ spi_message_add_tail(&index_xfer, &msg); -+ -+ /* register value */ -+ buffer[4] = 0x72; -+ buffer[5] = val >> 8; -+ buffer[6] = val; -+ value_xfer.tx_buf = buffer + 4; -+ spi_message_add_tail(&value_xfer, &msg); -+ -+ return spi_sync(spi, &msg); -+} -+ -+static void init_lb035q02_panel(struct spi_device *spi) -+{ -+ /* Init sequence from page 28 of the lb035q02 spec */ -+ lb035q02_write_reg(spi, 0x01, 0x6300); -+ lb035q02_write_reg(spi, 0x02, 0x0200); -+ lb035q02_write_reg(spi, 0x03, 0x0177); -+ lb035q02_write_reg(spi, 0x04, 0x04c7); -+ lb035q02_write_reg(spi, 0x05, 0xffc0); -+ lb035q02_write_reg(spi, 0x06, 0xe806); -+ lb035q02_write_reg(spi, 0x0a, 0x4008); -+ lb035q02_write_reg(spi, 0x0b, 0x0000); -+ lb035q02_write_reg(spi, 0x0d, 0x0030); -+ lb035q02_write_reg(spi, 0x0e, 0x2800); -+ lb035q02_write_reg(spi, 0x0f, 0x0000); -+ lb035q02_write_reg(spi, 0x16, 0x9f80); -+ lb035q02_write_reg(spi, 0x17, 0x0a0f); -+ lb035q02_write_reg(spi, 0x1e, 0x00c1); -+ lb035q02_write_reg(spi, 0x30, 0x0300); -+ lb035q02_write_reg(spi, 0x31, 0x0007); -+ lb035q02_write_reg(spi, 0x32, 0x0000); -+ lb035q02_write_reg(spi, 0x33, 0x0000); -+ lb035q02_write_reg(spi, 0x34, 0x0707); -+ lb035q02_write_reg(spi, 0x35, 0x0004); -+ lb035q02_write_reg(spi, 0x36, 0x0302); -+ lb035q02_write_reg(spi, 0x37, 0x0202); -+ lb035q02_write_reg(spi, 0x3a, 0x0a0d); -+ lb035q02_write_reg(spi, 0x3b, 0x0806); -+} -+ -+static int __devinit lb035q02_panel_spi_probe(struct spi_device *spi) -+{ -+ init_lb035q02_panel(spi); -+ return omap_dss_register_driver(&lb035q02_driver); -+} -+ -+static int __devexit lb035q02_panel_spi_remove(struct spi_device *spi) -+{ -+ omap_dss_unregister_driver(&lb035q02_driver); -+ return 0; -+} -+ -+static struct spi_driver lb035q02_spi_driver = { -+ .driver = { -+ .name = "lgphilips_lb035q02_panel-spi", -+ .owner = THIS_MODULE, -+ }, -+ .probe = lb035q02_panel_spi_probe, -+ .remove = __devexit_p(lb035q02_panel_spi_remove), -+}; -+ -+static int __init lb035q02_panel_drv_init(void) -+{ -+ return spi_register_driver(&lb035q02_spi_driver); -+} -+ -+static void __exit lb035q02_panel_drv_exit(void) -+{ -+ spi_unregister_driver(&lb035q02_spi_driver); -+} -+ -+module_init(lb035q02_panel_drv_init); -+module_exit(lb035q02_panel_drv_exit); -+MODULE_LICENSE("GPL"); -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/displays/panel-taal.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-taal.c ---- linux-2.6.38-rc7/drivers/video/omap2/displays/panel-taal.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/displays/panel-taal.c 2011-03-09 13:19:21.081278983 +0100 -@@ -218,6 +218,8 @@ - u16 w; - u16 h; - } update_region; -+ int channel; -+ - struct delayed_work te_timeout_work; - - bool use_dsi_bl; -@@ -257,12 +259,12 @@ - } - } - --static int taal_dcs_read_1(u8 dcs_cmd, u8 *data) -+static int taal_dcs_read_1(struct taal_data *td, u8 dcs_cmd, u8 *data) - { - int r; - u8 buf[1]; - -- r = dsi_vc_dcs_read(TCH, dcs_cmd, buf, 1); -+ r = dsi_vc_dcs_read(td->channel, dcs_cmd, buf, 1); - - if (r < 0) - return r; -@@ -272,17 +274,17 @@ - return 0; - } - --static int taal_dcs_write_0(u8 dcs_cmd) -+static int taal_dcs_write_0(struct taal_data *td, u8 dcs_cmd) - { -- return dsi_vc_dcs_write(TCH, &dcs_cmd, 1); -+ return dsi_vc_dcs_write(td->channel, &dcs_cmd, 1); - } - --static int taal_dcs_write_1(u8 dcs_cmd, u8 param) -+static int taal_dcs_write_1(struct taal_data *td, u8 dcs_cmd, u8 param) - { - u8 buf[2]; - buf[0] = dcs_cmd; - buf[1] = param; -- return dsi_vc_dcs_write(TCH, buf, 2); -+ return dsi_vc_dcs_write(td->channel, buf, 2); - } - - static int taal_sleep_in(struct taal_data *td) -@@ -294,7 +296,7 @@ - hw_guard_wait(td); - - cmd = DCS_SLEEP_IN; -- r = dsi_vc_dcs_write_nosync(TCH, &cmd, 1); -+ r = dsi_vc_dcs_write_nosync(td->channel, &cmd, 1); - if (r) - return r; - -@@ -312,7 +314,7 @@ - - hw_guard_wait(td); - -- r = taal_dcs_write_0(DCS_SLEEP_OUT); -+ r = taal_dcs_write_0(td, DCS_SLEEP_OUT); - if (r) - return r; - -@@ -324,30 +326,30 @@ - return 0; - } - --static int taal_get_id(u8 *id1, u8 *id2, u8 *id3) -+static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3) - { - int r; - -- r = taal_dcs_read_1(DCS_GET_ID1, id1); -+ r = taal_dcs_read_1(td, DCS_GET_ID1, id1); - if (r) - return r; -- r = taal_dcs_read_1(DCS_GET_ID2, id2); -+ r = taal_dcs_read_1(td, DCS_GET_ID2, id2); - if (r) - return r; -- r = taal_dcs_read_1(DCS_GET_ID3, id3); -+ r = taal_dcs_read_1(td, DCS_GET_ID3, id3); - if (r) - return r; - - return 0; - } - --static int taal_set_addr_mode(u8 rotate, bool mirror) -+static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror) - { - int r; - u8 mode; - int b5, b6, b7; - -- r = taal_dcs_read_1(DCS_READ_MADCTL, &mode); -+ r = taal_dcs_read_1(td, DCS_READ_MADCTL, &mode); - if (r) - return r; - -@@ -381,10 +383,11 @@ - mode &= ~((1<<7) | (1<<6) | (1<<5)); - mode |= (b7 << 7) | (b6 << 6) | (b5 << 5); - -- return taal_dcs_write_1(DCS_MEM_ACC_CTRL, mode); -+ return taal_dcs_write_1(td, DCS_MEM_ACC_CTRL, mode); - } - --static int taal_set_update_window(u16 x, u16 y, u16 w, u16 h) -+static int taal_set_update_window(struct taal_data *td, -+ u16 x, u16 y, u16 w, u16 h) - { - int r; - u16 x1 = x; -@@ -399,7 +402,7 @@ - buf[3] = (x2 >> 8) & 0xff; - buf[4] = (x2 >> 0) & 0xff; - -- r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); -+ r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf)); - if (r) - return r; - -@@ -409,11 +412,11 @@ - buf[3] = (y2 >> 8) & 0xff; - buf[4] = (y2 >> 0) & 0xff; - -- r = dsi_vc_dcs_write_nosync(TCH, buf, sizeof(buf)); -+ r = dsi_vc_dcs_write_nosync(td->channel, buf, sizeof(buf)); - if (r) - return r; - -- dsi_vc_send_bta_sync(TCH); -+ dsi_vc_send_bta_sync(td->channel); - - return r; - } -@@ -439,7 +442,7 @@ - if (td->use_dsi_bl) { - if (td->enabled) { - dsi_bus_lock(); -- r = taal_dcs_write_1(DCS_BRIGHTNESS, level); -+ r = taal_dcs_write_1(td, DCS_BRIGHTNESS, level); - dsi_bus_unlock(); - } else { - r = 0; -@@ -502,7 +505,7 @@ - - if (td->enabled) { - dsi_bus_lock(); -- r = taal_dcs_read_1(DCS_READ_NUM_ERRORS, &errors); -+ r = taal_dcs_read_1(td, DCS_READ_NUM_ERRORS, &errors); - dsi_bus_unlock(); - } else { - r = -ENODEV; -@@ -528,7 +531,7 @@ - - if (td->enabled) { - dsi_bus_lock(); -- r = taal_get_id(&id1, &id2, &id3); -+ r = taal_get_id(td, &id1, &id2, &id3); - dsi_bus_unlock(); - } else { - r = -ENODEV; -@@ -590,7 +593,7 @@ - if (td->enabled) { - dsi_bus_lock(); - if (!td->cabc_broken) -- taal_dcs_write_1(DCS_WRITE_CABC, i); -+ taal_dcs_write_1(td, DCS_WRITE_CABC, i); - dsi_bus_unlock(); - } - -@@ -774,14 +777,29 @@ - dev_dbg(&dssdev->dev, "Using GPIO TE\n"); - } - -+ r = omap_dsi_request_vc(dssdev, &td->channel); -+ if (r) { -+ dev_err(&dssdev->dev, "failed to get virtual channel\n"); -+ goto err_req_vc; -+ } -+ -+ r = omap_dsi_set_vc_id(dssdev, td->channel, TCH); -+ if (r) { -+ dev_err(&dssdev->dev, "failed to set VC_ID\n"); -+ goto err_vc_id; -+ } -+ - r = sysfs_create_group(&dssdev->dev.kobj, &taal_attr_group); - if (r) { - dev_err(&dssdev->dev, "failed to create sysfs files\n"); -- goto err_sysfs; -+ goto err_vc_id; - } - - return 0; --err_sysfs: -+ -+err_vc_id: -+ omap_dsi_release_vc(dssdev, td->channel); -+err_req_vc: - if (panel_data->use_ext_te) - free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev); - err_irq: -@@ -808,6 +826,7 @@ - dev_dbg(&dssdev->dev, "remove\n"); - - sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group); -+ omap_dsi_release_vc(dssdev, td->channel); - - if (panel_data->use_ext_te) { - int gpio = panel_data->ext_te_gpio; -@@ -846,13 +865,13 @@ - - taal_hw_reset(dssdev); - -- omapdss_dsi_vc_enable_hs(TCH, false); -+ omapdss_dsi_vc_enable_hs(td->channel, false); - - r = taal_sleep_out(td); - if (r) - goto err; - -- r = taal_get_id(&id1, &id2, &id3); -+ r = taal_get_id(td, &id1, &id2, &id3); - if (r) - goto err; - -@@ -861,30 +880,30 @@ - (id2 == 0x00 || id2 == 0xff || id2 == 0x81)) - td->cabc_broken = true; - -- r = taal_dcs_write_1(DCS_BRIGHTNESS, 0xff); -+ r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff); - if (r) - goto err; - -- r = taal_dcs_write_1(DCS_CTRL_DISPLAY, -+ r = taal_dcs_write_1(td, DCS_CTRL_DISPLAY, - (1<<2) | (1<<5)); /* BL | BCTRL */ - if (r) - goto err; - -- r = taal_dcs_write_1(DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ -+ r = taal_dcs_write_1(td, DCS_PIXEL_FORMAT, 0x7); /* 24bit/pixel */ - if (r) - goto err; - -- r = taal_set_addr_mode(td->rotate, td->mirror); -+ r = taal_set_addr_mode(td, td->rotate, td->mirror); - if (r) - goto err; - - if (!td->cabc_broken) { -- r = taal_dcs_write_1(DCS_WRITE_CABC, td->cabc_mode); -+ r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode); - if (r) - goto err; - } - -- r = taal_dcs_write_0(DCS_DISPLAY_ON); -+ r = taal_dcs_write_0(td, DCS_DISPLAY_ON); - if (r) - goto err; - -@@ -903,7 +922,7 @@ - td->intro_printed = true; - } - -- omapdss_dsi_vc_enable_hs(TCH, true); -+ omapdss_dsi_vc_enable_hs(td->channel, true); - - return 0; - err: -@@ -921,7 +940,7 @@ - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - int r; - -- r = taal_dcs_write_0(DCS_DISPLAY_OFF); -+ r = taal_dcs_write_0(td, DCS_DISPLAY_OFF); - if (!r) { - r = taal_sleep_in(td); - /* HACK: wait a bit so that the message goes through */ -@@ -1089,7 +1108,7 @@ - if (old) { - cancel_delayed_work(&td->te_timeout_work); - -- r = omap_dsi_update(dssdev, TCH, -+ r = omap_dsi_update(dssdev, td->channel, - td->update_region.x, - td->update_region.y, - td->update_region.w, -@@ -1139,7 +1158,7 @@ - if (r) - goto err; - -- r = taal_set_update_window(x, y, w, h); -+ r = taal_set_update_window(td, x, y, w, h); - if (r) - goto err; - -@@ -1153,7 +1172,7 @@ - msecs_to_jiffies(250)); - atomic_set(&td->do_update, 1); - } else { -- r = omap_dsi_update(dssdev, TCH, x, y, w, h, -+ r = omap_dsi_update(dssdev, td->channel, x, y, w, h, - taal_framedone_cb, dssdev); - if (r) - goto err; -@@ -1191,9 +1210,9 @@ - int r; - - if (enable) -- r = taal_dcs_write_1(DCS_TEAR_ON, 0); -+ r = taal_dcs_write_1(td, DCS_TEAR_ON, 0); - else -- r = taal_dcs_write_0(DCS_TEAR_OFF); -+ r = taal_dcs_write_0(td, DCS_TEAR_OFF); - - if (!panel_data->use_ext_te) - omapdss_dsi_enable_te(dssdev, enable); -@@ -1263,7 +1282,7 @@ - dsi_bus_lock(); - - if (td->enabled) { -- r = taal_set_addr_mode(rotate, td->mirror); -+ r = taal_set_addr_mode(td, rotate, td->mirror); - if (r) - goto err; - } -@@ -1306,7 +1325,7 @@ - - dsi_bus_lock(); - if (td->enabled) { -- r = taal_set_addr_mode(td->rotate, enable); -+ r = taal_set_addr_mode(td, td->rotate, enable); - if (r) - goto err; - } -@@ -1350,13 +1369,13 @@ - - dsi_bus_lock(); - -- r = taal_dcs_read_1(DCS_GET_ID1, &id1); -+ r = taal_dcs_read_1(td, DCS_GET_ID1, &id1); - if (r) - goto err2; -- r = taal_dcs_read_1(DCS_GET_ID2, &id2); -+ r = taal_dcs_read_1(td, DCS_GET_ID2, &id2); - if (r) - goto err2; -- r = taal_dcs_read_1(DCS_GET_ID3, &id3); -+ r = taal_dcs_read_1(td, DCS_GET_ID3, &id3); - if (r) - goto err2; - -@@ -1404,9 +1423,9 @@ - else - plen = 2; - -- taal_set_update_window(x, y, w, h); -+ taal_set_update_window(td, x, y, w, h); - -- r = dsi_vc_set_max_rx_packet_size(TCH, plen); -+ r = dsi_vc_set_max_rx_packet_size(td->channel, plen); - if (r) - goto err2; - -@@ -1414,7 +1433,7 @@ - u8 dcs_cmd = first ? 0x2e : 0x3e; - first = 0; - -- r = dsi_vc_dcs_read(TCH, dcs_cmd, -+ r = dsi_vc_dcs_read(td->channel, dcs_cmd, - buf + buf_used, size - buf_used); - - if (r < 0) { -@@ -1440,7 +1459,7 @@ - r = buf_used; - - err3: -- dsi_vc_set_max_rx_packet_size(TCH, 1); -+ dsi_vc_set_max_rx_packet_size(td->channel, 1); - err2: - dsi_bus_unlock(); - err1: -@@ -1466,7 +1485,7 @@ - - dsi_bus_lock(); - -- r = taal_dcs_read_1(DCS_RDDSDR, &state1); -+ r = taal_dcs_read_1(td, DCS_RDDSDR, &state1); - if (r) { - dev_err(&dssdev->dev, "failed to read Taal status\n"); - goto err; -@@ -1479,7 +1498,7 @@ - goto err; - } - -- r = taal_dcs_read_1(DCS_RDDSDR, &state2); -+ r = taal_dcs_read_1(td, DCS_RDDSDR, &state2); - if (r) { - dev_err(&dssdev->dev, "failed to read Taal status\n"); - goto err; -@@ -1495,7 +1514,7 @@ - /* Self-diagnostics result is also shown on TE GPIO line. We need - * to re-enable TE after self diagnostics */ - if (td->te_enabled && panel_data->use_ext_te) { -- r = taal_dcs_write_1(DCS_TEAR_ON, 0); -+ r = taal_dcs_write_1(td, DCS_TEAR_ON, 0); - if (r) - goto err; - } -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/core.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/core.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/core.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/core.c 2011-03-09 13:19:21.083278942 +0100 -@@ -34,332 +34,26 @@ - #include - - #include --#include - - #include "dss.h" - #include "dss_features.h" - - static struct { - struct platform_device *pdev; -- int ctx_id; -- -- struct clk *dss_ick; -- struct clk *dss1_fck; -- struct clk *dss2_fck; -- struct clk *dss_54m_fck; -- struct clk *dss_96m_fck; -- unsigned num_clks_enabled; - - struct regulator *vdds_dsi_reg; - struct regulator *vdds_sdi_reg; -- struct regulator *vdda_dac_reg; - } core; - --static void dss_clk_enable_all_no_ctx(void); --static void dss_clk_disable_all_no_ctx(void); --static void dss_clk_enable_no_ctx(enum dss_clock clks); --static void dss_clk_disable_no_ctx(enum dss_clock clks); -- - static char *def_disp_name; - module_param_named(def_disp, def_disp_name, charp, 0); --MODULE_PARM_DESC(def_disp_name, "default display name"); -+MODULE_PARM_DESC(def_disp, "default display name"); - - #ifdef DEBUG - unsigned int dss_debug; - module_param_named(debug, dss_debug, bool, 0644); - #endif - --/* CONTEXT */ --static int dss_get_ctx_id(void) --{ -- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; -- int r; -- -- if (!pdata->get_last_off_on_transaction_id) -- return 0; -- r = pdata->get_last_off_on_transaction_id(&core.pdev->dev); -- if (r < 0) { -- dev_err(&core.pdev->dev, "getting transaction ID failed, " -- "will force context restore\n"); -- r = -1; -- } -- return r; --} -- --int dss_need_ctx_restore(void) --{ -- int id = dss_get_ctx_id(); -- -- if (id < 0 || id != core.ctx_id) { -- DSSDBG("ctx id %d -> id %d\n", -- core.ctx_id, id); -- core.ctx_id = id; -- return 1; -- } else { -- return 0; -- } --} -- --static void save_all_ctx(void) --{ -- DSSDBG("save context\n"); -- -- dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); -- -- dss_save_context(); -- dispc_save_context(); --#ifdef CONFIG_OMAP2_DSS_DSI -- dsi_save_context(); --#endif -- -- dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1); --} -- --static void restore_all_ctx(void) --{ -- DSSDBG("restore context\n"); -- -- dss_clk_enable_all_no_ctx(); -- -- dss_restore_context(); -- dispc_restore_context(); --#ifdef CONFIG_OMAP2_DSS_DSI -- dsi_restore_context(); --#endif -- -- dss_clk_disable_all_no_ctx(); --} -- --#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) --/* CLOCKS */ --static void core_dump_clocks(struct seq_file *s) --{ -- int i; -- struct clk *clocks[5] = { -- core.dss_ick, -- core.dss1_fck, -- core.dss2_fck, -- core.dss_54m_fck, -- core.dss_96m_fck -- }; -- -- seq_printf(s, "- CORE -\n"); -- -- seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled); -- -- for (i = 0; i < 5; i++) { -- if (!clocks[i]) -- continue; -- seq_printf(s, "%-15s\t%lu\t%d\n", -- clocks[i]->name, -- clk_get_rate(clocks[i]), -- clocks[i]->usecount); -- } --} --#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ -- --static int dss_get_clock(struct clk **clock, const char *clk_name) --{ -- struct clk *clk; -- -- clk = clk_get(&core.pdev->dev, clk_name); -- -- if (IS_ERR(clk)) { -- DSSERR("can't get clock %s", clk_name); -- return PTR_ERR(clk); -- } -- -- *clock = clk; -- -- DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); -- -- return 0; --} -- --static int dss_get_clocks(void) --{ -- int r; -- -- core.dss_ick = NULL; -- core.dss1_fck = NULL; -- core.dss2_fck = NULL; -- core.dss_54m_fck = NULL; -- core.dss_96m_fck = NULL; -- -- r = dss_get_clock(&core.dss_ick, "ick"); -- if (r) -- goto err; -- -- r = dss_get_clock(&core.dss1_fck, "dss1_fck"); -- if (r) -- goto err; -- -- r = dss_get_clock(&core.dss2_fck, "dss2_fck"); -- if (r) -- goto err; -- -- r = dss_get_clock(&core.dss_54m_fck, "tv_fck"); -- if (r) -- goto err; -- -- r = dss_get_clock(&core.dss_96m_fck, "video_fck"); -- if (r) -- goto err; -- -- return 0; -- --err: -- if (core.dss_ick) -- clk_put(core.dss_ick); -- if (core.dss1_fck) -- clk_put(core.dss1_fck); -- if (core.dss2_fck) -- clk_put(core.dss2_fck); -- if (core.dss_54m_fck) -- clk_put(core.dss_54m_fck); -- if (core.dss_96m_fck) -- clk_put(core.dss_96m_fck); -- -- return r; --} -- --static void dss_put_clocks(void) --{ -- if (core.dss_96m_fck) -- clk_put(core.dss_96m_fck); -- clk_put(core.dss_54m_fck); -- clk_put(core.dss1_fck); -- clk_put(core.dss2_fck); -- clk_put(core.dss_ick); --} -- --unsigned long dss_clk_get_rate(enum dss_clock clk) --{ -- switch (clk) { -- case DSS_CLK_ICK: -- return clk_get_rate(core.dss_ick); -- case DSS_CLK_FCK1: -- return clk_get_rate(core.dss1_fck); -- case DSS_CLK_FCK2: -- return clk_get_rate(core.dss2_fck); -- case DSS_CLK_54M: -- return clk_get_rate(core.dss_54m_fck); -- case DSS_CLK_96M: -- return clk_get_rate(core.dss_96m_fck); -- } -- -- BUG(); -- return 0; --} -- --static unsigned count_clk_bits(enum dss_clock clks) --{ -- unsigned num_clks = 0; -- -- if (clks & DSS_CLK_ICK) -- ++num_clks; -- if (clks & DSS_CLK_FCK1) -- ++num_clks; -- if (clks & DSS_CLK_FCK2) -- ++num_clks; -- if (clks & DSS_CLK_54M) -- ++num_clks; -- if (clks & DSS_CLK_96M) -- ++num_clks; -- -- return num_clks; --} -- --static void dss_clk_enable_no_ctx(enum dss_clock clks) --{ -- unsigned num_clks = count_clk_bits(clks); -- -- if (clks & DSS_CLK_ICK) -- clk_enable(core.dss_ick); -- if (clks & DSS_CLK_FCK1) -- clk_enable(core.dss1_fck); -- if (clks & DSS_CLK_FCK2) -- clk_enable(core.dss2_fck); -- if (clks & DSS_CLK_54M) -- clk_enable(core.dss_54m_fck); -- if (clks & DSS_CLK_96M) -- clk_enable(core.dss_96m_fck); -- -- core.num_clks_enabled += num_clks; --} -- --void dss_clk_enable(enum dss_clock clks) --{ -- bool check_ctx = core.num_clks_enabled == 0; -- -- dss_clk_enable_no_ctx(clks); -- -- if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) -- restore_all_ctx(); --} -- --static void dss_clk_disable_no_ctx(enum dss_clock clks) --{ -- unsigned num_clks = count_clk_bits(clks); -- -- if (clks & DSS_CLK_ICK) -- clk_disable(core.dss_ick); -- if (clks & DSS_CLK_FCK1) -- clk_disable(core.dss1_fck); -- if (clks & DSS_CLK_FCK2) -- clk_disable(core.dss2_fck); -- if (clks & DSS_CLK_54M) -- clk_disable(core.dss_54m_fck); -- if (clks & DSS_CLK_96M) -- clk_disable(core.dss_96m_fck); -- -- core.num_clks_enabled -= num_clks; --} -- --void dss_clk_disable(enum dss_clock clks) --{ -- if (cpu_is_omap34xx()) { -- unsigned num_clks = count_clk_bits(clks); -- -- BUG_ON(core.num_clks_enabled < num_clks); -- -- if (core.num_clks_enabled == num_clks) -- save_all_ctx(); -- } -- -- dss_clk_disable_no_ctx(clks); --} -- --static void dss_clk_enable_all_no_ctx(void) --{ -- enum dss_clock clks; -- -- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; -- if (cpu_is_omap34xx()) -- clks |= DSS_CLK_96M; -- dss_clk_enable_no_ctx(clks); --} -- --static void dss_clk_disable_all_no_ctx(void) --{ -- enum dss_clock clks; -- -- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; -- if (cpu_is_omap34xx()) -- clks |= DSS_CLK_96M; -- dss_clk_disable_no_ctx(clks); --} -- --static void dss_clk_disable_all(void) --{ -- enum dss_clock clks; -- -- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M; -- if (cpu_is_omap34xx()) -- clks |= DSS_CLK_96M; -- dss_clk_disable(clks); --} -- - /* REGULATORS */ - - struct regulator *dss_get_vdds_dsi(void) -@@ -390,32 +84,7 @@ - return reg; - } - --struct regulator *dss_get_vdda_dac(void) --{ -- struct regulator *reg; -- -- if (core.vdda_dac_reg != NULL) -- return core.vdda_dac_reg; -- -- reg = regulator_get(&core.pdev->dev, "vdda_dac"); -- if (!IS_ERR(reg)) -- core.vdda_dac_reg = reg; -- -- return reg; --} -- --/* DEBUGFS */ - #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) --static void dss_debug_dump_clocks(struct seq_file *s) --{ -- core_dump_clocks(s); -- dss_dump_clocks(s); -- dispc_dump_clocks(s); --#ifdef CONFIG_OMAP2_DSS_DSI -- dsi_dump_clocks(s); --#endif --} -- - static int dss_debug_show(struct seq_file *s, void *unused) - { - void (*func)(struct seq_file *) = s->private; -@@ -497,7 +166,6 @@ - static int omap_dss_probe(struct platform_device *pdev) - { - struct omap_dss_board_info *pdata = pdev->dev.platform_data; -- int skip_init = 0; - int r; - int i; - -@@ -508,63 +176,37 @@ - dss_init_overlay_managers(pdev); - dss_init_overlays(pdev); - -- r = dss_get_clocks(); -- if (r) -- goto err_clocks; -- -- dss_clk_enable_all_no_ctx(); -- -- core.ctx_id = dss_get_ctx_id(); -- DSSDBG("initial ctx id %u\n", core.ctx_id); -- --#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT -- /* DISPC_CONTROL */ -- if (omap_readl(0x48050440) & 1) /* LCD enabled? */ -- skip_init = 1; --#endif -- -- r = dss_init(skip_init); -+ r = dss_init_platform_driver(); - if (r) { -- DSSERR("Failed to initialize DSS\n"); -+ DSSERR("Failed to initialize DSS platform driver\n"); - goto err_dss; - } - -- r = rfbi_init(); -- if (r) { -- DSSERR("Failed to initialize rfbi\n"); -- goto err_rfbi; -- } -+ /* keep clocks enabled to prevent context saves/restores during init */ -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - -- r = dpi_init(pdev); -+ r = rfbi_init_platform_driver(); - if (r) { -- DSSERR("Failed to initialize dpi\n"); -- goto err_dpi; -+ DSSERR("Failed to initialize rfbi platform driver\n"); -+ goto err_rfbi; - } - -- r = dispc_init(); -+ r = dispc_init_platform_driver(); - if (r) { -- DSSERR("Failed to initialize dispc\n"); -+ DSSERR("Failed to initialize dispc platform driver\n"); - goto err_dispc; - } - -- r = venc_init(pdev); -+ r = venc_init_platform_driver(); - if (r) { -- DSSERR("Failed to initialize venc\n"); -+ DSSERR("Failed to initialize venc platform driver\n"); - goto err_venc; - } - -- if (cpu_is_omap34xx()) { -- r = sdi_init(skip_init); -- if (r) { -- DSSERR("Failed to initialize SDI\n"); -- goto err_sdi; -- } -- -- r = dsi_init(pdev); -- if (r) { -- DSSERR("Failed to initialize DSI\n"); -- goto err_dsi; -- } -+ r = dsi_init_platform_driver(); -+ if (r) { -+ DSSERR("Failed to initialize DSI platform driver\n"); -+ goto err_dsi; - } - - r = dss_initialize_debugfs(); -@@ -589,32 +231,23 @@ - pdata->default_device = dssdev; - } - -- dss_clk_disable_all(); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - - return 0; - - err_register: - dss_uninitialize_debugfs(); - err_debugfs: -- if (cpu_is_omap34xx()) -- dsi_exit(); -+ dsi_uninit_platform_driver(); - err_dsi: -- if (cpu_is_omap34xx()) -- sdi_exit(); --err_sdi: -- venc_exit(); -+ venc_uninit_platform_driver(); - err_venc: -- dispc_exit(); -+ dispc_uninit_platform_driver(); - err_dispc: -- dpi_exit(); --err_dpi: -- rfbi_exit(); -+ rfbi_uninit_platform_driver(); - err_rfbi: -- dss_exit(); -+ dss_uninit_platform_driver(); - err_dss: -- dss_clk_disable_all_no_ctx(); -- dss_put_clocks(); --err_clocks: - - return r; - } -@@ -623,61 +256,14 @@ - { - struct omap_dss_board_info *pdata = pdev->dev.platform_data; - int i; -- int c; - - dss_uninitialize_debugfs(); - -- venc_exit(); -- dispc_exit(); -- dpi_exit(); -- rfbi_exit(); -- if (cpu_is_omap34xx()) { -- dsi_exit(); -- sdi_exit(); -- } -- -- dss_exit(); -- -- /* these should be removed at some point */ -- c = core.dss_ick->usecount; -- if (c > 0) { -- DSSERR("warning: dss_ick usecount %d, disabling\n", c); -- while (c-- > 0) -- clk_disable(core.dss_ick); -- } -- -- c = core.dss1_fck->usecount; -- if (c > 0) { -- DSSERR("warning: dss1_fck usecount %d, disabling\n", c); -- while (c-- > 0) -- clk_disable(core.dss1_fck); -- } -- -- c = core.dss2_fck->usecount; -- if (c > 0) { -- DSSERR("warning: dss2_fck usecount %d, disabling\n", c); -- while (c-- > 0) -- clk_disable(core.dss2_fck); -- } -- -- c = core.dss_54m_fck->usecount; -- if (c > 0) { -- DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c); -- while (c-- > 0) -- clk_disable(core.dss_54m_fck); -- } -- -- if (core.dss_96m_fck) { -- c = core.dss_96m_fck->usecount; -- if (c > 0) { -- DSSERR("warning: dss_96m_fck usecount %d, disabling\n", -- c); -- while (c-- > 0) -- clk_disable(core.dss_96m_fck); -- } -- } -- -- dss_put_clocks(); -+ venc_uninit_platform_driver(); -+ dispc_uninit_platform_driver(); -+ rfbi_uninit_platform_driver(); -+ dsi_uninit_platform_driver(); -+ dss_uninit_platform_driver(); - - dss_uninit_overlays(pdev); - dss_uninit_overlay_managers(pdev); -@@ -965,11 +551,6 @@ - core.vdds_sdi_reg = NULL; - } - -- if (core.vdda_dac_reg != NULL) { -- regulator_put(core.vdda_dac_reg); -- core.vdda_dac_reg = NULL; -- } -- - platform_driver_unregister(&omap_dss_driver); - - omap_dss_bus_unregister(); -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dispc.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dispc.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dispc.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dispc.c 2011-03-09 13:19:21.083278942 +0100 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -42,8 +43,6 @@ - #include "dss_features.h" - - /* DISPC */ --#define DISPC_BASE 0x48050400 -- - #define DISPC_SZ_REGS SZ_4K - - struct dispc_reg { u16 idx; }; -@@ -74,7 +73,7 @@ - #define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400) - #define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404) - #define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408) --#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) -+#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C) - #define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074) - #define DISPC_SIZE_DIG DISPC_REG(0x0078) - #define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC) -@@ -129,6 +128,7 @@ - - #define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04) - -+#define DISPC_DIVISOR DISPC_REG(0x0804) - - #define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \ - DISPC_IRQ_OCP_ERR | \ -@@ -178,7 +178,9 @@ - }; - - static struct { -+ struct platform_device *pdev; - void __iomem *base; -+ int irq; - - u32 fifo_size[3]; - -@@ -230,7 +232,7 @@ - SR(TIMING_H(0)); - SR(TIMING_V(0)); - SR(POL_FREQ(0)); -- SR(DIVISOR(0)); -+ SR(DIVISORo(0)); - SR(GLOBAL_ALPHA); - SR(SIZE_DIG); - SR(SIZE_LCD(0)); -@@ -242,7 +244,7 @@ - SR(TIMING_H(2)); - SR(TIMING_V(2)); - SR(POL_FREQ(2)); -- SR(DIVISOR(2)); -+ SR(DIVISORo(2)); - SR(CONFIG2); - } - -@@ -373,6 +375,9 @@ - SR(VID_FIR_COEF_V(1, 7)); - - SR(VID_PRELOAD(1)); -+ -+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) -+ SR(DIVISOR); - } - - void dispc_restore_context(void) -@@ -389,7 +394,7 @@ - RR(TIMING_H(0)); - RR(TIMING_V(0)); - RR(POL_FREQ(0)); -- RR(DIVISOR(0)); -+ RR(DIVISORo(0)); - RR(GLOBAL_ALPHA); - RR(SIZE_DIG); - RR(SIZE_LCD(0)); -@@ -400,7 +405,7 @@ - RR(TIMING_H(2)); - RR(TIMING_V(2)); - RR(POL_FREQ(2)); -- RR(DIVISOR(2)); -+ RR(DIVISORo(2)); - RR(CONFIG2); - } - -@@ -532,6 +537,9 @@ - - RR(VID_PRELOAD(1)); - -+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) -+ RR(DIVISOR); -+ - /* enable last, because LCD & DIGIT enable are here */ - RR(CONTROL); - if (dss_has_feature(FEAT_MGR_LCD2)) -@@ -552,9 +560,9 @@ - static inline void enable_clocks(bool enable) - { - if (enable) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - else -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - } - - bool dispc_go_busy(enum omap_channel channel) -@@ -1129,10 +1137,16 @@ - u32 val; - const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0), - DISPC_VID_ACCU0(1) }; -+ u8 hor_start, hor_end, vert_start, vert_end; - - BUG_ON(plane == OMAP_DSS_GFX); - -- val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); -+ dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end); -+ dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end); -+ -+ val = FLD_VAL(vaccu, vert_start, vert_end) | -+ FLD_VAL(haccu, hor_start, hor_end); -+ - dispc_write_reg(ac0_reg[plane-1], val); - } - -@@ -1141,10 +1155,16 @@ - u32 val; - const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0), - DISPC_VID_ACCU1(1) }; -+ u8 hor_start, hor_end, vert_start, vert_end; - - BUG_ON(plane == OMAP_DSS_GFX); - -- val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0); -+ dss_feat_get_reg_field(FEAT_REG_HORIZONTALACCU, &hor_start, &hor_end); -+ dss_feat_get_reg_field(FEAT_REG_VERTICALACCU, &vert_start, &vert_end); -+ -+ val = FLD_VAL(vaccu, vert_start, vert_end) | -+ FLD_VAL(haccu, hor_start, hor_end); -+ - dispc_write_reg(ac1_reg[plane-1], val); - } - -@@ -1182,16 +1202,25 @@ - _dispc_set_fir(plane, fir_hinc, fir_vinc); - - l = dispc_read_reg(dispc_reg_att[plane]); -- l &= ~((0x0f << 5) | (0x3 << 21)); - -+ /* RESIZEENABLE and VERTICALTAPS */ -+ l &= ~((0x3 << 5) | (0x1 << 21)); - l |= fir_hinc ? (1 << 5) : 0; - l |= fir_vinc ? (1 << 6) : 0; -+ l |= five_taps ? (1 << 21) : 0; - -- l |= hscaleup ? 0 : (1 << 7); -- l |= vscaleup ? 0 : (1 << 8); -+ /* VRESIZECONF and HRESIZECONF */ -+ if (dss_has_feature(FEAT_RESIZECONF)) { -+ l &= ~(0x3 << 7); -+ l |= hscaleup ? 0 : (1 << 7); -+ l |= vscaleup ? 0 : (1 << 8); -+ } - -- l |= five_taps ? (1 << 21) : 0; -- l |= five_taps ? (1 << 22) : 0; -+ /* LINEBUFFERSPLIT */ -+ if (dss_has_feature(FEAT_LINEBUFFERSPLIT)) { -+ l &= ~(0x1 << 22); -+ l |= five_taps ? (1 << 22) : 0; -+ } - - dispc_write_reg(dispc_reg_att[plane], l); - -@@ -1215,9 +1244,11 @@ - static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation, - bool mirroring, enum omap_color_mode color_mode) - { -+ bool row_repeat = false; -+ int vidrot = 0; -+ - if (color_mode == OMAP_DSS_COLOR_YUV2 || - color_mode == OMAP_DSS_COLOR_UYVY) { -- int vidrot = 0; - - if (mirroring) { - switch (rotation) { -@@ -1251,16 +1282,15 @@ - } - } - -- REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12); -- - if (rotation == OMAP_DSS_ROT_90 || rotation == OMAP_DSS_ROT_270) -- REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18); -+ row_repeat = true; - else -- REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18); -- } else { -- REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12); -- REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18); -+ row_repeat = false; - } -+ -+ REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12); -+ if (dss_has_feature(FEAT_ROWREPEATENABLE)) -+ REG_FLD_MOD(dispc_reg_att[plane], row_repeat ? 1 : 0, 18, 18); - } - - static int color_mode_to_bpp(enum omap_color_mode color_mode) -@@ -2293,7 +2323,7 @@ - BUG_ON(pck_div < 2); - - enable_clocks(1); -- dispc_write_reg(DISPC_DIVISOR(channel), -+ dispc_write_reg(DISPC_DIVISORo(channel), - FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); - enable_clocks(0); - } -@@ -2302,7 +2332,7 @@ - int *pck_div) - { - u32 l; -- l = dispc_read_reg(DISPC_DIVISOR(channel)); -+ l = dispc_read_reg(DISPC_DIVISORo(channel)); - *lck_div = FLD_GET(l, 23, 16); - *pck_div = FLD_GET(l, 7, 0); - } -@@ -2311,14 +2341,17 @@ - { - unsigned long r = 0; - -- if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) -- r = dss_clk_get_rate(DSS_CLK_FCK1); -- else --#ifdef CONFIG_OMAP2_DSS_DSI -- r = dsi_get_dsi1_pll_rate(); --#else -- BUG(); --#endif -+ switch (dss_get_dispc_clk_source()) { -+ case DSS_CLK_SRC_FCK: -+ r = dss_clk_get_rate(DSS_CLK_FCK); -+ break; -+ case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: -+ r = dsi_get_pll_hsdiv_dispc_rate(); -+ break; -+ default: -+ BUG(); -+ } -+ - return r; - } - -@@ -2328,47 +2361,72 @@ - unsigned long r; - u32 l; - -- l = dispc_read_reg(DISPC_DIVISOR(channel)); -+ l = dispc_read_reg(DISPC_DIVISORo(channel)); - - lcd = FLD_GET(l, 23, 16); - -- r = dispc_fclk_rate(); -+ switch (dss_get_lcd_clk_source(channel)) { -+ case DSS_CLK_SRC_FCK: -+ r = dss_clk_get_rate(DSS_CLK_FCK); -+ break; -+ case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: -+ r = dsi_get_pll_hsdiv_dispc_rate(); -+ break; -+ default: -+ BUG(); -+ } - - return r / lcd; - } - - unsigned long dispc_pclk_rate(enum omap_channel channel) - { -- int lcd, pcd; -+ int pcd; - unsigned long r; - u32 l; - -- l = dispc_read_reg(DISPC_DIVISOR(channel)); -+ l = dispc_read_reg(DISPC_DIVISORo(channel)); - -- lcd = FLD_GET(l, 23, 16); - pcd = FLD_GET(l, 7, 0); - -- r = dispc_fclk_rate(); -+ r = dispc_lclk_rate(channel); - -- return r / lcd / pcd; -+ return r / pcd; - } - - void dispc_dump_clocks(struct seq_file *s) - { - int lcd, pcd; -+ u32 l; -+ enum dss_clk_source dispc_clk_src = dss_get_dispc_clk_source(); -+ enum dss_clk_source lcd_clk_src; - - enable_clocks(1); - - seq_printf(s, "- DISPC -\n"); - -- seq_printf(s, "dispc fclk source = %s\n", -- dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? -- "dss1_alwon_fclk" : "dsi1_pll_fclk"); -+ seq_printf(s, "dispc fclk source = %s (%s)\n", -+ dss_get_generic_clk_source_name(dispc_clk_src), -+ dss_feat_get_clk_source_name(dispc_clk_src)); - - seq_printf(s, "fck\t\t%-16lu\n", dispc_fclk_rate()); - -+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) { -+ seq_printf(s, "- DISPC-CORE-CLK -\n"); -+ l = dispc_read_reg(DISPC_DIVISOR); -+ lcd = FLD_GET(l, 23, 16); -+ -+ seq_printf(s, "lck\t\t%-16lulck div\t%u\n", -+ (dispc_fclk_rate()/lcd), lcd); -+ } - seq_printf(s, "- LCD1 -\n"); - -+ lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD); -+ -+ seq_printf(s, "lcd1_clk source = %s (%s)\n", -+ dss_get_generic_clk_source_name(lcd_clk_src), -+ dss_feat_get_clk_source_name(lcd_clk_src)); -+ - dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD, &lcd, &pcd); - - seq_printf(s, "lck\t\t%-16lulck div\t%u\n", -@@ -2378,6 +2436,12 @@ - if (dss_has_feature(FEAT_MGR_LCD2)) { - seq_printf(s, "- LCD2 -\n"); - -+ lcd_clk_src = dss_get_lcd_clk_source(OMAP_DSS_CHANNEL_LCD2); -+ -+ seq_printf(s, "lcd2_clk source = %s (%s)\n", -+ dss_get_generic_clk_source_name(lcd_clk_src), -+ dss_feat_get_clk_source_name(lcd_clk_src)); -+ - dispc_get_lcd_divisor(OMAP_DSS_CHANNEL_LCD2, &lcd, &pcd); - - seq_printf(s, "lck\t\t%-16lulck div\t%u\n", -@@ -2440,7 +2504,7 @@ - { - #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r)) - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - DUMPREG(DISPC_REVISION); - DUMPREG(DISPC_SYSCONFIG); -@@ -2459,7 +2523,7 @@ - DUMPREG(DISPC_TIMING_H(0)); - DUMPREG(DISPC_TIMING_V(0)); - DUMPREG(DISPC_POL_FREQ(0)); -- DUMPREG(DISPC_DIVISOR(0)); -+ DUMPREG(DISPC_DIVISORo(0)); - DUMPREG(DISPC_GLOBAL_ALPHA); - DUMPREG(DISPC_SIZE_DIG); - DUMPREG(DISPC_SIZE_LCD(0)); -@@ -2471,7 +2535,7 @@ - DUMPREG(DISPC_TIMING_H(2)); - DUMPREG(DISPC_TIMING_V(2)); - DUMPREG(DISPC_POL_FREQ(2)); -- DUMPREG(DISPC_DIVISOR(2)); -+ DUMPREG(DISPC_DIVISORo(2)); - DUMPREG(DISPC_SIZE_LCD(2)); - } - -@@ -2597,7 +2661,7 @@ - DUMPREG(DISPC_VID_PRELOAD(0)); - DUMPREG(DISPC_VID_PRELOAD(1)); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - #undef DUMPREG - } - -@@ -2713,8 +2777,8 @@ - - fck = dispc_fclk_rate(); - -- cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16); -- cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0); -+ cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16); -+ cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0); - - cinfo->lck = fck / cinfo->lck_div; - cinfo->pck = cinfo->lck / cinfo->pck_div; -@@ -2791,6 +2855,9 @@ - break; - } - -+ if (ret) -+ goto err; -+ - _omap_dispc_set_irqs(); - - spin_unlock_irqrestore(&dispc.irq_lock, flags); -@@ -2866,10 +2933,10 @@ - * but we presume they are on because we got an IRQ. However, - * an irq handler may turn the clocks off, so we may not have - * clock later in the function. */ --void dispc_irq_handler(void) -+static irqreturn_t omap_dispc_irq_handler(int irq, void *arg) - { - int i; -- u32 irqstatus; -+ u32 irqstatus, irqenable; - u32 handledirqs = 0; - u32 unhandled_errors; - struct omap_dispc_isr_data *isr_data; -@@ -2878,6 +2945,13 @@ - spin_lock(&dispc.irq_lock); - - irqstatus = dispc_read_reg(DISPC_IRQSTATUS); -+ irqenable = dispc_read_reg(DISPC_IRQENABLE); -+ -+ /* IRQ is not for us */ -+ if (!(irqstatus & irqenable)) { -+ spin_unlock(&dispc.irq_lock); -+ return IRQ_NONE; -+ } - - #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS - spin_lock(&dispc.irq_stats_lock); -@@ -2929,6 +3003,8 @@ - } - - spin_unlock(&dispc.irq_lock); -+ -+ return IRQ_HANDLED; - } - - static void dispc_error_worker(struct work_struct *work) -@@ -3253,6 +3329,15 @@ - l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */ - dispc_write_reg(DISPC_SYSCONFIG, l); - -+ /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */ -+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) { -+ l = dispc_read_reg(DISPC_DIVISOR); -+ /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */ -+ l = FLD_MOD(l, 1, 0, 0); -+ l = FLD_MOD(l, 1, 23, 16); -+ dispc_write_reg(DISPC_DIVISOR, l); -+ } -+ - /* FUNCGATED */ - if (dss_has_feature(FEAT_FUNCGATED)) - REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9); -@@ -3269,47 +3354,6 @@ - dispc_read_plane_fifo_sizes(); - } - --int dispc_init(void) --{ -- u32 rev; -- -- spin_lock_init(&dispc.irq_lock); -- --#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS -- spin_lock_init(&dispc.irq_stats_lock); -- dispc.irq_stats.last_reset = jiffies; --#endif -- -- INIT_WORK(&dispc.error_work, dispc_error_worker); -- -- dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS); -- if (!dispc.base) { -- DSSERR("can't ioremap DISPC\n"); -- return -ENOMEM; -- } -- -- enable_clocks(1); -- -- _omap_dispc_initial_config(); -- -- _omap_dispc_initialize_irq(); -- -- dispc_save_context(); -- -- rev = dispc_read_reg(DISPC_REVISION); -- printk(KERN_INFO "OMAP DISPC rev %d.%d\n", -- FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); -- -- enable_clocks(0); -- -- return 0; --} -- --void dispc_exit(void) --{ -- iounmap(dispc.base); --} -- - int dispc_enable_plane(enum omap_plane plane, bool enable) - { - DSSDBG("dispc_enable_plane %d, %d\n", plane, enable); -@@ -3359,3 +3403,94 @@ - - return r; - } -+ -+/* DISPC HW IP initialisation */ -+static int omap_dispchw_probe(struct platform_device *pdev) -+{ -+ u32 rev; -+ int r = 0; -+ struct resource *dispc_mem; -+ -+ dispc.pdev = pdev; -+ -+ spin_lock_init(&dispc.irq_lock); -+ -+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS -+ spin_lock_init(&dispc.irq_stats_lock); -+ dispc.irq_stats.last_reset = jiffies; -+#endif -+ -+ INIT_WORK(&dispc.error_work, dispc_error_worker); -+ -+ dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0); -+ if (!dispc_mem) { -+ DSSERR("can't get IORESOURCE_MEM DISPC\n"); -+ r = -EINVAL; -+ goto fail0; -+ } -+ dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); -+ if (!dispc.base) { -+ DSSERR("can't ioremap DISPC\n"); -+ r = -ENOMEM; -+ goto fail0; -+ } -+ dispc.irq = platform_get_irq(dispc.pdev, 0); -+ if (dispc.irq < 0) { -+ DSSERR("platform_get_irq failed\n"); -+ r = -ENODEV; -+ goto fail1; -+ } -+ -+ r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, -+ "OMAP DISPC", dispc.pdev); -+ if (r < 0) { -+ DSSERR("request_irq failed\n"); -+ goto fail1; -+ } -+ -+ enable_clocks(1); -+ -+ _omap_dispc_initial_config(); -+ -+ _omap_dispc_initialize_irq(); -+ -+ dispc_save_context(); -+ -+ rev = dispc_read_reg(DISPC_REVISION); -+ dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n", -+ FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); -+ -+ enable_clocks(0); -+ -+ return 0; -+fail1: -+ iounmap(dispc.base); -+fail0: -+ return r; -+} -+ -+static int omap_dispchw_remove(struct platform_device *pdev) -+{ -+ free_irq(dispc.irq, dispc.pdev); -+ iounmap(dispc.base); -+ return 0; -+} -+ -+static struct platform_driver omap_dispchw_driver = { -+ .probe = omap_dispchw_probe, -+ .remove = omap_dispchw_remove, -+ .driver = { -+ .name = "omapdss_dispc", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int dispc_init_platform_driver(void) -+{ -+ return platform_driver_register(&omap_dispchw_driver); -+} -+ -+void dispc_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omap_dispchw_driver); -+} -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/display.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/display.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/display.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/display.c 2011-03-09 13:19:21.083278943 +0100 -@@ -25,14 +25,11 @@ - #include - #include - #include --#include - #include - - #include - #include "dss.h" - --static LIST_HEAD(display_list); -- - static ssize_t display_enabled_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -396,29 +393,6 @@ - switch (dssdev->type) { - #ifdef CONFIG_OMAP2_DSS_DPI - case OMAP_DISPLAY_TYPE_DPI: --#endif --#ifdef CONFIG_OMAP2_DSS_RFBI -- case OMAP_DISPLAY_TYPE_DBI: --#endif --#ifdef CONFIG_OMAP2_DSS_SDI -- case OMAP_DISPLAY_TYPE_SDI: --#endif --#ifdef CONFIG_OMAP2_DSS_DSI -- case OMAP_DISPLAY_TYPE_DSI: --#endif --#ifdef CONFIG_OMAP2_DSS_VENC -- case OMAP_DISPLAY_TYPE_VENC: --#endif -- break; -- default: -- DSSERR("Support for display '%s' not compiled in.\n", -- dssdev->name); -- return; -- } -- -- switch (dssdev->type) { --#ifdef CONFIG_OMAP2_DSS_DPI -- case OMAP_DISPLAY_TYPE_DPI: - r = dpi_init_display(dssdev); - break; - #endif -@@ -443,7 +417,9 @@ - break; - #endif - default: -- BUG(); -+ DSSERR("Support for display '%s' not compiled in.\n", -+ dssdev->name); -+ return; - } - - if (r) { -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dpi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dpi.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dpi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dpi.c 2011-03-09 13:19:21.083278943 +0100 -@@ -57,13 +57,13 @@ - if (r) - return r; - -- dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); -+ dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); - - r = dispc_set_clock_div(dssdev->manager->id, &dispc_cinfo); - if (r) - return r; - -- *fck = dsi_cinfo.dsi1_pll_fclk; -+ *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; - *lck_div = dispc_cinfo.lck_div; - *pck_div = dispc_cinfo.pck_div; - -@@ -107,7 +107,7 @@ - bool is_tft; - int r = 0; - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, - dssdev->panel.acbi, dssdev->panel.acb); -@@ -137,7 +137,7 @@ - dispc_set_lcd_timings(dssdev->manager->id, t); - - err0: -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - return r; - } - -@@ -173,14 +173,14 @@ - goto err1; - } - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - r = dpi_basic_init(dssdev); - if (r) - goto err2; - - #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL -- dss_clk_enable(DSS_CLK_FCK2); -+ dss_clk_enable(DSS_CLK_SYSCK); - r = dsi_pll_init(dssdev, 0, 1); - if (r) - goto err3; -@@ -199,10 +199,10 @@ - #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL - dsi_pll_uninit(); - err3: -- dss_clk_disable(DSS_CLK_FCK2); -+ dss_clk_disable(DSS_CLK_SYSCK); - #endif - err2: -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - if (cpu_is_omap34xx()) - regulator_disable(dpi.vdds_dsi_reg); - err1: -@@ -217,12 +217,12 @@ - dssdev->manager->disable(dssdev->manager); - - #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL -- dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); -+ dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); - dsi_pll_uninit(); -- dss_clk_disable(DSS_CLK_FCK2); -+ dss_clk_disable(DSS_CLK_SYSCK); - #endif - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - - if (cpu_is_omap34xx()) - regulator_disable(dpi.vdds_dsi_reg); -@@ -271,7 +271,7 @@ - if (r) - return r; - -- fck = dsi_cinfo.dsi1_pll_fclk; -+ fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; - lck_div = dispc_cinfo.lck_div; - pck_div = dispc_cinfo.pck_div; - } -@@ -303,22 +303,27 @@ - { - DSSDBG("init_display\n"); - -- return 0; --} -+ if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) { -+ struct regulator *vdds_dsi; - --int dpi_init(struct platform_device *pdev) --{ -- if (cpu_is_omap34xx()) { -- dpi.vdds_dsi_reg = dss_get_vdds_dsi(); -- if (IS_ERR(dpi.vdds_dsi_reg)) { -+ vdds_dsi = dss_get_vdds_dsi(); -+ -+ if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); -- return PTR_ERR(dpi.vdds_dsi_reg); -+ return PTR_ERR(vdds_dsi); - } -+ -+ dpi.vdds_dsi_reg = vdds_dsi; - } - - return 0; - } - -+int dpi_init(void) -+{ -+ return 0; -+} -+ - void dpi_exit(void) - { - } -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dsi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dsi.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dsi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dsi.c 2011-03-09 13:19:21.084278923 +0100 -@@ -38,12 +38,11 @@ - #include - - #include "dss.h" -+#include "dss_features.h" - - /*#define VERBOSE_IRQ*/ - #define DSI_CATCH_MISSING_TE - --#define DSI_BASE 0x4804FC00 -- - struct dsi_reg { u16 idx; }; - - #define DSI_REG(idx) ((const struct dsi_reg) { idx }) -@@ -190,8 +189,8 @@ - #define FINT_MIN 750000 - #define REGN_MAX (1 << 7) - #define REGM_MAX ((1 << 11) - 1) --#define REGM3_MAX (1 << 4) --#define REGM4_MAX (1 << 4) -+#define REGM_DISPC_MAX (1 << 4) -+#define REGM_DSI_MAX (1 << 4) - #define LP_DIV_MAX ((1 << 13) - 1) - - enum fifo_size { -@@ -222,7 +221,9 @@ - - static struct - { -+ struct platform_device *pdev; - void __iomem *base; -+ int irq; - - struct dsi_clock_info current_cinfo; - -@@ -232,6 +233,7 @@ - enum dsi_vc_mode mode; - struct omap_dss_device *dssdev; - enum fifo_size fifo_size; -+ int vc_id; - } vc[4]; - - struct mutex lock; -@@ -481,13 +483,17 @@ - static int debug_irq; - - /* called from dss */ --void dsi_irq_handler(void) -+static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) - { - u32 irqstatus, vcstatus, ciostatus; - int i; - - irqstatus = dsi_read_reg(DSI_IRQSTATUS); - -+ /* IRQ is not for us */ -+ if (!irqstatus) -+ return IRQ_NONE; -+ - #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS - spin_lock(&dsi.irq_stats_lock); - dsi.irq_stats.irq_count++; -@@ -565,9 +571,9 @@ - #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS - spin_unlock(&dsi.irq_stats_lock); - #endif -+ return IRQ_HANDLED; - } - -- - static void _dsi_initialize_irq(void) - { - u32 l; -@@ -637,22 +643,22 @@ - dsi_write_reg(DSI_VC_IRQENABLE(channel), l); - } - --/* DSI func clock. this could also be DSI2_PLL_FCLK */ -+/* DSI func clock. this could also be dsi_pll_hsdiv_dsi_clk */ - static inline void enable_clocks(bool enable) - { - if (enable) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - else -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - } - - /* source clock for DSI PLL. this could also be PCLKFREE */ - static inline void dsi_enable_pll_clock(bool enable) - { - if (enable) -- dss_clk_enable(DSS_CLK_FCK2); -+ dss_clk_enable(DSS_CLK_SYSCK); - else -- dss_clk_disable(DSS_CLK_FCK2); -+ dss_clk_disable(DSS_CLK_SYSCK); - - if (enable && dsi.pll_locked) { - if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) -@@ -707,14 +713,14 @@ - return 0; - } - --unsigned long dsi_get_dsi1_pll_rate(void) -+unsigned long dsi_get_pll_hsdiv_dispc_rate(void) - { -- return dsi.current_cinfo.dsi1_pll_fclk; -+ return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; - } - --static unsigned long dsi_get_dsi2_pll_rate(void) -+static unsigned long dsi_get_pll_hsdiv_dsi_rate(void) - { -- return dsi.current_cinfo.dsi2_pll_fclk; -+ return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; - } - - static unsigned long dsi_get_txbyteclkhs(void) -@@ -726,12 +732,12 @@ - { - unsigned long r; - -- if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) { -- /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */ -- r = dss_clk_get_rate(DSS_CLK_FCK1); -+ if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) { -+ /* DSI FCLK source is DSS_CLK_FCK */ -+ r = dss_clk_get_rate(DSS_CLK_FCK); - } else { -- /* DSI FCLK source is DSI2_PLL_FCLK */ -- r = dsi_get_dsi2_pll_rate(); -+ /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ -+ r = dsi_get_pll_hsdiv_dsi_rate(); - } - - return r; -@@ -801,16 +807,16 @@ - if (cinfo->regm == 0 || cinfo->regm > REGM_MAX) - return -EINVAL; - -- if (cinfo->regm3 > REGM3_MAX) -+ if (cinfo->regm_dispc > REGM_DISPC_MAX) - return -EINVAL; - -- if (cinfo->regm4 > REGM4_MAX) -+ if (cinfo->regm_dsi > REGM_DSI_MAX) - return -EINVAL; - -- if (cinfo->use_dss2_fck) { -- cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2); -+ if (cinfo->use_sys_clk) { -+ cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK); - /* XXX it is unclear if highfreq should be used -- * with DSS2_FCK source also */ -+ * with DSS_SYS_CLK source also */ - cinfo->highfreq = 0; - } else { - cinfo->clkin = dispc_pclk_rate(dssdev->manager->id); -@@ -831,15 +837,17 @@ - if (cinfo->clkin4ddr > 1800 * 1000 * 1000) - return -EINVAL; - -- if (cinfo->regm3 > 0) -- cinfo->dsi1_pll_fclk = cinfo->clkin4ddr / cinfo->regm3; -+ if (cinfo->regm_dispc > 0) -+ cinfo->dsi_pll_hsdiv_dispc_clk = -+ cinfo->clkin4ddr / cinfo->regm_dispc; - else -- cinfo->dsi1_pll_fclk = 0; -+ cinfo->dsi_pll_hsdiv_dispc_clk = 0; - -- if (cinfo->regm4 > 0) -- cinfo->dsi2_pll_fclk = cinfo->clkin4ddr / cinfo->regm4; -+ if (cinfo->regm_dsi > 0) -+ cinfo->dsi_pll_hsdiv_dsi_clk = -+ cinfo->clkin4ddr / cinfo->regm_dsi; - else -- cinfo->dsi2_pll_fclk = 0; -+ cinfo->dsi_pll_hsdiv_dsi_clk = 0; - - return 0; - } -@@ -852,23 +860,25 @@ - struct dispc_clock_info best_dispc; - int min_fck_per_pck; - int match = 0; -- unsigned long dss_clk_fck2; -+ unsigned long dss_sys_clk, max_dss_fck; - -- dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2); -+ dss_sys_clk = dss_clk_get_rate(DSS_CLK_SYSCK); -+ -+ max_dss_fck = dss_feat_get_max_dss_fck(); - - if (req_pck == dsi.cache_req_pck && -- dsi.cache_cinfo.clkin == dss_clk_fck2) { -+ dsi.cache_cinfo.clkin == dss_sys_clk) { - DSSDBG("DSI clock info found from cache\n"); - *dsi_cinfo = dsi.cache_cinfo; -- dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi1_pll_fclk, -- dispc_cinfo); -+ dispc_find_clk_divs(is_tft, req_pck, -+ dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); - return 0; - } - - min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; - - if (min_fck_per_pck && -- req_pck * min_fck_per_pck > DISPC_MAX_FCK) { -+ req_pck * min_fck_per_pck > max_dss_fck) { - DSSERR("Requested pixel clock not possible with the current " - "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " - "the constraint off.\n"); -@@ -882,8 +892,8 @@ - memset(&best_dispc, 0, sizeof(best_dispc)); - - memset(&cur, 0, sizeof(cur)); -- cur.clkin = dss_clk_fck2; -- cur.use_dss2_fck = 1; -+ cur.clkin = dss_sys_clk; -+ cur.use_sys_clk = 1; - cur.highfreq = 0; - - /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ -@@ -909,30 +919,32 @@ - if (cur.clkin4ddr > 1800 * 1000 * 1000) - break; - -- /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */ -- for (cur.regm3 = 1; cur.regm3 < REGM3_MAX; -- ++cur.regm3) { -+ /* dsi_pll_hsdiv_dispc_clk(MHz) = -+ * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ -+ for (cur.regm_dispc = 1; cur.regm_dispc < REGM_DISPC_MAX; -+ ++cur.regm_dispc) { - struct dispc_clock_info cur_dispc; -- cur.dsi1_pll_fclk = cur.clkin4ddr / cur.regm3; -+ cur.dsi_pll_hsdiv_dispc_clk = -+ cur.clkin4ddr / cur.regm_dispc; - - /* this will narrow down the search a bit, - * but still give pixclocks below what was - * requested */ -- if (cur.dsi1_pll_fclk < req_pck) -+ if (cur.dsi_pll_hsdiv_dispc_clk < req_pck) - break; - -- if (cur.dsi1_pll_fclk > DISPC_MAX_FCK) -+ if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck) - continue; - - if (min_fck_per_pck && -- cur.dsi1_pll_fclk < -+ cur.dsi_pll_hsdiv_dispc_clk < - req_pck * min_fck_per_pck) - continue; - - match = 1; - - dispc_find_clk_divs(is_tft, req_pck, -- cur.dsi1_pll_fclk, -+ cur.dsi_pll_hsdiv_dispc_clk, - &cur_dispc); - - if (abs(cur_dispc.pck - req_pck) < -@@ -961,9 +973,9 @@ - return -EINVAL; - } - -- /* DSI2_PLL_FCLK (regm4) is not used */ -- best.regm4 = 0; -- best.dsi2_pll_fclk = 0; -+ /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */ -+ best.regm_dsi = 0; -+ best.dsi_pll_hsdiv_dsi_clk = 0; - - if (dsi_cinfo) - *dsi_cinfo = best; -@@ -987,18 +999,20 @@ - - dsi.current_cinfo.fint = cinfo->fint; - dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; -- dsi.current_cinfo.dsi1_pll_fclk = cinfo->dsi1_pll_fclk; -- dsi.current_cinfo.dsi2_pll_fclk = cinfo->dsi2_pll_fclk; -+ dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = -+ cinfo->dsi_pll_hsdiv_dispc_clk; -+ dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk = -+ cinfo->dsi_pll_hsdiv_dsi_clk; - - dsi.current_cinfo.regn = cinfo->regn; - dsi.current_cinfo.regm = cinfo->regm; -- dsi.current_cinfo.regm3 = cinfo->regm3; -- dsi.current_cinfo.regm4 = cinfo->regm4; -+ dsi.current_cinfo.regm_dispc = cinfo->regm_dispc; -+ dsi.current_cinfo.regm_dsi = cinfo->regm_dsi; - - DSSDBG("DSI Fint %ld\n", cinfo->fint); - - DSSDBG("clkin (%s) rate %ld, highfreq %d\n", -- cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree", -+ cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree", - cinfo->clkin, - cinfo->highfreq); - -@@ -1015,10 +1029,14 @@ - - DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); - -- DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n", -- cinfo->regm3, cinfo->dsi1_pll_fclk); -- DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n", -- cinfo->regm4, cinfo->dsi2_pll_fclk); -+ DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), -+ cinfo->dsi_pll_hsdiv_dispc_clk); -+ DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), -+ cinfo->dsi_pll_hsdiv_dsi_clk); - - REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ - -@@ -1026,9 +1044,9 @@ - l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ - l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */ - l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */ -- l = FLD_MOD(l, cinfo->regm3 > 0 ? cinfo->regm3 - 1 : 0, -+ l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0, - 22, 19); /* DSI_CLOCK_DIV */ -- l = FLD_MOD(l, cinfo->regm4 > 0 ? cinfo->regm4 - 1 : 0, -+ l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, - 26, 23); /* DSIPROTO_CLOCK_DIV */ - dsi_write_reg(DSI_PLL_CONFIGURATION1, l); - -@@ -1046,7 +1064,7 @@ - - l = dsi_read_reg(DSI_PLL_CONFIGURATION2); - l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ -- l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, -+ l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, - 11, 11); /* DSI_PLL_CLKSEL */ - l = FLD_MOD(l, cinfo->highfreq, - 12, 12); /* DSI_PLL_HIGHFREQ */ -@@ -1101,6 +1119,26 @@ - - DSSDBG("PLL init\n"); - -+#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL -+ /* -+ * HACK: this is just a quick hack to get the USE_DSI_PLL -+ * option working. USE_DSI_PLL is itself a big hack, and -+ * should be removed. -+ */ -+ if (dsi.vdds_dsi_reg == NULL) { -+ struct regulator *vdds_dsi; -+ -+ vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); -+ -+ if (IS_ERR(vdds_dsi)) { -+ DSSERR("can't get VDDS_DSI regulator\n"); -+ return PTR_ERR(vdds_dsi); -+ } -+ -+ dsi.vdds_dsi_reg = vdds_dsi; -+ } -+#endif -+ - enable_clocks(1); - dsi_enable_pll_clock(1); - -@@ -1162,6 +1200,10 @@ - { - int clksel; - struct dsi_clock_info *cinfo = &dsi.current_cinfo; -+ enum dss_clk_source dispc_clk_src, dsi_clk_src; -+ -+ dispc_clk_src = dss_get_dispc_clk_source(); -+ dsi_clk_src = dss_get_dsi_clk_source(); - - enable_clocks(1); - -@@ -1171,30 +1213,34 @@ - - seq_printf(s, "dsi pll source = %s\n", - clksel == 0 ? -- "dss2_alwon_fclk" : "pclkfree"); -+ "dss_sys_clk" : "pclkfree"); - - seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); - - seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", - cinfo->clkin4ddr, cinfo->regm); - -- seq_printf(s, "dsi1_pll_fck\t%-16luregm3 %u\t(%s)\n", -- cinfo->dsi1_pll_fclk, -- cinfo->regm3, -- dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? -+ seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n", -+ dss_get_generic_clk_source_name(dispc_clk_src), -+ dss_feat_get_clk_source_name(dispc_clk_src), -+ cinfo->dsi_pll_hsdiv_dispc_clk, -+ cinfo->regm_dispc, -+ dispc_clk_src == DSS_CLK_SRC_FCK ? - "off" : "on"); - -- seq_printf(s, "dsi2_pll_fck\t%-16luregm4 %u\t(%s)\n", -- cinfo->dsi2_pll_fclk, -- cinfo->regm4, -- dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? -+ seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n", -+ dss_get_generic_clk_source_name(dsi_clk_src), -+ dss_feat_get_clk_source_name(dsi_clk_src), -+ cinfo->dsi_pll_hsdiv_dsi_clk, -+ cinfo->regm_dsi, -+ dsi_clk_src == DSS_CLK_SRC_FCK ? - "off" : "on"); - - seq_printf(s, "- DSI -\n"); - -- seq_printf(s, "dsi fclk source = %s\n", -- dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK ? -- "dss1_alwon_fclk" : "dsi2_pll_fclk"); -+ seq_printf(s, "dsi fclk source = %s (%s)\n", -+ dss_get_generic_clk_source_name(dsi_clk_src), -+ dss_feat_get_clk_source_name(dsi_clk_src)); - - seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); - -@@ -1306,7 +1352,7 @@ - { - #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - DUMPREG(DSI_REVISION); - DUMPREG(DSI_SYSCONFIG); -@@ -1378,7 +1424,7 @@ - DUMPREG(DSI_PLL_CONFIGURATION1); - DUMPREG(DSI_PLL_CONFIGURATION2); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - #undef DUMPREG - } - -@@ -1622,20 +1668,6 @@ - return _dsi_wait_reset(); - } - --static void dsi_reset_tx_fifo(int channel) --{ -- u32 mask; -- u32 l; -- -- /* set fifosize of the channel to 0, then return the old size */ -- l = dsi_read_reg(DSI_TX_FIFO_VC_SIZE); -- -- mask = FLD_MASK((8 * channel) + 7, (8 * channel) + 4); -- dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l & ~mask); -- -- dsi_write_reg(DSI_TX_FIFO_VC_SIZE, l); --} -- - static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, - enum fifo_size size3, enum fifo_size size4) - { -@@ -1753,8 +1785,6 @@ - r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ - - dsi_write_reg(DSI_VC_CTRL(channel), r); -- -- dsi.vc[channel].mode = DSI_VC_MODE_L4; - } - - static int dsi_vc_config_l4(int channel) -@@ -1961,7 +1991,7 @@ - - WARN_ON(!dsi_bus_is_locked()); - -- data_id = data_type | channel << 6; -+ data_id = data_type | dsi.vc[channel].vc_id << 6; - - val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | - FLD_VAL(ecc, 31, 24); -@@ -2064,7 +2094,7 @@ - return -EINVAL; - } - -- data_id = data_type | channel << 6; -+ data_id = data_type | dsi.vc[channel].vc_id << 6; - - r = (data_id << 0) | (data << 8) | (ecc << 24); - -@@ -2984,12 +3014,12 @@ - struct dsi_clock_info cinfo; - int r; - -- /* we always use DSS2_FCK as input clock */ -- cinfo.use_dss2_fck = true; -+ /* we always use DSS_CLK_SYSCK as input clock */ -+ cinfo.use_sys_clk = true; - cinfo.regn = dssdev->phy.dsi.div.regn; - cinfo.regm = dssdev->phy.dsi.div.regm; -- cinfo.regm3 = dssdev->phy.dsi.div.regm3; -- cinfo.regm4 = dssdev->phy.dsi.div.regm4; -+ cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc; -+ cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi; - r = dsi_calc_clock_rates(dssdev, &cinfo); - if (r) { - DSSERR("Failed to calc dsi clocks\n"); -@@ -3011,7 +3041,7 @@ - int r; - unsigned long long fck; - -- fck = dsi_get_dsi1_pll_rate(); -+ fck = dsi_get_pll_hsdiv_dispc_rate(); - - dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; - dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; -@@ -3045,8 +3075,8 @@ - if (r) - goto err1; - -- dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); -- dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); -+ dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); -+ dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI); - - DSSDBG("PLL OK\n"); - -@@ -3082,8 +3112,8 @@ - err3: - dsi_complexio_uninit(); - err2: -- dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); -- dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); -+ dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); -+ dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); - err1: - dsi_pll_uninit(); - err0: -@@ -3099,8 +3129,8 @@ - dsi_vc_enable(2, 0); - dsi_vc_enable(3, 0); - -- dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); -- dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); -+ dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); -+ dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); - dsi_complexio_uninit(); - dsi_pll_uninit(); - } -@@ -3220,28 +3250,94 @@ - dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | - OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; - -- dsi.vc[0].dssdev = dssdev; -- dsi.vc[1].dssdev = dssdev; -+ if (dsi.vdds_dsi_reg == NULL) { -+ struct regulator *vdds_dsi; -+ -+ vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); -+ -+ if (IS_ERR(vdds_dsi)) { -+ DSSERR("can't get VDDS_DSI regulator\n"); -+ return PTR_ERR(vdds_dsi); -+ } -+ -+ dsi.vdds_dsi_reg = vdds_dsi; -+ } -+ -+ return 0; -+} -+ -+int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { -+ if (!dsi.vc[i].dssdev) { -+ dsi.vc[i].dssdev = dssdev; -+ *channel = i; -+ return 0; -+ } -+ } -+ -+ DSSERR("cannot get VC for display %s", dssdev->name); -+ return -ENOSPC; -+} -+EXPORT_SYMBOL(omap_dsi_request_vc); -+ -+int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) -+{ -+ if (vc_id < 0 || vc_id > 3) { -+ DSSERR("VC ID out of range\n"); -+ return -EINVAL; -+ } -+ -+ if (channel < 0 || channel > 3) { -+ DSSERR("Virtual Channel out of range\n"); -+ return -EINVAL; -+ } -+ -+ if (dsi.vc[channel].dssdev != dssdev) { -+ DSSERR("Virtual Channel not allocated to display %s\n", -+ dssdev->name); -+ return -EINVAL; -+ } -+ -+ dsi.vc[channel].vc_id = vc_id; - - return 0; - } -+EXPORT_SYMBOL(omap_dsi_set_vc_id); - --void dsi_wait_dsi1_pll_active(void) -+void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) -+{ -+ if ((channel >= 0 && channel <= 3) && -+ dsi.vc[channel].dssdev == dssdev) { -+ dsi.vc[channel].dssdev = NULL; -+ dsi.vc[channel].vc_id = 0; -+ } -+} -+EXPORT_SYMBOL(omap_dsi_release_vc); -+ -+void dsi_wait_pll_hsdiv_dispc_active(void) - { - if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) -- DSSERR("DSI1 PLL clock not active\n"); -+ DSSERR("%s (%s) not active\n", -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); - } - --void dsi_wait_dsi2_pll_active(void) -+void dsi_wait_pll_hsdiv_dsi_active(void) - { - if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) -- DSSERR("DSI2 PLL clock not active\n"); -+ DSSERR("%s (%s) not active\n", -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); - } - --int dsi_init(struct platform_device *pdev) -+static int dsi_init(struct platform_device *pdev) - { - u32 rev; -- int r; -+ int r, i; -+ struct resource *dsi_mem; - - spin_lock_init(&dsi.errors_lock); - dsi.errors = 0; -@@ -3268,24 +3364,43 @@ - dsi.te_timer.function = dsi_te_timeout; - dsi.te_timer.data = 0; - #endif -- dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS); -+ dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0); -+ if (!dsi_mem) { -+ DSSERR("can't get IORESOURCE_MEM DSI\n"); -+ r = -EINVAL; -+ goto err1; -+ } -+ dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem)); - if (!dsi.base) { - DSSERR("can't ioremap DSI\n"); - r = -ENOMEM; - goto err1; - } -+ dsi.irq = platform_get_irq(dsi.pdev, 0); -+ if (dsi.irq < 0) { -+ DSSERR("platform_get_irq failed\n"); -+ r = -ENODEV; -+ goto err2; -+ } - -- dsi.vdds_dsi_reg = dss_get_vdds_dsi(); -- if (IS_ERR(dsi.vdds_dsi_reg)) { -- DSSERR("can't get VDDS_DSI regulator\n"); -- r = PTR_ERR(dsi.vdds_dsi_reg); -+ r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED, -+ "OMAP DSI1", dsi.pdev); -+ if (r < 0) { -+ DSSERR("request_irq failed\n"); - goto err2; - } - -+ /* DSI VCs initialization */ -+ for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { -+ dsi.vc[i].mode = DSI_VC_MODE_L4; -+ dsi.vc[i].dssdev = NULL; -+ dsi.vc[i].vc_id = 0; -+ } -+ - enable_clocks(1); - - rev = dsi_read_reg(DSI_REVISION); -- printk(KERN_INFO "OMAP DSI rev %d.%d\n", -+ dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n", - FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); - - enable_clocks(0); -@@ -3298,8 +3413,14 @@ - return r; - } - --void dsi_exit(void) -+static void dsi_exit(void) - { -+ if (dsi.vdds_dsi_reg != NULL) { -+ regulator_put(dsi.vdds_dsi_reg); -+ dsi.vdds_dsi_reg = NULL; -+ } -+ -+ free_irq(dsi.irq, dsi.pdev); - iounmap(dsi.base); - - destroy_workqueue(dsi.workqueue); -@@ -3307,3 +3428,41 @@ - DSSDBG("omap_dsi_exit\n"); - } - -+/* DSI1 HW IP initialisation */ -+static int omap_dsi1hw_probe(struct platform_device *pdev) -+{ -+ int r; -+ dsi.pdev = pdev; -+ r = dsi_init(pdev); -+ if (r) { -+ DSSERR("Failed to initialize DSI\n"); -+ goto err_dsi; -+ } -+err_dsi: -+ return r; -+} -+ -+static int omap_dsi1hw_remove(struct platform_device *pdev) -+{ -+ dsi_exit(); -+ return 0; -+} -+ -+static struct platform_driver omap_dsi1hw_driver = { -+ .probe = omap_dsi1hw_probe, -+ .remove = omap_dsi1hw_remove, -+ .driver = { -+ .name = "omapdss_dsi1", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int dsi_init_platform_driver(void) -+{ -+ return platform_driver_register(&omap_dsi1hw_driver); -+} -+ -+void dsi_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omap_dsi1hw_driver); -+} -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dss.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dss.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss.c 2011-03-09 13:19:21.085278903 +0100 -@@ -26,14 +26,13 @@ - #include - #include - #include --#include - #include - #include - - #include -+#include - #include "dss.h" -- --#define DSS_BASE 0x48050000 -+#include "dss_features.h" - - #define DSS_SZ_REGS SZ_512 - -@@ -59,9 +58,17 @@ - dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end)) - - static struct { -+ struct platform_device *pdev; - void __iomem *base; -+ int ctx_id; - - struct clk *dpll4_m4_ck; -+ struct clk *dss_ick; -+ struct clk *dss_fck; -+ struct clk *dss_sys_clk; -+ struct clk *dss_tv_fck; -+ struct clk *dss_video_fck; -+ unsigned num_clks_enabled; - - unsigned long cache_req_pck; - unsigned long cache_prate; -@@ -70,10 +77,22 @@ - - enum dss_clk_source dsi_clk_source; - enum dss_clk_source dispc_clk_source; -+ enum dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS]; - - u32 ctx[DSS_SZ_REGS / sizeof(u32)]; - } dss; - -+static const struct dss_clk_source_name dss_generic_clk_source_names[] = { -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI_PLL_HSDIV_DISPC" }, -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI_PLL_HSDIV_DSI" }, -+ { DSS_CLK_SRC_FCK, "DSS_FCK" }, -+}; -+ -+static void dss_clk_enable_all_no_ctx(void); -+static void dss_clk_disable_all_no_ctx(void); -+static void dss_clk_enable_no_ctx(enum dss_clock clks); -+static void dss_clk_disable_no_ctx(enum dss_clock clks); -+ - static int _omap_dss_wait_reset(void); - - static inline void dss_write_reg(const struct dss_reg idx, u32 val) -@@ -99,10 +118,11 @@ - SR(SYSCONFIG); - SR(CONTROL); - --#ifdef CONFIG_OMAP2_DSS_SDI -- SR(SDI_CONTROL); -- SR(PLL_CONTROL); --#endif -+ if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & -+ OMAP_DISPLAY_TYPE_SDI) { -+ SR(SDI_CONTROL); -+ SR(PLL_CONTROL); -+ } - } - - void dss_restore_context(void) -@@ -113,10 +133,11 @@ - RR(SYSCONFIG); - RR(CONTROL); - --#ifdef CONFIG_OMAP2_DSS_SDI -- RR(SDI_CONTROL); -- RR(PLL_CONTROL); --#endif -+ if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & -+ OMAP_DISPLAY_TYPE_SDI) { -+ RR(SDI_CONTROL); -+ RR(PLL_CONTROL); -+ } - } - - #undef SR -@@ -209,12 +230,17 @@ - REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */ - } - -+const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src) -+{ -+ return dss_generic_clk_source_names[clk_src].clksrc_name; -+} -+ - void dss_dump_clocks(struct seq_file *s) - { - unsigned long dpll4_ck_rate; - unsigned long dpll4_m4_ck_rate; - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); -@@ -224,51 +250,66 @@ - seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); - - if (cpu_is_omap3630()) -- seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n", -+ seq_printf(s, "%s (%s) = %lu / %lu = %lu\n", -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK), - dpll4_ck_rate, - dpll4_ck_rate / dpll4_m4_ck_rate, -- dss_clk_get_rate(DSS_CLK_FCK1)); -+ dss_clk_get_rate(DSS_CLK_FCK)); - else -- seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n", -+ seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n", -+ dss_get_generic_clk_source_name(DSS_CLK_SRC_FCK), -+ dss_feat_get_clk_source_name(DSS_CLK_SRC_FCK), - dpll4_ck_rate, - dpll4_ck_rate / dpll4_m4_ck_rate, -- dss_clk_get_rate(DSS_CLK_FCK1)); -+ dss_clk_get_rate(DSS_CLK_FCK)); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - } - - void dss_dump_regs(struct seq_file *s) - { - #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r)) - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - DUMPREG(DSS_REVISION); - DUMPREG(DSS_SYSCONFIG); - DUMPREG(DSS_SYSSTATUS); - DUMPREG(DSS_IRQSTATUS); - DUMPREG(DSS_CONTROL); -- DUMPREG(DSS_SDI_CONTROL); -- DUMPREG(DSS_PLL_CONTROL); -- DUMPREG(DSS_SDI_STATUS); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) & -+ OMAP_DISPLAY_TYPE_SDI) { -+ DUMPREG(DSS_SDI_CONTROL); -+ DUMPREG(DSS_PLL_CONTROL); -+ DUMPREG(DSS_SDI_STATUS); -+ } -+ -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - #undef DUMPREG - } - - void dss_select_dispc_clk_source(enum dss_clk_source clk_src) - { - int b; -+ u8 start, end; - -- BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && -- clk_src != DSS_SRC_DSS1_ALWON_FCLK); -- -- b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; -+ switch (clk_src) { -+ case DSS_CLK_SRC_FCK: -+ b = 0; -+ break; -+ case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: -+ b = 1; -+ dsi_wait_pll_hsdiv_dispc_active(); -+ break; -+ default: -+ BUG(); -+ } - -- if (clk_src == DSS_SRC_DSI1_PLL_FCLK) -- dsi_wait_dsi1_pll_active(); -+ dss_feat_get_reg_field(FEAT_REG_DISPC_CLK_SWITCH, &start, &end); - -- REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ -+ REG_FLD_MOD(DSS_CONTROL, b, start, end); /* DISPC_CLK_SWITCH */ - - dss.dispc_clk_source = clk_src; - } -@@ -277,19 +318,51 @@ - { - int b; - -- BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && -- clk_src != DSS_SRC_DSS1_ALWON_FCLK); -- -- b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; -- -- if (clk_src == DSS_SRC_DSI2_PLL_FCLK) -- dsi_wait_dsi2_pll_active(); -+ switch (clk_src) { -+ case DSS_CLK_SRC_FCK: -+ b = 0; -+ break; -+ case DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: -+ b = 1; -+ dsi_wait_pll_hsdiv_dsi_active(); -+ break; -+ default: -+ BUG(); -+ } - - REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ - - dss.dsi_clk_source = clk_src; - } - -+void dss_select_lcd_clk_source(enum omap_channel channel, -+ enum dss_clk_source clk_src) -+{ -+ int b, ix, pos; -+ -+ if (!dss_has_feature(FEAT_LCD_CLK_SRC)) -+ return; -+ -+ switch (clk_src) { -+ case DSS_CLK_SRC_FCK: -+ b = 0; -+ break; -+ case DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: -+ BUG_ON(channel != OMAP_DSS_CHANNEL_LCD); -+ b = 1; -+ dsi_wait_pll_hsdiv_dispc_active(); -+ break; -+ default: -+ BUG(); -+ } -+ -+ pos = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 12; -+ REG_FLD_MOD(DSS_CONTROL, b, pos, pos); /* LCDx_CLK_SWITCH */ -+ -+ ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; -+ dss.lcd_clk_source[ix] = clk_src; -+} -+ - enum dss_clk_source dss_get_dispc_clk_source(void) - { - return dss.dispc_clk_source; -@@ -300,6 +373,12 @@ - return dss.dsi_clk_source; - } - -+enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) -+{ -+ int ix = channel == OMAP_DSS_CHANNEL_LCD ? 0 : 1; -+ return dss.lcd_clk_source[ix]; -+} -+ - /* calculate clock rates using dividers in cinfo */ - int dss_calc_clock_rates(struct dss_clock_info *cinfo) - { -@@ -337,7 +416,7 @@ - - int dss_get_clock_div(struct dss_clock_info *cinfo) - { -- cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1); -+ cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK); - - if (cpu_is_omap34xx()) { - unsigned long prate; -@@ -369,7 +448,7 @@ - struct dss_clock_info best_dss; - struct dispc_clock_info best_dispc; - -- unsigned long fck; -+ unsigned long fck, max_dss_fck; - - u16 fck_div; - -@@ -378,7 +457,9 @@ - - prate = dss_get_dpll4_rate(); - -- fck = dss_clk_get_rate(DSS_CLK_FCK1); -+ max_dss_fck = dss_feat_get_max_dss_fck(); -+ -+ fck = dss_clk_get_rate(DSS_CLK_FCK); - if (req_pck == dss.cache_req_pck && - ((cpu_is_omap34xx() && prate == dss.cache_prate) || - dss.cache_dss_cinfo.fck == fck)) { -@@ -391,7 +472,7 @@ - min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK; - - if (min_fck_per_pck && -- req_pck * min_fck_per_pck > DISPC_MAX_FCK) { -+ req_pck * min_fck_per_pck > max_dss_fck) { - DSSERR("Requested pixel clock not possible with the current " - "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning " - "the constraint off.\n"); -@@ -405,7 +486,7 @@ - if (cpu_is_omap24xx()) { - struct dispc_clock_info cur_dispc; - /* XXX can we change the clock on omap2? */ -- fck = dss_clk_get_rate(DSS_CLK_FCK1); -+ fck = dss_clk_get_rate(DSS_CLK_FCK); - fck_div = 1; - - dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc); -@@ -427,7 +508,7 @@ - else - fck = prate / fck_div * 2; - -- if (fck > DISPC_MAX_FCK) -+ if (fck > max_dss_fck) - continue; - - if (min_fck_per_pck && -@@ -482,31 +563,6 @@ - return 0; - } - -- -- --static irqreturn_t dss_irq_handler_omap2(int irq, void *arg) --{ -- dispc_irq_handler(); -- -- return IRQ_HANDLED; --} -- --static irqreturn_t dss_irq_handler_omap3(int irq, void *arg) --{ -- u32 irqstatus; -- -- irqstatus = dss_read_reg(DSS_IRQSTATUS); -- -- if (irqstatus & (1<<0)) /* DISPC_IRQ */ -- dispc_irq_handler(); --#ifdef CONFIG_OMAP2_DSS_DSI -- if (irqstatus & (1<<1)) /* DSI_IRQ */ -- dsi_irq_handler(); --#endif -- -- return IRQ_HANDLED; --} -- - static int _omap_dss_wait_reset(void) - { - int t = 0; -@@ -549,34 +605,39 @@ - REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ - } - --int dss_init(bool skip_init) -+static int dss_init(void) - { - int r; - u32 rev; -+ struct resource *dss_mem; - -- dss.base = ioremap(DSS_BASE, DSS_SZ_REGS); -+ dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0); -+ if (!dss_mem) { -+ DSSERR("can't get IORESOURCE_MEM DSS\n"); -+ r = -EINVAL; -+ goto fail0; -+ } -+ dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); - if (!dss.base) { - DSSERR("can't ioremap DSS\n"); - r = -ENOMEM; - goto fail0; - } - -- if (!skip_init) { -- /* disable LCD and DIGIT output. This seems to fix the synclost -- * problem that we get, if the bootloader starts the DSS and -- * the kernel resets it */ -- omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); -- -- /* We need to wait here a bit, otherwise we sometimes start to -- * get synclost errors, and after that only power cycle will -- * restore DSS functionality. I have no idea why this happens. -- * And we have to wait _before_ resetting the DSS, but after -- * enabling clocks. -- */ -- msleep(50); -+ /* disable LCD and DIGIT output. This seems to fix the synclost -+ * problem that we get, if the bootloader starts the DSS and -+ * the kernel resets it */ -+ omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440); -+ -+ /* We need to wait here a bit, otherwise we sometimes start to -+ * get synclost errors, and after that only power cycle will -+ * restore DSS functionality. I have no idea why this happens. -+ * And we have to wait _before_ resetting the DSS, but after -+ * enabling clocks. -+ */ -+ msleep(50); - -- _omap_dss_reset(); -- } -+ _omap_dss_reset(); - - /* autoidle */ - REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0); -@@ -590,28 +651,19 @@ - REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */ - #endif - -- r = request_irq(INT_24XX_DSS_IRQ, -- cpu_is_omap24xx() -- ? dss_irq_handler_omap2 -- : dss_irq_handler_omap3, -- 0, "OMAP DSS", NULL); -- -- if (r < 0) { -- DSSERR("omap2 dss: request_irq failed\n"); -- goto fail1; -- } -- - if (cpu_is_omap34xx()) { - dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck"); - if (IS_ERR(dss.dpll4_m4_ck)) { - DSSERR("Failed to get dpll4_m4_ck\n"); - r = PTR_ERR(dss.dpll4_m4_ck); -- goto fail2; -+ goto fail1; - } - } - -- dss.dsi_clk_source = DSS_SRC_DSS1_ALWON_FCLK; -- dss.dispc_clk_source = DSS_SRC_DSS1_ALWON_FCLK; -+ dss.dsi_clk_source = DSS_CLK_SRC_FCK; -+ dss.dispc_clk_source = DSS_CLK_SRC_FCK; -+ dss.lcd_clk_source[0] = DSS_CLK_SRC_FCK; -+ dss.lcd_clk_source[1] = DSS_CLK_SRC_FCK; - - dss_save_context(); - -@@ -621,21 +673,416 @@ - - return 0; - --fail2: -- free_irq(INT_24XX_DSS_IRQ, NULL); - fail1: - iounmap(dss.base); - fail0: - return r; - } - --void dss_exit(void) -+static void dss_exit(void) - { - if (cpu_is_omap34xx()) - clk_put(dss.dpll4_m4_ck); - -- free_irq(INT_24XX_DSS_IRQ, NULL); -- - iounmap(dss.base); - } - -+/* CONTEXT */ -+static int dss_get_ctx_id(void) -+{ -+ struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data; -+ int r; -+ -+ if (!pdata->board_data->get_last_off_on_transaction_id) -+ return 0; -+ r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev); -+ if (r < 0) { -+ dev_err(&dss.pdev->dev, "getting transaction ID failed, " -+ "will force context restore\n"); -+ r = -1; -+ } -+ return r; -+} -+ -+int dss_need_ctx_restore(void) -+{ -+ int id = dss_get_ctx_id(); -+ -+ if (id < 0 || id != dss.ctx_id) { -+ DSSDBG("ctx id %d -> id %d\n", -+ dss.ctx_id, id); -+ dss.ctx_id = id; -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ -+static void save_all_ctx(void) -+{ -+ DSSDBG("save context\n"); -+ -+ dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); -+ -+ dss_save_context(); -+ dispc_save_context(); -+#ifdef CONFIG_OMAP2_DSS_DSI -+ dsi_save_context(); -+#endif -+ -+ dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK); -+} -+ -+static void restore_all_ctx(void) -+{ -+ DSSDBG("restore context\n"); -+ -+ dss_clk_enable_all_no_ctx(); -+ -+ dss_restore_context(); -+ dispc_restore_context(); -+#ifdef CONFIG_OMAP2_DSS_DSI -+ dsi_restore_context(); -+#endif -+ -+ dss_clk_disable_all_no_ctx(); -+} -+ -+static int dss_get_clock(struct clk **clock, const char *clk_name) -+{ -+ struct clk *clk; -+ -+ clk = clk_get(&dss.pdev->dev, clk_name); -+ -+ if (IS_ERR(clk)) { -+ DSSERR("can't get clock %s", clk_name); -+ return PTR_ERR(clk); -+ } -+ -+ *clock = clk; -+ -+ DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk)); -+ -+ return 0; -+} -+ -+static int dss_get_clocks(void) -+{ -+ int r; -+ struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data; -+ -+ dss.dss_ick = NULL; -+ dss.dss_fck = NULL; -+ dss.dss_sys_clk = NULL; -+ dss.dss_tv_fck = NULL; -+ dss.dss_video_fck = NULL; -+ -+ r = dss_get_clock(&dss.dss_ick, "ick"); -+ if (r) -+ goto err; -+ -+ r = dss_get_clock(&dss.dss_fck, "fck"); -+ if (r) -+ goto err; -+ -+ if (!pdata->opt_clock_available) { -+ r = -ENODEV; -+ goto err; -+ } -+ -+ if (pdata->opt_clock_available("sys_clk")) { -+ r = dss_get_clock(&dss.dss_sys_clk, "sys_clk"); -+ if (r) -+ goto err; -+ } -+ -+ if (pdata->opt_clock_available("tv_clk")) { -+ r = dss_get_clock(&dss.dss_tv_fck, "tv_clk"); -+ if (r) -+ goto err; -+ } -+ -+ if (pdata->opt_clock_available("video_clk")) { -+ r = dss_get_clock(&dss.dss_video_fck, "video_clk"); -+ if (r) -+ goto err; -+ } -+ -+ return 0; -+ -+err: -+ if (dss.dss_ick) -+ clk_put(dss.dss_ick); -+ if (dss.dss_fck) -+ clk_put(dss.dss_fck); -+ if (dss.dss_sys_clk) -+ clk_put(dss.dss_sys_clk); -+ if (dss.dss_tv_fck) -+ clk_put(dss.dss_tv_fck); -+ if (dss.dss_video_fck) -+ clk_put(dss.dss_video_fck); -+ -+ return r; -+} -+ -+static void dss_put_clocks(void) -+{ -+ if (dss.dss_video_fck) -+ clk_put(dss.dss_video_fck); -+ if (dss.dss_tv_fck) -+ clk_put(dss.dss_tv_fck); -+ if (dss.dss_sys_clk) -+ clk_put(dss.dss_sys_clk); -+ clk_put(dss.dss_fck); -+ clk_put(dss.dss_ick); -+} -+ -+unsigned long dss_clk_get_rate(enum dss_clock clk) -+{ -+ switch (clk) { -+ case DSS_CLK_ICK: -+ return clk_get_rate(dss.dss_ick); -+ case DSS_CLK_FCK: -+ return clk_get_rate(dss.dss_fck); -+ case DSS_CLK_SYSCK: -+ return clk_get_rate(dss.dss_sys_clk); -+ case DSS_CLK_TVFCK: -+ return clk_get_rate(dss.dss_tv_fck); -+ case DSS_CLK_VIDFCK: -+ return clk_get_rate(dss.dss_video_fck); -+ } -+ -+ BUG(); -+ return 0; -+} -+ -+static unsigned count_clk_bits(enum dss_clock clks) -+{ -+ unsigned num_clks = 0; -+ -+ if (clks & DSS_CLK_ICK) -+ ++num_clks; -+ if (clks & DSS_CLK_FCK) -+ ++num_clks; -+ if (clks & DSS_CLK_SYSCK) -+ ++num_clks; -+ if (clks & DSS_CLK_TVFCK) -+ ++num_clks; -+ if (clks & DSS_CLK_VIDFCK) -+ ++num_clks; -+ -+ return num_clks; -+} -+ -+static void dss_clk_enable_no_ctx(enum dss_clock clks) -+{ -+ unsigned num_clks = count_clk_bits(clks); -+ -+ if (clks & DSS_CLK_ICK) -+ clk_enable(dss.dss_ick); -+ if (clks & DSS_CLK_FCK) -+ clk_enable(dss.dss_fck); -+ if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) -+ clk_enable(dss.dss_sys_clk); -+ if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) -+ clk_enable(dss.dss_tv_fck); -+ if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck) -+ clk_enable(dss.dss_video_fck); -+ -+ dss.num_clks_enabled += num_clks; -+} -+ -+void dss_clk_enable(enum dss_clock clks) -+{ -+ bool check_ctx = dss.num_clks_enabled == 0; -+ -+ dss_clk_enable_no_ctx(clks); -+ -+ /* -+ * HACK: On omap4 the registers may not be accessible right after -+ * enabling the clocks. At some point this will be handled by -+ * pm_runtime, but for the time begin this should make things work. -+ */ -+ if (cpu_is_omap44xx() && check_ctx) -+ udelay(10); -+ -+ if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) -+ restore_all_ctx(); -+} -+ -+static void dss_clk_disable_no_ctx(enum dss_clock clks) -+{ -+ unsigned num_clks = count_clk_bits(clks); -+ -+ if (clks & DSS_CLK_ICK) -+ clk_disable(dss.dss_ick); -+ if (clks & DSS_CLK_FCK) -+ clk_disable(dss.dss_fck); -+ if ((clks & DSS_CLK_SYSCK) && dss.dss_sys_clk) -+ clk_disable(dss.dss_sys_clk); -+ if ((clks & DSS_CLK_TVFCK) && dss.dss_tv_fck) -+ clk_disable(dss.dss_tv_fck); -+ if ((clks & DSS_CLK_VIDFCK) && dss.dss_video_fck) -+ clk_disable(dss.dss_video_fck); -+ -+ dss.num_clks_enabled -= num_clks; -+} -+ -+void dss_clk_disable(enum dss_clock clks) -+{ -+ if (cpu_is_omap34xx()) { -+ unsigned num_clks = count_clk_bits(clks); -+ -+ BUG_ON(dss.num_clks_enabled < num_clks); -+ -+ if (dss.num_clks_enabled == num_clks) -+ save_all_ctx(); -+ } -+ -+ dss_clk_disable_no_ctx(clks); -+} -+ -+static void dss_clk_enable_all_no_ctx(void) -+{ -+ enum dss_clock clks; -+ -+ clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; -+ if (cpu_is_omap34xx()) -+ clks |= DSS_CLK_VIDFCK; -+ dss_clk_enable_no_ctx(clks); -+} -+ -+static void dss_clk_disable_all_no_ctx(void) -+{ -+ enum dss_clock clks; -+ -+ clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK; -+ if (cpu_is_omap34xx()) -+ clks |= DSS_CLK_VIDFCK; -+ dss_clk_disable_no_ctx(clks); -+} -+ -+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) -+/* CLOCKS */ -+static void core_dump_clocks(struct seq_file *s) -+{ -+ int i; -+ struct clk *clocks[5] = { -+ dss.dss_ick, -+ dss.dss_fck, -+ dss.dss_sys_clk, -+ dss.dss_tv_fck, -+ dss.dss_video_fck -+ }; -+ -+ seq_printf(s, "- CORE -\n"); -+ -+ seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled); -+ -+ for (i = 0; i < 5; i++) { -+ if (!clocks[i]) -+ continue; -+ seq_printf(s, "%-15s\t%lu\t%d\n", -+ clocks[i]->name, -+ clk_get_rate(clocks[i]), -+ clocks[i]->usecount); -+ } -+} -+#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */ -+ -+/* DEBUGFS */ -+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) -+void dss_debug_dump_clocks(struct seq_file *s) -+{ -+ core_dump_clocks(s); -+ dss_dump_clocks(s); -+ dispc_dump_clocks(s); -+#ifdef CONFIG_OMAP2_DSS_DSI -+ dsi_dump_clocks(s); -+#endif -+} -+#endif -+ -+ -+/* DSS HW IP initialisation */ -+static int omap_dsshw_probe(struct platform_device *pdev) -+{ -+ int r; -+ -+ dss.pdev = pdev; -+ -+ r = dss_get_clocks(); -+ if (r) -+ goto err_clocks; -+ -+ dss_clk_enable_all_no_ctx(); -+ -+ dss.ctx_id = dss_get_ctx_id(); -+ DSSDBG("initial ctx id %u\n", dss.ctx_id); -+ -+ r = dss_init(); -+ if (r) { -+ DSSERR("Failed to initialize DSS\n"); -+ goto err_dss; -+ } -+ -+ r = dpi_init(); -+ if (r) { -+ DSSERR("Failed to initialize DPI\n"); -+ goto err_dpi; -+ } -+ -+ r = sdi_init(); -+ if (r) { -+ DSSERR("Failed to initialize SDI\n"); -+ goto err_sdi; -+ } -+ -+ dss_clk_disable_all_no_ctx(); -+ return 0; -+err_sdi: -+ dpi_exit(); -+err_dpi: -+ dss_exit(); -+err_dss: -+ dss_clk_disable_all_no_ctx(); -+ dss_put_clocks(); -+err_clocks: -+ return r; -+} -+ -+static int omap_dsshw_remove(struct platform_device *pdev) -+{ -+ -+ dss_exit(); -+ -+ /* -+ * As part of hwmod changes, DSS is not the only controller of dss -+ * clocks; hwmod framework itself will also enable clocks during hwmod -+ * init for dss, and autoidle is set in h/w for DSS. Hence, there's no -+ * need to disable clocks if their usecounts > 1. -+ */ -+ WARN_ON(dss.num_clks_enabled > 0); -+ -+ dss_put_clocks(); -+ return 0; -+} -+ -+static struct platform_driver omap_dsshw_driver = { -+ .probe = omap_dsshw_probe, -+ .remove = omap_dsshw_remove, -+ .driver = { -+ .name = "omapdss_dss", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int dss_init_platform_driver(void) -+{ -+ return platform_driver_register(&omap_dsshw_driver); -+} -+ -+void dss_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omap_dsshw_driver); -+} -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dss_features.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss_features.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dss_features.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss_features.c 2011-03-09 13:19:21.085278903 +0100 -@@ -25,6 +25,7 @@ - #include - #include - -+#include "dss.h" - #include "dss_features.h" - - /* Defines a generic omap register field */ -@@ -41,8 +42,10 @@ - - const int num_mgrs; - const int num_ovls; -+ const unsigned long max_dss_fck; - const enum omap_display_type *supported_displays; - const enum omap_color_mode *supported_color_modes; -+ const struct dss_clk_source_name *clksrc_names; - }; - - /* This struct is assigned to one of the below during initialization */ -@@ -54,6 +57,9 @@ - { FEAT_REG_FIFOLOWTHRESHOLD, 8, 0 }, - { FEAT_REG_FIFOHIGHTHRESHOLD, 24, 16 }, - { FEAT_REG_FIFOSIZE, 8, 0 }, -+ { FEAT_REG_HORIZONTALACCU, 9, 0 }, -+ { FEAT_REG_VERTICALACCU, 25, 16 }, -+ { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, - }; - - static const struct dss_reg_field omap3_dss_reg_fields[] = { -@@ -62,10 +68,32 @@ - { FEAT_REG_FIFOLOWTHRESHOLD, 11, 0 }, - { FEAT_REG_FIFOHIGHTHRESHOLD, 27, 16 }, - { FEAT_REG_FIFOSIZE, 10, 0 }, -+ { FEAT_REG_HORIZONTALACCU, 9, 0 }, -+ { FEAT_REG_VERTICALACCU, 25, 16 }, -+ { FEAT_REG_DISPC_CLK_SWITCH, 0, 0 }, -+}; -+ -+static const struct dss_reg_field omap4_dss_reg_fields[] = { -+ { FEAT_REG_FIRHINC, 12, 0 }, -+ { FEAT_REG_FIRVINC, 28, 16 }, -+ { FEAT_REG_FIFOLOWTHRESHOLD, 15, 0 }, -+ { FEAT_REG_FIFOHIGHTHRESHOLD, 31, 16 }, -+ { FEAT_REG_FIFOSIZE, 15, 0 }, -+ { FEAT_REG_HORIZONTALACCU, 10, 0 }, -+ { FEAT_REG_VERTICALACCU, 26, 16 }, -+ { FEAT_REG_DISPC_CLK_SWITCH, 9, 8 }, - }; - - static const enum omap_display_type omap2_dss_supported_displays[] = { - /* OMAP_DSS_CHANNEL_LCD */ -+ OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, -+ -+ /* OMAP_DSS_CHANNEL_DIGIT */ -+ OMAP_DISPLAY_TYPE_VENC, -+}; -+ -+static const enum omap_display_type omap3430_dss_supported_displays[] = { -+ /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | - OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, - -@@ -73,10 +101,10 @@ - OMAP_DISPLAY_TYPE_VENC, - }; - --static const enum omap_display_type omap3_dss_supported_displays[] = { -+static const enum omap_display_type omap3630_dss_supported_displays[] = { - /* OMAP_DSS_CHANNEL_LCD */ - OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | -- OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI, -+ OMAP_DISPLAY_TYPE_DSI, - - /* OMAP_DSS_CHANNEL_DIGIT */ - OMAP_DISPLAY_TYPE_VENC, -@@ -134,6 +162,24 @@ - OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32, - }; - -+static const struct dss_clk_source_name omap2_dss_clk_source_names[] = { -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "N/A" }, -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "N/A" }, -+ { DSS_CLK_SRC_FCK, "DSS_FCLK1" }, -+}; -+ -+static const struct dss_clk_source_name omap3_dss_clk_source_names[] = { -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "DSI1_PLL_FCLK" }, -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "DSI2_PLL_FCLK" }, -+ { DSS_CLK_SRC_FCK, "DSS1_ALWON_FCLK" }, -+}; -+ -+static const struct dss_clk_source_name omap4_dss_clk_source_names[] = { -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, "PLL1_CLK1" }, -+ { DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, "PLL1_CLK2" }, -+ { DSS_CLK_SRC_FCK, "DSS_FCLK" }, -+}; -+ - /* OMAP2 DSS Features */ - static struct omap_dss_features omap2_dss_features = { - .reg_fields = omap2_dss_reg_fields, -@@ -141,12 +187,15 @@ - - .has_feature = - FEAT_LCDENABLEPOL | FEAT_LCDENABLESIGNAL | -- FEAT_PCKFREEENABLE | FEAT_FUNCGATED, -+ FEAT_PCKFREEENABLE | FEAT_FUNCGATED | -+ FEAT_ROWREPEATENABLE | FEAT_RESIZECONF, - - .num_mgrs = 2, - .num_ovls = 3, -+ .max_dss_fck = 173000000, - .supported_displays = omap2_dss_supported_displays, - .supported_color_modes = omap2_dss_supported_color_modes, -+ .clksrc_names = omap2_dss_clk_source_names, - }; - - /* OMAP3 DSS Features */ -@@ -157,12 +206,15 @@ - .has_feature = - FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | - FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | -- FEAT_FUNCGATED, -+ FEAT_FUNCGATED | FEAT_ROWREPEATENABLE | -+ FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF, - - .num_mgrs = 2, - .num_ovls = 3, -- .supported_displays = omap3_dss_supported_displays, -+ .max_dss_fck = 173000000, -+ .supported_displays = omap3430_dss_supported_displays, - .supported_color_modes = omap3_dss_supported_color_modes, -+ .clksrc_names = omap3_dss_clk_source_names, - }; - - static struct omap_dss_features omap3630_dss_features = { -@@ -172,27 +224,34 @@ - .has_feature = - FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL | - FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE | -- FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED, -+ FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED | -+ FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | -+ FEAT_RESIZECONF, - - .num_mgrs = 2, - .num_ovls = 3, -- .supported_displays = omap3_dss_supported_displays, -+ .max_dss_fck = 173000000, -+ .supported_displays = omap3630_dss_supported_displays, - .supported_color_modes = omap3_dss_supported_color_modes, -+ .clksrc_names = omap3_dss_clk_source_names, - }; - - /* OMAP4 DSS Features */ - static struct omap_dss_features omap4_dss_features = { -- .reg_fields = omap3_dss_reg_fields, -- .num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), -+ .reg_fields = omap4_dss_reg_fields, -+ .num_reg_fields = ARRAY_SIZE(omap4_dss_reg_fields), - - .has_feature = - FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA | -- FEAT_MGR_LCD2, -+ FEAT_MGR_LCD2 | FEAT_GLOBAL_ALPHA_VID1 | -+ FEAT_CORE_CLK_DIV | FEAT_LCD_CLK_SRC, - - .num_mgrs = 3, - .num_ovls = 3, -+ .max_dss_fck = 186000000, - .supported_displays = omap4_dss_supported_displays, - .supported_color_modes = omap3_dss_supported_color_modes, -+ .clksrc_names = omap4_dss_clk_source_names, - }; - - /* Functions returning values related to a DSS feature */ -@@ -206,6 +265,12 @@ - return omap_current_dss_features->num_ovls; - } - -+/* Max supported DSS FCK in Hz */ -+unsigned long dss_feat_get_max_dss_fck(void) -+{ -+ return omap_current_dss_features->max_dss_fck; -+} -+ - enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel) - { - return omap_current_dss_features->supported_displays[channel]; -@@ -223,6 +288,11 @@ - color_mode; - } - -+const char *dss_feat_get_clk_source_name(enum dss_clk_source id) -+{ -+ return omap_current_dss_features->clksrc_names[id].clksrc_name; -+} -+ - /* DSS has_feature check */ - bool dss_has_feature(enum dss_feat_id id) - { -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dss_features.h linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss_features.h ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dss_features.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss_features.h 2011-03-09 13:19:21.085278903 +0100 -@@ -22,6 +22,7 @@ - - #define MAX_DSS_MANAGERS 3 - #define MAX_DSS_OVERLAYS 3 -+#define MAX_DSS_LCD_MANAGERS 2 - - /* DSS has feature id */ - enum dss_feat_id { -@@ -33,6 +34,12 @@ - FEAT_PCKFREEENABLE = 1 << 5, - FEAT_FUNCGATED = 1 << 6, - FEAT_MGR_LCD2 = 1 << 7, -+ FEAT_LINEBUFFERSPLIT = 1 << 8, -+ FEAT_ROWREPEATENABLE = 1 << 9, -+ FEAT_RESIZECONF = 1 << 10, -+ /* Independent core clk divider */ -+ FEAT_CORE_CLK_DIV = 1 << 11, -+ FEAT_LCD_CLK_SRC = 1 << 12, - }; - - /* DSS register field id */ -@@ -42,15 +49,20 @@ - FEAT_REG_FIFOHIGHTHRESHOLD, - FEAT_REG_FIFOLOWTHRESHOLD, - FEAT_REG_FIFOSIZE, -+ FEAT_REG_HORIZONTALACCU, -+ FEAT_REG_VERTICALACCU, -+ FEAT_REG_DISPC_CLK_SWITCH, - }; - - /* DSS Feature Functions */ - int dss_feat_get_num_mgrs(void); - int dss_feat_get_num_ovls(void); -+unsigned long dss_feat_get_max_dss_fck(void); - enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); - enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); - bool dss_feat_color_mode_supported(enum omap_plane plane, - enum omap_color_mode color_mode); -+const char *dss_feat_get_clk_source_name(enum dss_clk_source id); - - bool dss_has_feature(enum dss_feat_id id); - void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end); -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/dss.h linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss.h ---- linux-2.6.38-rc7/drivers/video/omap2/dss/dss.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/dss.h 2011-03-09 13:19:21.085278903 +0100 -@@ -97,8 +97,6 @@ - #define FLD_MOD(orig, val, start, end) \ - (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end)) - --#define DISPC_MAX_FCK 173000000 -- - enum omap_burst_size { - OMAP_DSS_BURST_4x32 = 0, - OMAP_DSS_BURST_8x32 = 1, -@@ -112,17 +110,26 @@ - }; - - enum dss_clock { -- DSS_CLK_ICK = 1 << 0, -- DSS_CLK_FCK1 = 1 << 1, -- DSS_CLK_FCK2 = 1 << 2, -- DSS_CLK_54M = 1 << 3, -- DSS_CLK_96M = 1 << 4, -+ DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */ -+ DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */ -+ DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */ -+ DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */ -+ DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/ - }; - - enum dss_clk_source { -- DSS_SRC_DSI1_PLL_FCLK, -- DSS_SRC_DSI2_PLL_FCLK, -- DSS_SRC_DSS1_ALWON_FCLK, -+ DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC, /* OMAP3: DSI1_PLL_FCLK -+ * OMAP4: PLL1_CLK1 */ -+ DSS_CLK_SRC_DSI_PLL_HSDIV_DSI, /* OMAP3: DSI2_PLL_FCLK -+ * OMAP4: PLL1_CLK2 */ -+ DSS_CLK_SRC_FCK, /* OMAP2/3: DSS1_ALWON_FCLK -+ * OMAP4: DSS_FCLK */ -+}; -+ -+/* Correlates clock source name and dss_clk_source member */ -+struct dss_clk_source_name { -+ enum dss_clk_source clksrc; -+ const char *clksrc_name; - }; - - struct dss_clock_info { -@@ -148,36 +155,32 @@ - unsigned long fint; - unsigned long clkin4ddr; - unsigned long clkin; -- unsigned long dsi1_pll_fclk; -- unsigned long dsi2_pll_fclk; -- -+ unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK -+ * OMAP4: PLLx_CLK1 */ -+ unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK -+ * OMAP4: PLLx_CLK2 */ - unsigned long lp_clk; - - /* dividers */ - u16 regn; - u16 regm; -- u16 regm3; -- u16 regm4; -- -+ u16 regm_dispc; /* OMAP3: REGM3 -+ * OMAP4: REGM4 */ -+ u16 regm_dsi; /* OMAP3: REGM4 -+ * OMAP4: REGM5 */ - u16 lp_clk_div; - - u8 highfreq; -- bool use_dss2_fck; -+ bool use_sys_clk; - }; - - struct seq_file; - struct platform_device; - - /* core */ --void dss_clk_enable(enum dss_clock clks); --void dss_clk_disable(enum dss_clock clks); --unsigned long dss_clk_get_rate(enum dss_clock clk); --int dss_need_ctx_restore(void); --void dss_dump_clocks(struct seq_file *s); - struct bus_type *dss_get_bus(void); - struct regulator *dss_get_vdds_dsi(void); - struct regulator *dss_get_vdds_sdi(void); --struct regulator *dss_get_vdda_dac(void); - - /* display */ - int dss_suspend_all_devices(void); -@@ -214,13 +217,22 @@ - void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); - - /* DSS */ --int dss_init(bool skip_init); --void dss_exit(void); -+int dss_init_platform_driver(void); -+void dss_uninit_platform_driver(void); - - void dss_save_context(void); - void dss_restore_context(void); -+void dss_clk_enable(enum dss_clock clks); -+void dss_clk_disable(enum dss_clock clks); -+unsigned long dss_clk_get_rate(enum dss_clock clk); -+int dss_need_ctx_restore(void); -+const char *dss_get_generic_clk_source_name(enum dss_clk_source clk_src); -+void dss_dump_clocks(struct seq_file *s); - - void dss_dump_regs(struct seq_file *s); -+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) -+void dss_debug_dump_clocks(struct seq_file *s); -+#endif - - void dss_sdi_init(u8 datapairs); - int dss_sdi_enable(void); -@@ -228,8 +240,11 @@ - - void dss_select_dispc_clk_source(enum dss_clk_source clk_src); - void dss_select_dsi_clk_source(enum dss_clk_source clk_src); -+void dss_select_lcd_clk_source(enum omap_channel channel, -+ enum dss_clk_source clk_src); - enum dss_clk_source dss_get_dispc_clk_source(void); - enum dss_clk_source dss_get_dsi_clk_source(void); -+enum dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel); - - void dss_set_venc_output(enum omap_dss_venc_type type); - void dss_set_dac_pwrdn_bgz(bool enable); -@@ -244,11 +259,11 @@ - - /* SDI */ - #ifdef CONFIG_OMAP2_DSS_SDI --int sdi_init(bool skip_init); -+int sdi_init(void); - void sdi_exit(void); - int sdi_init_display(struct omap_dss_device *display); - #else --static inline int sdi_init(bool skip_init) -+static inline int sdi_init(void) - { - return 0; - } -@@ -259,8 +274,8 @@ - - /* DSI */ - #ifdef CONFIG_OMAP2_DSS_DSI --int dsi_init(struct platform_device *pdev); --void dsi_exit(void); -+int dsi_init_platform_driver(void); -+void dsi_uninit_platform_driver(void); - - void dsi_dump_clocks(struct seq_file *s); - void dsi_dump_irqs(struct seq_file *s); -@@ -271,7 +286,7 @@ - - int dsi_init_display(struct omap_dss_device *display); - void dsi_irq_handler(void); --unsigned long dsi_get_dsi1_pll_rate(void); -+unsigned long dsi_get_pll_hsdiv_dispc_rate(void); - int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo); - int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, - struct dsi_clock_info *cinfo, -@@ -282,31 +297,36 @@ - void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, enum omap_burst_size *burst_size, - u32 *fifo_low, u32 *fifo_high); --void dsi_wait_dsi1_pll_active(void); --void dsi_wait_dsi2_pll_active(void); -+void dsi_wait_pll_hsdiv_dispc_active(void); -+void dsi_wait_pll_hsdiv_dsi_active(void); - #else --static inline int dsi_init(struct platform_device *pdev) -+static inline int dsi_init_platform_driver(void) - { - return 0; - } --static inline void dsi_exit(void) -+static inline void dsi_uninit_platform_driver(void) -+{ -+} -+static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(void) - { -+ WARN("%s: DSI not compiled in, returning rate as 0\n", __func__); -+ return 0; - } --static inline void dsi_wait_dsi1_pll_active(void) -+static inline void dsi_wait_pll_hsdiv_dispc_active(void) - { - } --static inline void dsi_wait_dsi2_pll_active(void) -+static inline void dsi_wait_pll_hsdiv_dsi_active(void) - { - } - #endif - - /* DPI */ - #ifdef CONFIG_OMAP2_DSS_DPI --int dpi_init(struct platform_device *pdev); -+int dpi_init(void); - void dpi_exit(void); - int dpi_init_display(struct omap_dss_device *dssdev); - #else --static inline int dpi_init(struct platform_device *pdev) -+static inline int dpi_init(void) - { - return 0; - } -@@ -316,8 +336,8 @@ - #endif - - /* DISPC */ --int dispc_init(void); --void dispc_exit(void); -+int dispc_init_platform_driver(void); -+void dispc_uninit_platform_driver(void); - void dispc_dump_clocks(struct seq_file *s); - void dispc_dump_irqs(struct seq_file *s); - void dispc_dump_regs(struct seq_file *s); -@@ -409,24 +429,24 @@ - - /* VENC */ - #ifdef CONFIG_OMAP2_DSS_VENC --int venc_init(struct platform_device *pdev); --void venc_exit(void); -+int venc_init_platform_driver(void); -+void venc_uninit_platform_driver(void); - void venc_dump_regs(struct seq_file *s); - int venc_init_display(struct omap_dss_device *display); - #else --static inline int venc_init(struct platform_device *pdev) -+static inline int venc_init_platform_driver(void) - { - return 0; - } --static inline void venc_exit(void) -+static inline void venc_uninit_platform_driver(void) - { - } - #endif - - /* RFBI */ - #ifdef CONFIG_OMAP2_DSS_RFBI --int rfbi_init(void); --void rfbi_exit(void); -+int rfbi_init_platform_driver(void); -+void rfbi_uninit_platform_driver(void); - void rfbi_dump_regs(struct seq_file *s); - - int rfbi_configure(int rfbi_module, int bpp, int lines); -@@ -437,11 +457,11 @@ - unsigned long rfbi_get_max_tx_rate(void); - int rfbi_init_display(struct omap_dss_device *display); - #else --static inline int rfbi_init(void) -+static inline int rfbi_init_platform_driver(void) - { - return 0; - } --static inline void rfbi_exit(void) -+static inline void rfbi_uninit_platform_driver(void) - { - } - #endif -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/Kconfig ---- linux-2.6.38-rc7/drivers/video/omap2/dss/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/Kconfig 2011-03-09 13:19:21.081278983 +0100 -@@ -1,8 +1,8 @@ - menuconfig OMAP2_DSS -- tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)" -- depends on ARCH_OMAP2 || ARCH_OMAP3 -+ tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)" -+ depends on ARCH_OMAP2PLUS - help -- OMAP2/3 Display Subsystem support. -+ OMAP2+ Display Subsystem support. - - if OMAP2_DSS - -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/manager.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/manager.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/manager.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/manager.c 2011-03-09 13:19:21.086278883 +0100 -@@ -1394,7 +1394,7 @@ - } - - r = 0; -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - if (!dss_cache.irq_enabled) { - u32 mask; - -@@ -1407,7 +1407,7 @@ - dss_cache.irq_enabled = true; - } - configure_dispc(); -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - - spin_unlock_irqrestore(&dss_cache.lock, flags); - -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/overlay.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/overlay.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/overlay.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/overlay.c 2011-03-09 13:19:21.086278883 +0100 -@@ -490,7 +490,7 @@ - - ovl->manager = mgr; - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - /* XXX: on manual update display, in auto update mode, a bug happens - * here. When an overlay is first enabled on LCD, then it's disabled, - * and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT -@@ -499,7 +499,7 @@ - * but I don't understand how or why. */ - msleep(40); - dispc_set_channel_out(ovl->id, mgr->id); -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - - return 0; - } -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/rfbi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/rfbi.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/rfbi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/rfbi.c 2011-03-09 13:19:21.086278883 +0100 -@@ -36,8 +36,6 @@ - #include - #include "dss.h" - --#define RFBI_BASE 0x48050800 -- - struct rfbi_reg { u16 idx; }; - - #define RFBI_REG(idx) ((const struct rfbi_reg) { idx }) -@@ -100,6 +98,7 @@ - static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div); - - static struct { -+ struct platform_device *pdev; - void __iomem *base; - - unsigned long l4_khz; -@@ -142,9 +141,9 @@ - static void rfbi_enable_clocks(bool enable) - { - if (enable) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - else -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - } - - void omap_rfbi_write_command(const void *buf, u32 len) -@@ -497,7 +496,7 @@ - }; - - l4_rate = rfbi.l4_khz / 1000; -- dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000; -+ dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000; - - for (i = 0; i < ARRAY_SIZE(ftab); i++) { - /* Use a window instead of an exact match, to account -@@ -922,7 +921,7 @@ - { - #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r)) - -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - DUMPREG(RFBI_REVISION); - DUMPREG(RFBI_SYSCONFIG); -@@ -953,54 +952,10 @@ - DUMPREG(RFBI_VSYNC_WIDTH); - DUMPREG(RFBI_HSYNC_WIDTH); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - #undef DUMPREG - } - --int rfbi_init(void) --{ -- u32 rev; -- u32 l; -- -- spin_lock_init(&rfbi.cmd_lock); -- -- init_completion(&rfbi.cmd_done); -- atomic_set(&rfbi.cmd_fifo_full, 0); -- atomic_set(&rfbi.cmd_pending, 0); -- -- rfbi.base = ioremap(RFBI_BASE, SZ_256); -- if (!rfbi.base) { -- DSSERR("can't ioremap RFBI\n"); -- return -ENOMEM; -- } -- -- rfbi_enable_clocks(1); -- -- msleep(10); -- -- rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; -- -- /* Enable autoidle and smart-idle */ -- l = rfbi_read_reg(RFBI_SYSCONFIG); -- l |= (1 << 0) | (2 << 3); -- rfbi_write_reg(RFBI_SYSCONFIG, l); -- -- rev = rfbi_read_reg(RFBI_REVISION); -- printk(KERN_INFO "OMAP RFBI rev %d.%d\n", -- FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); -- -- rfbi_enable_clocks(0); -- -- return 0; --} -- --void rfbi_exit(void) --{ -- DSSDBG("rfbi_exit\n"); -- -- iounmap(rfbi.base); --} -- - int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) - { - int r; -@@ -1056,3 +1011,74 @@ - dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; - return 0; - } -+ -+/* RFBI HW IP initialisation */ -+static int omap_rfbihw_probe(struct platform_device *pdev) -+{ -+ u32 rev; -+ u32 l; -+ struct resource *rfbi_mem; -+ -+ rfbi.pdev = pdev; -+ -+ spin_lock_init(&rfbi.cmd_lock); -+ -+ init_completion(&rfbi.cmd_done); -+ atomic_set(&rfbi.cmd_fifo_full, 0); -+ atomic_set(&rfbi.cmd_pending, 0); -+ -+ rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0); -+ if (!rfbi_mem) { -+ DSSERR("can't get IORESOURCE_MEM RFBI\n"); -+ return -EINVAL; -+ } -+ rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); -+ if (!rfbi.base) { -+ DSSERR("can't ioremap RFBI\n"); -+ return -ENOMEM; -+ } -+ -+ rfbi_enable_clocks(1); -+ -+ msleep(10); -+ -+ rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000; -+ -+ /* Enable autoidle and smart-idle */ -+ l = rfbi_read_reg(RFBI_SYSCONFIG); -+ l |= (1 << 0) | (2 << 3); -+ rfbi_write_reg(RFBI_SYSCONFIG, l); -+ -+ rev = rfbi_read_reg(RFBI_REVISION); -+ dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n", -+ FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); -+ -+ rfbi_enable_clocks(0); -+ -+ return 0; -+} -+ -+static int omap_rfbihw_remove(struct platform_device *pdev) -+{ -+ iounmap(rfbi.base); -+ return 0; -+} -+ -+static struct platform_driver omap_rfbihw_driver = { -+ .probe = omap_rfbihw_probe, -+ .remove = omap_rfbihw_remove, -+ .driver = { -+ .name = "omapdss_rfbi", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int rfbi_init_platform_driver(void) -+{ -+ return platform_driver_register(&omap_rfbihw_driver); -+} -+ -+void rfbi_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omap_rfbihw_driver); -+} -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/sdi.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/sdi.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/sdi.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/sdi.c 2011-03-09 13:19:21.086278883 +0100 -@@ -30,7 +30,6 @@ - #include "dss.h" - - static struct { -- bool skip_init; - bool update_enabled; - struct regulator *vdds_sdi_reg; - } sdi; -@@ -68,9 +67,7 @@ - if (r) - goto err1; - -- /* In case of skip_init sdi_init has already enabled the clocks */ -- if (!sdi.skip_init) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - - sdi_basic_init(dssdev); - -@@ -80,14 +77,8 @@ - dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config, - dssdev->panel.acbi, dssdev->panel.acb); - -- if (!sdi.skip_init) { -- r = dss_calc_clock_div(1, t->pixel_clock * 1000, -- &dss_cinfo, &dispc_cinfo); -- } else { -- r = dss_get_clock_div(&dss_cinfo); -- r = dispc_get_clock_div(dssdev->manager->id, &dispc_cinfo); -- } -- -+ r = dss_calc_clock_div(1, t->pixel_clock * 1000, -+ &dss_cinfo, &dispc_cinfo); - if (r) - goto err2; - -@@ -116,21 +107,17 @@ - if (r) - goto err2; - -- if (!sdi.skip_init) { -- dss_sdi_init(dssdev->phy.sdi.datapairs); -- r = dss_sdi_enable(); -- if (r) -- goto err1; -- mdelay(2); -- } -+ dss_sdi_init(dssdev->phy.sdi.datapairs); -+ r = dss_sdi_enable(); -+ if (r) -+ goto err1; -+ mdelay(2); - - dssdev->manager->enable(dssdev->manager); - -- sdi.skip_init = 0; -- - return 0; - err2: -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - regulator_disable(sdi.vdds_sdi_reg); - err1: - omap_dss_stop_device(dssdev); -@@ -145,7 +132,7 @@ - - dss_sdi_disable(); - -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); - - regulator_disable(sdi.vdds_sdi_reg); - -@@ -157,25 +144,24 @@ - { - DSSDBG("SDI init\n"); - -+ if (sdi.vdds_sdi_reg == NULL) { -+ struct regulator *vdds_sdi; -+ -+ vdds_sdi = dss_get_vdds_sdi(); -+ -+ if (IS_ERR(vdds_sdi)) { -+ DSSERR("can't get VDDS_SDI regulator\n"); -+ return PTR_ERR(vdds_sdi); -+ } -+ -+ sdi.vdds_sdi_reg = vdds_sdi; -+ } -+ - return 0; - } - --int sdi_init(bool skip_init) -+int sdi_init(void) - { -- /* we store this for first display enable, then clear it */ -- sdi.skip_init = skip_init; -- -- sdi.vdds_sdi_reg = dss_get_vdds_sdi(); -- if (IS_ERR(sdi.vdds_sdi_reg)) { -- DSSERR("can't get VDDS_SDI regulator\n"); -- return PTR_ERR(sdi.vdds_sdi_reg); -- } -- /* -- * Enable clocks already here, otherwise there would be a toggle -- * of them until sdi_display_enable is called. -- */ -- if (skip_init) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); - return 0; - } - -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/dss/venc.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/venc.c ---- linux-2.6.38-rc7/drivers/video/omap2/dss/venc.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/dss/venc.c 2011-03-09 13:19:21.087278863 +0100 -@@ -39,8 +39,6 @@ - - #include "dss.h" - --#define VENC_BASE 0x48050C00 -- - /* Venc registers */ - #define VENC_REV_ID 0x00 - #define VENC_STATUS 0x04 -@@ -289,6 +287,7 @@ - EXPORT_SYMBOL(omap_dss_ntsc_timings); - - static struct { -+ struct platform_device *pdev; - void __iomem *base; - struct mutex venc_lock; - u32 wss_data; -@@ -381,11 +380,11 @@ - static void venc_enable_clocks(int enable) - { - if (enable) -- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | -- DSS_CLK_96M); -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | -+ DSS_CLK_VIDFCK); - else -- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M | -- DSS_CLK_96M); -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK | -+ DSS_CLK_VIDFCK); - } - - static const struct venc_config *venc_timings_to_config( -@@ -641,50 +640,23 @@ - }; - /* driver end */ - -- -- --int venc_init(struct platform_device *pdev) -+int venc_init_display(struct omap_dss_device *dssdev) - { -- u8 rev_id; -+ DSSDBG("init_display\n"); - -- mutex_init(&venc.venc_lock); -+ if (venc.vdda_dac_reg == NULL) { -+ struct regulator *vdda_dac; - -- venc.wss_data = 0; -+ vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac"); - -- venc.base = ioremap(VENC_BASE, SZ_1K); -- if (!venc.base) { -- DSSERR("can't ioremap VENC\n"); -- return -ENOMEM; -- } -+ if (IS_ERR(vdda_dac)) { -+ DSSERR("can't get VDDA_DAC regulator\n"); -+ return PTR_ERR(vdda_dac); -+ } - -- venc.vdda_dac_reg = dss_get_vdda_dac(); -- if (IS_ERR(venc.vdda_dac_reg)) { -- iounmap(venc.base); -- DSSERR("can't get VDDA_DAC regulator\n"); -- return PTR_ERR(venc.vdda_dac_reg); -+ venc.vdda_dac_reg = vdda_dac; - } - -- venc_enable_clocks(1); -- -- rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); -- printk(KERN_INFO "OMAP VENC rev %d\n", rev_id); -- -- venc_enable_clocks(0); -- -- return omap_dss_register_driver(&venc_driver); --} -- --void venc_exit(void) --{ -- omap_dss_unregister_driver(&venc_driver); -- -- iounmap(venc.base); --} -- --int venc_init_display(struct omap_dss_device *dssdev) --{ -- DSSDBG("init_display\n"); -- - return 0; - } - -@@ -740,3 +712,67 @@ - - #undef DUMPREG - } -+ -+/* VENC HW IP initialisation */ -+static int omap_venchw_probe(struct platform_device *pdev) -+{ -+ u8 rev_id; -+ struct resource *venc_mem; -+ -+ venc.pdev = pdev; -+ -+ mutex_init(&venc.venc_lock); -+ -+ venc.wss_data = 0; -+ -+ venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0); -+ if (!venc_mem) { -+ DSSERR("can't get IORESOURCE_MEM VENC\n"); -+ return -EINVAL; -+ } -+ venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); -+ if (!venc.base) { -+ DSSERR("can't ioremap VENC\n"); -+ return -ENOMEM; -+ } -+ -+ venc_enable_clocks(1); -+ -+ rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff); -+ dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id); -+ -+ venc_enable_clocks(0); -+ -+ return omap_dss_register_driver(&venc_driver); -+} -+ -+static int omap_venchw_remove(struct platform_device *pdev) -+{ -+ if (venc.vdda_dac_reg != NULL) { -+ regulator_put(venc.vdda_dac_reg); -+ venc.vdda_dac_reg = NULL; -+ } -+ omap_dss_unregister_driver(&venc_driver); -+ -+ iounmap(venc.base); -+ return 0; -+} -+ -+static struct platform_driver omap_venchw_driver = { -+ .probe = omap_venchw_probe, -+ .remove = omap_venchw_remove, -+ .driver = { -+ .name = "omapdss_venc", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int venc_init_platform_driver(void) -+{ -+ return platform_driver_register(&omap_venchw_driver); -+} -+ -+void venc_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omap_venchw_driver); -+} -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/omapfb/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/omapfb/Kconfig ---- linux-2.6.38-rc7/drivers/video/omap2/omapfb/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/omapfb/Kconfig 2011-03-09 13:19:21.087278863 +0100 -@@ -1,5 +1,5 @@ - menuconfig FB_OMAP2 -- tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)" -+ tristate "OMAP2+ frame buffer support (EXPERIMENTAL)" - depends on FB && OMAP2_DSS - - select OMAP2_VRAM -@@ -8,10 +8,10 @@ - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help -- Frame buffer driver for OMAP2/3 based boards. -+ Frame buffer driver for OMAP2+ based boards. - - config FB_OMAP2_DEBUG_SUPPORT -- bool "Debug support for OMAP2/3 FB" -+ bool "Debug support for OMAP2+ FB" - default y - depends on FB_OMAP2 - help -diff -Naur linux-2.6.38-rc7/drivers/video/omap2/omapfb/omapfb-main.c linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/omapfb/omapfb-main.c ---- linux-2.6.38-rc7/drivers/video/omap2/omapfb/omapfb-main.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/video/omap2/omapfb/omapfb-main.c 2011-03-09 13:19:21.088278842 +0100 -@@ -2090,7 +2090,7 @@ - { - int r; - u8 bpp; -- struct omap_video_timings timings; -+ struct omap_video_timings timings, temp_timings; - - r = omapfb_mode_to_timings(mode_str, &timings, &bpp); - if (r) -@@ -2100,14 +2100,23 @@ - fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp; - ++fbdev->num_bpp_overrides; - -- if (!display->driver->check_timings || !display->driver->set_timings) -- return -EINVAL; -- -- r = display->driver->check_timings(display, &timings); -- if (r) -- return r; -+ if (display->driver->check_timings) { -+ r = display->driver->check_timings(display, &timings); -+ if (r) -+ return r; -+ } else { -+ /* If check_timings is not present compare xres and yres */ -+ if (display->driver->get_timings) { -+ display->driver->get_timings(display, &temp_timings); -+ -+ if (temp_timings.x_res != timings.x_res || -+ temp_timings.y_res != timings.y_res) -+ return -EINVAL; -+ } -+ } - -- display->driver->set_timings(display, &timings); -+ if (display->driver->set_timings) -+ display->driver->set_timings(display, &timings); - - return 0; - } -diff -Naur linux-2.6.38-rc7/drivers/w1/masters/Kconfig linux-2.6.38-rc7-linux-omap-dss2/drivers/w1/masters/Kconfig ---- linux-2.6.38-rc7/drivers/w1/masters/Kconfig 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/drivers/w1/masters/Kconfig 2011-03-09 13:19:21.142277747 +0100 -@@ -60,7 +60,7 @@ - - config HDQ_MASTER_OMAP - tristate "OMAP HDQ driver" -- depends on ARCH_OMAP2430 || ARCH_OMAP3 -+ depends on SOC_OMAP2430 || ARCH_OMAP3 - help - Say Y here if you want support for the 1-wire or HDQ Interface - on an OMAP processor. -diff -Naur linux-2.6.38-rc7/include/linux/hwspinlock.h linux-2.6.38-rc7-linux-omap-dss2/include/linux/hwspinlock.h ---- linux-2.6.38-rc7/include/linux/hwspinlock.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/include/linux/hwspinlock.h 2011-03-09 13:19:21.851263363 +0100 -@@ -0,0 +1,292 @@ -+/* -+ * Hardware spinlock public header -+ * -+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com -+ * -+ * Contact: Ohad Ben-Cohen -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __LINUX_HWSPINLOCK_H -+#define __LINUX_HWSPINLOCK_H -+ -+#include -+#include -+ -+/* hwspinlock mode argument */ -+#define HWLOCK_IRQSTATE 0x01 /* Disable interrupts, save state */ -+#define HWLOCK_IRQ 0x02 /* Disable interrupts, don't save state */ -+ -+struct hwspinlock; -+ -+#if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE) -+ -+int hwspin_lock_register(struct hwspinlock *lock); -+struct hwspinlock *hwspin_lock_unregister(unsigned int id); -+struct hwspinlock *hwspin_lock_request(void); -+struct hwspinlock *hwspin_lock_request_specific(unsigned int id); -+int hwspin_lock_free(struct hwspinlock *hwlock); -+int hwspin_lock_get_id(struct hwspinlock *hwlock); -+int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int, -+ unsigned long *); -+int __hwspin_trylock(struct hwspinlock *, int, unsigned long *); -+void __hwspin_unlock(struct hwspinlock *, int, unsigned long *); -+ -+#else /* !CONFIG_HWSPINLOCK */ -+ -+/* -+ * We don't want these functions to fail if CONFIG_HWSPINLOCK is not -+ * enabled. We prefer to silently succeed in this case, and let the -+ * code path get compiled away. This way, if CONFIG_HWSPINLOCK is not -+ * required on a given setup, users will still work. -+ * -+ * The only exception is hwspin_lock_register/hwspin_lock_unregister, with which -+ * we _do_ want users to fail (no point in registering hwspinlock instances if -+ * the framework is not available). -+ * -+ * Note: ERR_PTR(-ENODEV) will still be considered a success for NULL-checking -+ * users. Others, which care, can still check this with IS_ERR. -+ */ -+static inline struct hwspinlock *hwspin_lock_request(void) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ -+static inline struct hwspinlock *hwspin_lock_request_specific(unsigned int id) -+{ -+ return ERR_PTR(-ENODEV); -+} -+ -+static inline int hwspin_lock_free(struct hwspinlock *hwlock) -+{ -+ return 0; -+} -+ -+static inline -+int __hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to, -+ int mode, unsigned long *flags) -+{ -+ return 0; -+} -+ -+static inline -+int __hwspin_trylock(struct hwspinlock *hwlock, int mode, unsigned long *flags) -+{ -+ return 0; -+} -+ -+static inline -+void __hwspin_unlock(struct hwspinlock *hwlock, int mode, unsigned long *flags) -+{ -+ return 0; -+} -+ -+static inline int hwspin_lock_get_id(struct hwspinlock *hwlock) -+{ -+ return 0; -+} -+ -+static inline int hwspin_lock_register(struct hwspinlock *hwlock) -+{ -+ return -ENODEV; -+} -+ -+static inline struct hwspinlock *hwspin_lock_unregister(unsigned int id) -+{ -+ return NULL; -+} -+ -+#endif /* !CONFIG_HWSPINLOCK */ -+ -+/** -+ * hwspin_trylock_irqsave() - try to lock an hwspinlock, disable interrupts -+ * @hwlock: an hwspinlock which we want to trylock -+ * @flags: a pointer to where the caller's interrupt state will be saved at -+ * -+ * This function attempts to lock the underlying hwspinlock, and will -+ * immediately fail if the hwspinlock is already locked. -+ * -+ * Upon a successful return from this function, preemption and local -+ * interrupts are disabled (previous interrupts state is saved at @flags), -+ * so the caller must not sleep, and is advised to release the hwspinlock -+ * as soon as possible. -+ * -+ * Returns 0 if we successfully locked the hwspinlock, -EBUSY if -+ * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid. -+ */ -+static inline -+int hwspin_trylock_irqsave(struct hwspinlock *hwlock, unsigned long *flags) -+{ -+ return __hwspin_trylock(hwlock, HWLOCK_IRQSTATE, flags); -+} -+ -+/** -+ * hwspin_trylock_irq() - try to lock an hwspinlock, disable interrupts -+ * @hwlock: an hwspinlock which we want to trylock -+ * -+ * This function attempts to lock the underlying hwspinlock, and will -+ * immediately fail if the hwspinlock is already locked. -+ * -+ * Upon a successful return from this function, preemption and local -+ * interrupts are disabled, so the caller must not sleep, and is advised -+ * to release the hwspinlock as soon as possible. -+ * -+ * Returns 0 if we successfully locked the hwspinlock, -EBUSY if -+ * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid. -+ */ -+static inline int hwspin_trylock_irq(struct hwspinlock *hwlock) -+{ -+ return __hwspin_trylock(hwlock, HWLOCK_IRQ, NULL); -+} -+ -+/** -+ * hwspin_trylock() - attempt to lock a specific hwspinlock -+ * @hwlock: an hwspinlock which we want to trylock -+ * -+ * This function attempts to lock an hwspinlock, and will immediately fail -+ * if the hwspinlock is already taken. -+ * -+ * Upon a successful return from this function, preemption is disabled, -+ * so the caller must not sleep, and is advised to release the hwspinlock -+ * as soon as possible. This is required in order to minimize remote cores -+ * polling on the hardware interconnect. -+ * -+ * Returns 0 if we successfully locked the hwspinlock, -EBUSY if -+ * the hwspinlock was already taken, and -EINVAL if @hwlock is invalid. -+ */ -+static inline int hwspin_trylock(struct hwspinlock *hwlock) -+{ -+ return __hwspin_trylock(hwlock, 0, NULL); -+} -+ -+/** -+ * hwspin_lock_timeout_irqsave() - lock hwspinlock, with timeout, disable irqs -+ * @hwlock: the hwspinlock to be locked -+ * @to: timeout value in msecs -+ * @flags: a pointer to where the caller's interrupt state will be saved at -+ * -+ * This function locks the underlying @hwlock. If the @hwlock -+ * is already taken, the function will busy loop waiting for it to -+ * be released, but give up when @timeout msecs have elapsed. -+ * -+ * Upon a successful return from this function, preemption and local interrupts -+ * are disabled (plus previous interrupt state is saved), so the caller must -+ * not sleep, and is advised to release the hwspinlock as soon as possible. -+ * -+ * Returns 0 when the @hwlock was successfully taken, and an appropriate -+ * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still -+ * busy after @timeout msecs). The function will never sleep. -+ */ -+static inline int hwspin_lock_timeout_irqsave(struct hwspinlock *hwlock, -+ unsigned int to, unsigned long *flags) -+{ -+ return __hwspin_lock_timeout(hwlock, to, HWLOCK_IRQSTATE, flags); -+} -+ -+/** -+ * hwspin_lock_timeout_irq() - lock hwspinlock, with timeout, disable irqs -+ * @hwlock: the hwspinlock to be locked -+ * @to: timeout value in msecs -+ * -+ * This function locks the underlying @hwlock. If the @hwlock -+ * is already taken, the function will busy loop waiting for it to -+ * be released, but give up when @timeout msecs have elapsed. -+ * -+ * Upon a successful return from this function, preemption and local interrupts -+ * are disabled so the caller must not sleep, and is advised to release the -+ * hwspinlock as soon as possible. -+ * -+ * Returns 0 when the @hwlock was successfully taken, and an appropriate -+ * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still -+ * busy after @timeout msecs). The function will never sleep. -+ */ -+static inline -+int hwspin_lock_timeout_irq(struct hwspinlock *hwlock, unsigned int to) -+{ -+ return __hwspin_lock_timeout(hwlock, to, HWLOCK_IRQ, NULL); -+} -+ -+/** -+ * hwspin_lock_timeout() - lock an hwspinlock with timeout limit -+ * @hwlock: the hwspinlock to be locked -+ * @to: timeout value in msecs -+ * -+ * This function locks the underlying @hwlock. If the @hwlock -+ * is already taken, the function will busy loop waiting for it to -+ * be released, but give up when @timeout msecs have elapsed. -+ * -+ * Upon a successful return from this function, preemption is disabled -+ * so the caller must not sleep, and is advised to release the hwspinlock -+ * as soon as possible. -+ * This is required in order to minimize remote cores polling on the -+ * hardware interconnect. -+ * -+ * Returns 0 when the @hwlock was successfully taken, and an appropriate -+ * error code otherwise (most notably an -ETIMEDOUT if the @hwlock is still -+ * busy after @timeout msecs). The function will never sleep. -+ */ -+static inline -+int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int to) -+{ -+ return __hwspin_lock_timeout(hwlock, to, 0, NULL); -+} -+ -+/** -+ * hwspin_unlock_irqrestore() - unlock hwspinlock, restore irq state -+ * @hwlock: a previously-acquired hwspinlock which we want to unlock -+ * @flags: previous caller's interrupt state to restore -+ * -+ * This function will unlock a specific hwspinlock, enable preemption and -+ * restore the previous state of the local interrupts. It should be used -+ * to undo, e.g., hwspin_trylock_irqsave(). -+ * -+ * @hwlock must be already locked before calling this function: it is a bug -+ * to call unlock on a @hwlock that is already unlocked. -+ */ -+static inline void hwspin_unlock_irqrestore(struct hwspinlock *hwlock, -+ unsigned long *flags) -+{ -+ __hwspin_unlock(hwlock, HWLOCK_IRQSTATE, flags); -+} -+ -+/** -+ * hwspin_unlock_irq() - unlock hwspinlock, enable interrupts -+ * @hwlock: a previously-acquired hwspinlock which we want to unlock -+ * -+ * This function will unlock a specific hwspinlock, enable preemption and -+ * enable local interrupts. Should be used to undo hwspin_lock_irq(). -+ * -+ * @hwlock must be already locked (e.g. by hwspin_trylock_irq()) before -+ * calling this function: it is a bug to call unlock on a @hwlock that is -+ * already unlocked. -+ */ -+static inline void hwspin_unlock_irq(struct hwspinlock *hwlock) -+{ -+ __hwspin_unlock(hwlock, HWLOCK_IRQ, NULL); -+} -+ -+/** -+ * hwspin_unlock() - unlock hwspinlock -+ * @hwlock: a previously-acquired hwspinlock which we want to unlock -+ * -+ * This function will unlock a specific hwspinlock and enable preemption -+ * back. -+ * -+ * @hwlock must be already locked (e.g. by hwspin_trylock()) before calling -+ * this function: it is a bug to call unlock on a @hwlock that is already -+ * unlocked. -+ */ -+static inline void hwspin_unlock(struct hwspinlock *hwlock) -+{ -+ __hwspin_unlock(hwlock, 0, NULL); -+} -+ -+#endif /* __LINUX_HWSPINLOCK_H */ -diff -Naur linux-2.6.38-rc7/include/linux/i2c/twl.h linux-2.6.38-rc7-linux-omap-dss2/include/linux/i2c/twl.h ---- linux-2.6.38-rc7/include/linux/i2c/twl.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/include/linux/i2c/twl.h 2011-03-09 13:19:21.857263241 +0100 -@@ -637,7 +637,6 @@ - extern int twl4030_remove_script(u8 flags); - - struct twl4030_codec_audio_data { -- unsigned int audio_mclk; /* not used, will be removed */ - unsigned int digimic_delay; /* in ms */ - unsigned int ramp_delay_value; - unsigned int offset_cncl_path; -@@ -648,7 +647,6 @@ - }; - - struct twl4030_codec_vibra_data { -- unsigned int audio_mclk; - unsigned int coexist; - }; - -diff -Naur linux-2.6.38-rc7/include/linux/mtd/onenand_regs.h linux-2.6.38-rc7-linux-omap-dss2/include/linux/mtd/onenand_regs.h ---- linux-2.6.38-rc7/include/linux/mtd/onenand_regs.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/include/linux/mtd/onenand_regs.h 2011-03-09 13:19:21.975260847 +0100 -@@ -168,6 +168,7 @@ - #define ONENAND_SYS_CFG1_INT (1 << 6) - #define ONENAND_SYS_CFG1_IOBE (1 << 5) - #define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) -+#define ONENAND_SYS_CFG1_VHF (1 << 3) - #define ONENAND_SYS_CFG1_HF (1 << 2) - #define ONENAND_SYS_CFG1_SYNC_WRITE (1 << 1) - -diff -Naur linux-2.6.38-rc7/MAINTAINERS linux-2.6.38-rc7-linux-omap-dss2/MAINTAINERS ---- linux-2.6.38-rc7/MAINTAINERS 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/MAINTAINERS 2011-03-09 13:19:09.391516121 +0100 -@@ -4504,14 +4504,14 @@ - F: sound/soc/omap/ - - OMAP FRAMEBUFFER SUPPORT --M: Tomi Valkeinen -+M: Tomi Valkeinen - L: linux-fbdev@vger.kernel.org - L: linux-omap@vger.kernel.org - S: Maintained - F: drivers/video/omap/ - - OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2) --M: Tomi Valkeinen -+M: Tomi Valkeinen - L: linux-omap@vger.kernel.org - L: linux-fbdev@vger.kernel.org - S: Maintained -diff -Naur linux-2.6.38-rc7/sound/soc/omap/omap-mcbsp.c linux-2.6.38-rc7-linux-omap-dss2/sound/soc/omap/omap-mcbsp.c ---- linux-2.6.38-rc7/sound/soc/omap/omap-mcbsp.c 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/sound/soc/omap/omap-mcbsp.c 2011-03-09 13:19:23.525229402 +0100 -@@ -69,110 +69,6 @@ - */ - static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2]; - --#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) --static const int omap1_dma_reqs[][2] = { -- { OMAP_DMA_MCBSP1_TX, OMAP_DMA_MCBSP1_RX }, -- { OMAP_DMA_MCBSP2_TX, OMAP_DMA_MCBSP2_RX }, -- { OMAP_DMA_MCBSP3_TX, OMAP_DMA_MCBSP3_RX }, --}; --static const unsigned long omap1_mcbsp_port[][2] = { -- { OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, -- OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, -- { OMAP1510_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1, -- OMAP1510_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, -- { OMAP1510_MCBSP3_BASE + OMAP_MCBSP_REG_DXR1, -- OMAP1510_MCBSP3_BASE + OMAP_MCBSP_REG_DRR1 }, --}; --#else --static const int omap1_dma_reqs[][2] = {}; --static const unsigned long omap1_mcbsp_port[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) --static const int omap24xx_dma_reqs[][2] = { -- { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, -- { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) -- { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX }, -- { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX }, -- { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX }, --#endif --}; --#else --static const int omap24xx_dma_reqs[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP4) --static const int omap44xx_dma_reqs[][2] = { -- { OMAP44XX_DMA_MCBSP1_TX, OMAP44XX_DMA_MCBSP1_RX }, -- { OMAP44XX_DMA_MCBSP2_TX, OMAP44XX_DMA_MCBSP2_RX }, -- { OMAP44XX_DMA_MCBSP3_TX, OMAP44XX_DMA_MCBSP3_RX }, -- { OMAP44XX_DMA_MCBSP4_TX, OMAP44XX_DMA_MCBSP4_RX }, --}; --#else --static const int omap44xx_dma_reqs[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP2420) --static const unsigned long omap2420_mcbsp_port[][2] = { -- { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, -- OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, -- { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1, -- OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, --}; --#else --static const unsigned long omap2420_mcbsp_port[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP2430) --static const unsigned long omap2430_mcbsp_port[][2] = { -- { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, -- OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, -- OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, -- OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, -- OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, -- OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, --}; --#else --static const unsigned long omap2430_mcbsp_port[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP3) --static const unsigned long omap34xx_mcbsp_port[][2] = { -- { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, -- OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, -- OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, -- OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, -- OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR, -- OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR }, --}; --#else --static const unsigned long omap34xx_mcbsp_port[][2] = {}; --#endif -- --#if defined(CONFIG_ARCH_OMAP4) --static const unsigned long omap44xx_mcbsp_port[][2] = { -- { OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, -- OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, -- OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, -- OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, -- { OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, -- OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, --}; --#else --static const unsigned long omap44xx_mcbsp_port[][2] = {}; --#endif -- - static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) - { - struct snd_soc_pcm_runtime *rtd = substream->private_data; -@@ -346,24 +242,10 @@ - unsigned int format, div, framesize, master; - - dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream]; -- if (cpu_class_is_omap1()) { -- dma = omap1_dma_reqs[bus_id][substream->stream]; -- port = omap1_mcbsp_port[bus_id][substream->stream]; -- } else if (cpu_is_omap2420()) { -- dma = omap24xx_dma_reqs[bus_id][substream->stream]; -- port = omap2420_mcbsp_port[bus_id][substream->stream]; -- } else if (cpu_is_omap2430()) { -- dma = omap24xx_dma_reqs[bus_id][substream->stream]; -- port = omap2430_mcbsp_port[bus_id][substream->stream]; -- } else if (cpu_is_omap343x()) { -- dma = omap24xx_dma_reqs[bus_id][substream->stream]; -- port = omap34xx_mcbsp_port[bus_id][substream->stream]; -- } else if (cpu_is_omap44xx()) { -- dma = omap44xx_dma_reqs[bus_id][substream->stream]; -- port = omap44xx_mcbsp_port[bus_id][substream->stream]; -- } else { -- return -ENODEV; -- } -+ -+ dma = omap_mcbsp_dma_ch_params(bus_id, substream->stream); -+ port = omap_mcbsp_dma_reg_params(bus_id, substream->stream); -+ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - dma_data->data_type = OMAP_DMA_DATA_TYPE_S16; -diff -Naur linux-2.6.38-rc7/sound/soc/omap/omap-mcbsp.h linux-2.6.38-rc7-linux-omap-dss2/sound/soc/omap/omap-mcbsp.h ---- linux-2.6.38-rc7/sound/soc/omap/omap-mcbsp.h 2011-03-01 22:55:12.000000000 +0100 -+++ linux-2.6.38-rc7-linux-omap-dss2/sound/soc/omap/omap-mcbsp.h 2011-03-09 13:19:23.525229402 +0100 -@@ -43,7 +43,7 @@ - OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ - }; - --#if defined(CONFIG_ARCH_OMAP2420) -+#if defined(CONFIG_SOC_OMAP2420) - #define NUM_LINKS 2 - #endif - #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) -@@ -54,7 +54,7 @@ - #undef NUM_LINKS - #define NUM_LINKS 4 - #endif --#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) -+#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430) - #undef NUM_LINKS - #define NUM_LINKS 5 - #endif diff --git a/packages/linux/patches/linux-2.6.38-rc8-301-V5_Add_display_type_HDMI_to_DSS2.patch b/packages/linux/patches/linux-2.6.38-rc8-301-V5_Add_display_type_HDMI_to_DSS2.patch deleted file mode 100644 index 4a2b1280e4..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-301-V5_Add_display_type_HDMI_to_DSS2.patch +++ /dev/null @@ -1,123 +0,0 @@ -Adding HDMI type in dss_features , overlay and -the manager so that HDMI type of display will be recognized. - -Signed-off-by: Mythri P K ---- - arch/arm/plat-omap/include/plat/display.h | 1 + - drivers/video/omap2/dss/display.c | 2 ++ - drivers/video/omap2/dss/dss_features.c | 2 +- - drivers/video/omap2/dss/manager.c | 9 +++++++-- - drivers/video/omap2/dss/overlay.c | 6 ++++-- - 5 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h -index e81ca66..5e04ddc 100644 ---- a/arch/arm/plat-omap/include/plat/display.h -+++ b/arch/arm/plat-omap/include/plat/display.h -@@ -58,6 +58,7 @@ enum omap_display_type { - OMAP_DISPLAY_TYPE_SDI = 1 << 2, - OMAP_DISPLAY_TYPE_DSI = 1 << 3, - OMAP_DISPLAY_TYPE_VENC = 1 << 4, -+ OMAP_DISPLAY_TYPE_HDMI = 1 << 5, - }; - - enum omap_plane { -diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c -index 7d96b72..c40bcbd 100644 ---- a/drivers/video/omap2/dss/display.c -+++ b/drivers/video/omap2/dss/display.c -@@ -342,6 +342,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) - return 16; - case OMAP_DISPLAY_TYPE_VENC: - case OMAP_DISPLAY_TYPE_SDI: -+ case OMAP_DISPLAY_TYPE_HDMI: - return 24; - default: - BUG(); -@@ -368,6 +369,7 @@ bool dss_use_replication(struct omap_dss_device *dssdev, - case OMAP_DISPLAY_TYPE_DPI: - bpp = dssdev->phy.dpi.data_lines; - break; -+ case OMAP_DISPLAY_TYPE_HDMI: - case OMAP_DISPLAY_TYPE_VENC: - case OMAP_DISPLAY_TYPE_SDI: - bpp = 24; -diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c -index 6eb6ec6..86dc848 100644 ---- a/drivers/video/omap2/dss/dss_features.c -+++ b/drivers/video/omap2/dss/dss_features.c -@@ -115,7 +115,7 @@ static const enum omap_display_type omap4_dss_supported_displays[] = { - OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, - - /* OMAP_DSS_CHANNEL_DIGIT */ -- OMAP_DISPLAY_TYPE_VENC, -+ OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI, - - /* OMAP_DSS_CHANNEL_LCD2 */ - OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI | -diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c -index 1f53bf2..bcd37ec 100644 ---- a/drivers/video/omap2/dss/manager.c -+++ b/drivers/video/omap2/dss/manager.c -@@ -515,6 +515,8 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) - - if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) { - irq = DISPC_IRQ_EVSYNC_ODD; -+ } else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) { -+ irq = DISPC_IRQ_EVSYNC_EVEN; - } else { - if (mgr->id == OMAP_DSS_CHANNEL_LCD) - irq = DISPC_IRQ_VSYNC; -@@ -536,7 +538,8 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) - if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return 0; - -- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { -+ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC -+ || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { - irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; - } else { - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { -@@ -613,7 +616,8 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) - if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) - return 0; - -- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { -+ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC -+ || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { - irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN; - } else { - if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { -@@ -1377,6 +1381,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr) - case OMAP_DISPLAY_TYPE_DBI: - case OMAP_DISPLAY_TYPE_SDI: - case OMAP_DISPLAY_TYPE_VENC: -+ case OMAP_DISPLAY_TYPE_HDMI: - default_get_overlay_fifo_thresholds(ovl->id, size, - &oc->burst_size, &oc->fifo_low, - &oc->fifo_high); -diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c -index 996e9a4..f1aca6d 100644 ---- a/drivers/video/omap2/dss/overlay.c -+++ b/drivers/video/omap2/dss/overlay.c -@@ -679,7 +679,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) - lcd2_mgr->set_device(lcd2_mgr, dssdev); - mgr = lcd2_mgr; - } -- } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC) { -+ } else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC -+ && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) { - if (!lcd_mgr->device || force) { - if (lcd_mgr->device) - lcd_mgr->unset_device(lcd_mgr); -@@ -688,7 +689,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force) - } - } - -- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) { -+ if (dssdev->type == OMAP_DISPLAY_TYPE_VENC -+ || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) { - if (!tv_mgr->device || force) { - if (tv_mgr->device) - tv_mgr->unset_device(tv_mgr); --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-302-V5_Select_between_HDMI_VENC_clock_source.patch b/packages/linux/patches/linux-2.6.38-rc8-302-V5_Select_between_HDMI_VENC_clock_source.patch deleted file mode 100644 index 663f5fe18e..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-302-V5_Select_between_HDMI_VENC_clock_source.patch +++ /dev/null @@ -1,47 +0,0 @@ -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/dss.c | 5 +++++ - drivers/video/omap2/dss/dss.h | 6 ++++++ - 2 files changed, 11 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c -index aed9345..0be83c8 100644 ---- a/drivers/video/omap2/dss/dss.c -+++ b/drivers/video/omap2/dss/dss.c -@@ -605,6 +605,11 @@ void dss_set_dac_pwrdn_bgz(bool enable) - REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */ - } - -+void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi) -+{ -+ REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15); /* VENC_HDMI_SWITCH */ -+} -+ - static int dss_init(void) - { - int r; -diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h -index b845468..c2c0fcf 100644 ---- a/drivers/video/omap2/dss/dss.h -+++ b/drivers/video/omap2/dss/dss.h -@@ -132,6 +132,11 @@ struct dss_clk_source_name { - const char *clksrc_name; - }; - -+enum dss_hdmi_venc_clk_source_select { -+ DSS_VENC_TV_CLK = 0, -+ DSS_HDMI_M_PCLK = 1, -+}; -+ - struct dss_clock_info { - /* rates that we get with dividers below */ - unsigned long fck; -@@ -220,6 +225,7 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force); - int dss_init_platform_driver(void); - void dss_uninit_platform_driver(void); - -+void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); - void dss_save_context(void); - void dss_restore_context(void); - void dss_clk_enable(enum dss_clock clks); --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-303-V5_Dispc_gamma_enable_set-reset_function_for_TV.patch b/packages/linux/patches/linux-2.6.38-rc8-303-V5_Dispc_gamma_enable_set-reset_function_for_TV.patch deleted file mode 100644 index 60a995f9e1..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-303-V5_Dispc_gamma_enable_set-reset_function_for_TV.patch +++ /dev/null @@ -1,46 +0,0 @@ -Adding function to reset/set gamma table bit for TV interface -currentl only support for disabled is added. - -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/dispc.c | 13 +++++++++++++ - drivers/video/omap2/dss/dss.h | 1 + - 2 files changed, 14 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c -index b8c576a..9b86f5f 100644 ---- a/drivers/video/omap2/dss/dispc.c -+++ b/drivers/video/omap2/dss/dispc.c -@@ -1008,6 +1008,19 @@ void dispc_set_burst_size(enum omap_plane plane, - enable_clocks(0); - } - -+void dispc_enable_gamma_table(bool enable) -+{ -+ /* This is partially implemented to support only -+ * disabling of the gamma table. -+ */ -+ if (enable) { -+ DSSWARN("Gamma table enabling for TV not yet supported"); -+ return; -+ } -+ -+ REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9); -+} -+ - static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable) - { - u32 val; -diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h -index c2c0fcf..9f563a6 100644 ---- a/drivers/video/omap2/dss/dss.h -+++ b/drivers/video/omap2/dss/dss.h -@@ -376,6 +376,7 @@ void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height); - void dispc_set_channel_out(enum omap_plane plane, - enum omap_channel channel_out); - -+void dispc_enable_gamma_table(bool enable); - int dispc_setup_plane(enum omap_plane plane, - u32 paddr, u16 screen_width, - u16 pos_x, u16 pos_y, --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-304-V5_HDMI_driver_header_file_addition.patch b/packages/linux/patches/linux-2.6.38-rc8-304-V5_HDMI_driver_header_file_addition.patch deleted file mode 100644 index 4cde7027ea..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-304-V5_HDMI_driver_header_file_addition.patch +++ /dev/null @@ -1,431 +0,0 @@ -Adding the hdmi interface driver header file (hdmi.h) to the dss driver. -Register and structure declaration done here. - -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/hdmi.h | 415 ++++++++++++++++++++++++++++++++++++++++ - 1 files changed, 415 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/omap2/dss/hdmi.h - -diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/omap2/dss/hdmi.h -new file mode 100644 -index 0000000..9887ab9 ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi.h -@@ -0,0 +1,415 @@ -+/* -+ * hdmi.h -+ * -+ * HDMI driver definition for TI OMAP4 processors. -+ * -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.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. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#ifndef _OMAP4_DSS_HDMI_H_ -+#define _OMAP4_DSS_HDMI_H_ -+ -+#include -+#include -+ -+#define HDMI_WP 0x0 -+#define HDMI_CORE_SYS 0x400 -+#define HDMI_CORE_AV 0x900 -+#define HDMI_PLLCTRL 0x200 -+#define HDMI_PHY 0x300 -+ -+struct hdmi_reg { u16 idx; }; -+ -+#define HDMI_REG(idx) ((const struct hdmi_reg) { idx }) -+ -+/* HDMI Wrapper */ -+#define HDMI_WP_REG(idx) HDMI_REG(HDMI_WP + idx) -+ -+#define HDMI_WP_REVISION HDMI_WP_REG(0x0) -+#define HDMI_WP_SYSCONFIG HDMI_WP_REG(0x10) -+#define HDMI_WP_IRQSTATUS_RAW HDMI_WP_REG(0x24) -+#define HDMI_WP_IRQSTATUS HDMI_WP_REG(0x28) -+#define HDMI_WP_PWR_CTRL HDMI_WP_REG(0x40) -+#define HDMI_WP_IRQENABLE_SET HDMI_WP_REG(0x2C) -+#define HDMI_WP_VIDEO_CFG HDMI_WP_REG(0x50) -+#define HDMI_WP_VIDEO_SIZE HDMI_WP_REG(0x60) -+#define HDMI_WP_VIDEO_TIMING_H HDMI_WP_REG(0x68) -+#define HDMI_WP_VIDEO_TIMING_V HDMI_WP_REG(0x6C) -+#define HDMI_WP_WP_CLK HDMI_WP_REG(0x70) -+ -+/* HDMI IP Core System */ -+#define HDMI_CORE_SYS_REG(idx) HDMI_REG(HDMI_CORE_SYS + idx) -+ -+#define HDMI_CORE_SYS_VND_IDL HDMI_CORE_SYS_REG(0x0) -+#define HDMI_CORE_SYS_DEV_IDL HDMI_CORE_SYS_REG(0x8) -+#define HDMI_CORE_SYS_DEV_IDH HDMI_CORE_SYS_REG(0xC) -+#define HDMI_CORE_SYS_DEV_REV HDMI_CORE_SYS_REG(0x10) -+#define HDMI_CORE_SYS_SRST HDMI_CORE_SYS_REG(0x14) -+#define HDMI_CORE_CTRL1 HDMI_CORE_SYS_REG(0x20) -+#define HDMI_CORE_SYS_SYS_STAT HDMI_CORE_SYS_REG(0x24) -+#define HDMI_CORE_SYS_VID_ACEN HDMI_CORE_SYS_REG(0x124) -+#define HDMI_CORE_SYS_VID_MODE HDMI_CORE_SYS_REG(0x128) -+#define HDMI_CORE_SYS_INTR_STATE HDMI_CORE_SYS_REG(0x1C0) -+#define HDMI_CORE_SYS_INTR1 HDMI_CORE_SYS_REG(0x1C4) -+#define HDMI_CORE_SYS_INTR2 HDMI_CORE_SYS_REG(0x1C8) -+#define HDMI_CORE_SYS_INTR3 HDMI_CORE_SYS_REG(0x1CC) -+#define HDMI_CORE_SYS_INTR4 HDMI_CORE_SYS_REG(0x1D0) -+#define HDMI_CORE_SYS_UMASK1 HDMI_CORE_SYS_REG(0x1D4) -+#define HDMI_CORE_SYS_TMDS_CTRL HDMI_CORE_SYS_REG(0x208) -+#define HDMI_CORE_SYS_DE_DLY HDMI_CORE_SYS_REG(0xC8) -+#define HDMI_CORE_SYS_DE_CTRL HDMI_CORE_SYS_REG(0xCC) -+#define HDMI_CORE_SYS_DE_TOP HDMI_CORE_SYS_REG(0xD0) -+#define HDMI_CORE_SYS_DE_CNTL HDMI_CORE_SYS_REG(0xD8) -+#define HDMI_CORE_SYS_DE_CNTH HDMI_CORE_SYS_REG(0xDC) -+#define HDMI_CORE_SYS_DE_LINL HDMI_CORE_SYS_REG(0xE0) -+#define HDMI_CORE_SYS_DE_LINH_1 HDMI_CORE_SYS_REG(0xE4) -+#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC 0x1 -+#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC 0x1 -+#define HDMI_CORE_CTRL1_BSEL_24BITBUS 0x1 -+#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE 0x1 -+ -+/* HDMI DDC E-DID */ -+#define HDMI_CORE_DDC_CMD HDMI_CORE_SYS_REG(0x3CC) -+#define HDMI_CORE_DDC_STATUS HDMI_CORE_SYS_REG(0x3C8) -+#define HDMI_CORE_DDC_ADDR HDMI_CORE_SYS_REG(0x3B4) -+#define HDMI_CORE_DDC_OFFSET HDMI_CORE_SYS_REG(0x3BC) -+#define HDMI_CORE_DDC_COUNT1 HDMI_CORE_SYS_REG(0x3C0) -+#define HDMI_CORE_DDC_COUNT2 HDMI_CORE_SYS_REG(0x3C4) -+#define HDMI_CORE_DDC_DATA HDMI_CORE_SYS_REG(0x3D0) -+#define HDMI_CORE_DDC_SEGM HDMI_CORE_SYS_REG(0x3B8) -+ -+/* HDMI IP Core Audio Video */ -+#define HDMI_CORE_AV_REG(idx) HDMI_REG(HDMI_CORE_AV + idx) -+ -+#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC) -+#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4) -+#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8) -+#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC) -+#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100) -+#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104) -+#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108) -+#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C) -+#define HDMI_CORE_AV_AVI_DBYTE(n) HDMI_CORE_AV_REG(n * 4 + 0x110) -+#define HDMI_CORE_AV_AVI_DBYTE_NELEMS HDMI_CORE_AV_REG(15) -+#define HDMI_CORE_AV_SPD_DBYTE HDMI_CORE_AV_REG(0x190) -+#define HDMI_CORE_AV_SPD_DBYTE_NELEMS HDMI_CORE_AV_REG(27) -+#define HDMI_CORE_AV_MPEG_DBYTE HDMI_CORE_AV_REG(0x290) -+#define HDMI_CORE_AV_MPEG_DBYTE_NELEMS HDMI_CORE_AV_REG(27) -+#define HDMI_CORE_AV_GEN_DBYTE HDMI_CORE_AV_REG(0x300) -+#define HDMI_CORE_AV_GEN_DBYTE_NELEMS HDMI_CORE_AV_REG(31) -+#define HDMI_CORE_AV_GEN2_DBYTE HDMI_CORE_AV_REG(0x380) -+#define HDMI_CORE_AV_GEN2_DBYTE_NELEMS HDMI_CORE_AV_REG(31) -+#define HDMI_CORE_AV_ACR_CTRL HDMI_CORE_AV_REG(0x4) -+#define HDMI_CORE_AV_FREQ_SVAL HDMI_CORE_AV_REG(0x8) -+#define HDMI_CORE_AV_N_SVAL1 HDMI_CORE_AV_REG(0xC) -+#define HDMI_CORE_AV_N_SVAL2 HDMI_CORE_AV_REG(0x10) -+#define HDMI_CORE_AV_N_SVAL3 HDMI_CORE_AV_REG(0x14) -+#define HDMI_CORE_AV_CTS_SVAL1 HDMI_CORE_AV_REG(0x18) -+#define HDMI_CORE_AV_CTS_SVAL2 HDMI_CORE_AV_REG(0x1C) -+#define HDMI_CORE_AV_CTS_SVAL3 HDMI_CORE_AV_REG(0x20) -+#define HDMI_CORE_AV_CTS_HVAL1 HDMI_CORE_AV_REG(0x24) -+#define HDMI_CORE_AV_CTS_HVAL2 HDMI_CORE_AV_REG(0x28) -+#define HDMI_CORE_AV_CTS_HVAL3 HDMI_CORE_AV_REG(0x2C) -+#define HDMI_CORE_AV_AUD_MODE HDMI_CORE_AV_REG(0x50) -+#define HDMI_CORE_AV_SPDIF_CTRL HDMI_CORE_AV_REG(0x54) -+#define HDMI_CORE_AV_HW_SPDIF_FS HDMI_CORE_AV_REG(0x60) -+#define HDMI_CORE_AV_SWAP_I2S HDMI_CORE_AV_REG(0x64) -+#define HDMI_CORE_AV_SPDIF_ERTH HDMI_CORE_AV_REG(0x6C) -+#define HDMI_CORE_AV_I2S_IN_MAP HDMI_CORE_AV_REG(0x70) -+#define HDMI_CORE_AV_I2S_IN_CTRL HDMI_CORE_AV_REG(0x74) -+#define HDMI_CORE_AV_I2S_CHST0 HDMI_CORE_AV_REG(0x78) -+#define HDMI_CORE_AV_I2S_CHST1 HDMI_CORE_AV_REG(0x7C) -+#define HDMI_CORE_AV_I2S_CHST2 HDMI_CORE_AV_REG(0x80) -+#define HDMI_CORE_AV_I2S_CHST4 HDMI_CORE_AV_REG(0x84) -+#define HDMI_CORE_AV_I2S_CHST5 HDMI_CORE_AV_REG(0x88) -+#define HDMI_CORE_AV_ASRC HDMI_CORE_AV_REG(0x8C) -+#define HDMI_CORE_AV_I2S_IN_LEN HDMI_CORE_AV_REG(0x90) -+#define HDMI_CORE_AV_HDMI_CTRL HDMI_CORE_AV_REG(0xBC) -+#define HDMI_CORE_AV_AUDO_TXSTAT HDMI_CORE_AV_REG(0xC0) -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_1 HDMI_CORE_AV_REG(0xCC) -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_2 HDMI_CORE_AV_REG(0xD0) -+#define HDMI_CORE_AV_AUD_PAR_BUSCLK_3 HDMI_CORE_AV_REG(0xD4) -+#define HDMI_CORE_AV_TEST_TXCTRL HDMI_CORE_AV_REG(0xF0) -+#define HDMI_CORE_AV_DPD HDMI_CORE_AV_REG(0xF4) -+#define HDMI_CORE_AV_PB_CTRL1 HDMI_CORE_AV_REG(0xF8) -+#define HDMI_CORE_AV_PB_CTRL2 HDMI_CORE_AV_REG(0xFC) -+#define HDMI_CORE_AV_AVI_TYPE HDMI_CORE_AV_REG(0x100) -+#define HDMI_CORE_AV_AVI_VERS HDMI_CORE_AV_REG(0x104) -+#define HDMI_CORE_AV_AVI_LEN HDMI_CORE_AV_REG(0x108) -+#define HDMI_CORE_AV_AVI_CHSUM HDMI_CORE_AV_REG(0x10C) -+#define HDMI_CORE_AV_SPD_TYPE HDMI_CORE_AV_REG(0x180) -+#define HDMI_CORE_AV_SPD_VERS HDMI_CORE_AV_REG(0x184) -+#define HDMI_CORE_AV_SPD_LEN HDMI_CORE_AV_REG(0x188) -+#define HDMI_CORE_AV_SPD_CHSUM HDMI_CORE_AV_REG(0x18C) -+#define HDMI_CORE_AV_MPEG_TYPE HDMI_CORE_AV_REG(0x280) -+#define HDMI_CORE_AV_MPEG_VERS HDMI_CORE_AV_REG(0x284) -+#define HDMI_CORE_AV_MPEG_LEN HDMI_CORE_AV_REG(0x288) -+#define HDMI_CORE_AV_MPEG_CHSUM HDMI_CORE_AV_REG(0x28C) -+#define HDMI_CORE_AV_CP_BYTE1 HDMI_CORE_AV_REG(0x37C) -+#define HDMI_CORE_AV_CEC_ADDR_ID HDMI_CORE_AV_REG(0x3FC) -+#define HDMI_CORE_AV_SPD_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_GEN2_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_MPEG_DBYTE_ELSIZE 0x4 -+#define HDMI_CORE_AV_GEN_DBYTE_ELSIZE 0x4 -+ -+/* PLL */ -+#define HDMI_PLL_REG(idx) HDMI_REG(HDMI_PLLCTRL + idx) -+ -+#define PLLCTRL_PLL_CONTROL HDMI_PLL_REG(0x0) -+#define PLLCTRL_PLL_STATUS HDMI_PLL_REG(0x4) -+#define PLLCTRL_PLL_GO HDMI_PLL_REG(0x8) -+#define PLLCTRL_CFG1 HDMI_PLL_REG(0xC) -+#define PLLCTRL_CFG2 HDMI_PLL_REG(0x10) -+#define PLLCTRL_CFG3 HDMI_PLL_REG(0x14) -+#define PLLCTRL_CFG4 HDMI_PLL_REG(0x20) -+ -+/* HDMI PHY */ -+#define HDMI_PHY_REG(idx) HDMI_REG(HDMI_PHY + idx) -+ -+#define HDMI_TXPHY_TX_CTRL HDMI_PHY_REG(0x0) -+#define HDMI_TXPHY_DIGITAL_CTRL HDMI_PHY_REG(0x4) -+#define HDMI_TXPHY_POWER_CTRL HDMI_PHY_REG(0x8) -+#define HDMI_TXPHY_PAD_CFG_CTRL HDMI_PHY_REG(0xC) -+ -+/* HDMI EDID Length */ -+#define HDMI_EDID_MAX_LENGTH 256 -+#define EDID_TIMING_DESCRIPTOR_SIZE 0x12 -+#define EDID_DESCRIPTOR_BLOCK0_ADDRESS 0x36 -+#define EDID_DESCRIPTOR_BLOCK1_ADDRESS 0x80 -+#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 -+#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 -+ -+#define OMAP_HDMI_TIMINGS_NB 34 -+ -+#define REG_FLD_MOD(idx, val, start, end) \ -+ hdmi_write_reg(idx, FLD_MOD(hdmi_read_reg(idx), val, start, end)) -+#define REG_GET(idx, start, end) \ -+ FLD_GET(hdmi_read_reg(idx), start, end) -+ -+/* HDMI timing structure */ -+struct hdmi_timings { -+ struct omap_video_timings timings; -+ int vsync_pol; -+ int hsync_pol; -+}; -+ -+enum hdmi_phy_pwr { -+ HDMI_PHYPWRCMD_OFF = 0, -+ HDMI_PHYPWRCMD_LDOON = 1, -+ HDMI_PHYPWRCMD_TXON = 2 -+}; -+ -+enum hdmi_pll_pwr { -+ HDMI_PLLPWRCMD_ALLOFF = 0, -+ HDMI_PLLPWRCMD_PLLONLY = 1, -+ HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, -+ HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 -+}; -+ -+enum hdmi_clk_refsel { -+ HDMI_REFSEL_PCLK = 0, -+ HDMI_REFSEL_REF1 = 1, -+ HDMI_REFSEL_REF2 = 2, -+ HDMI_REFSEL_SYSCLK = 3 -+}; -+ -+enum hdmi_core_inputbus_width { -+ HDMI_INPUT_8BIT = 0, -+ HDMI_INPUT_10BIT = 1, -+ HDMI_INPUT_12BIT = 2 -+}; -+ -+enum hdmi_core_dither_trunc { -+ HDMI_OUTPUTTRUNCATION_8BIT = 0, -+ HDMI_OUTPUTTRUNCATION_10BIT = 1, -+ HDMI_OUTPUTTRUNCATION_12BIT = 2, -+ HDMI_OUTPUTDITHER_8BIT = 3, -+ HDMI_OUTPUTDITHER_10BIT = 4, -+ HDMI_OUTPUTDITHER_12BIT = 5 -+}; -+ -+enum hdmi_core_deepcolor_ed { -+ HDMI_DEEPCOLORPACKECTDISABLE = 0, -+ HDMI_DEEPCOLORPACKECTENABLE = 1 -+}; -+ -+enum hdmi_core_packet_mode { -+ HDMI_PACKETMODERESERVEDVALUE = 0, -+ HDMI_PACKETMODE24BITPERPIXEL = 4, -+ HDMI_PACKETMODE30BITPERPIXEL = 5, -+ HDMI_PACKETMODE36BITPERPIXEL = 6, -+ HDMI_PACKETMODE48BITPERPIXEL = 7 -+}; -+ -+enum hdmi_core_hdmi_dvi { -+ HDMI_DVI = 0, -+ HDMI_HDMI = 1 -+}; -+ -+enum hdmi_core_tclkselclkmult { -+ HDMI_FPLL05IDCK = 0, -+ HDMI_FPLL10IDCK = 1, -+ HDMI_FPLL20IDCK = 2, -+ HDMI_FPLL40IDCK = 3 -+}; -+ -+enum hdmi_core_packet_ctrl { -+ HDMI_PACKETENABLE = 1, -+ HDMI_PACKETDISABLE = 0, -+ HDMI_PACKETREPEATON = 1, -+ HDMI_PACKETREPEATOFF = 0 -+}; -+ -+/* INFOFRAME_AVI_ definitions */ -+enum hdmi_core_infoframe { -+ HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, -+ HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, -+ HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1, -+ HDMI_INFOFRAME_AVI_DB1B_NO = 0, -+ HDMI_INFOFRAME_AVI_DB1B_VERT = 1, -+ HDMI_INFOFRAME_AVI_DB1B_HORI = 2, -+ HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, -+ HDMI_INFOFRAME_AVI_DB1S_0 = 0, -+ HDMI_INFOFRAME_AVI_DB1S_1 = 1, -+ HDMI_INFOFRAME_AVI_DB1S_2 = 2, -+ HDMI_INFOFRAME_AVI_DB2C_NO = 0, -+ HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, -+ HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, -+ HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, -+ HDMI_INFOFRAME_AVI_DB2M_NO = 0, -+ HDMI_INFOFRAME_AVI_DB2M_43 = 1, -+ HDMI_INFOFRAME_AVI_DB2M_169 = 2, -+ HDMI_INFOFRAME_AVI_DB2R_SAME = 8, -+ HDMI_INFOFRAME_AVI_DB2R_43 = 9, -+ HDMI_INFOFRAME_AVI_DB2R_169 = 10, -+ HDMI_INFOFRAME_AVI_DB2R_149 = 11, -+ HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, -+ HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, -+ HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, -+ HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, -+ HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, -+ HDMI_INFOFRAME_AVI_DB3Q_LR = 1, -+ HDMI_INFOFRAME_AVI_DB3Q_FR = 2, -+ HDMI_INFOFRAME_AVI_DB3SC_NO = 0, -+ HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, -+ HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, -+ HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, -+ HDMI_INFOFRAME_AVI_DB5PR_NO = 0, -+ HDMI_INFOFRAME_AVI_DB5PR_2 = 1, -+ HDMI_INFOFRAME_AVI_DB5PR_3 = 2, -+ HDMI_INFOFRAME_AVI_DB5PR_4 = 3, -+ HDMI_INFOFRAME_AVI_DB5PR_5 = 4, -+ HDMI_INFOFRAME_AVI_DB5PR_6 = 5, -+ HDMI_INFOFRAME_AVI_DB5PR_7 = 6, -+ HDMI_INFOFRAME_AVI_DB5PR_8 = 7, -+ HDMI_INFOFRAME_AVI_DB5PR_9 = 8, -+ HDMI_INFOFRAME_AVI_DB5PR_10 = 9 -+}; -+ -+enum hdmi_packing_mode { -+ HDMI_PACK_10b_RGB_YUV444 = 0, -+ HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, -+ HDMI_PACK_20b_YUV422 = 2, -+ HDMI_PACK_ALREADYPACKED = 7 -+}; -+ -+struct hdmi_core_video_config { -+ enum hdmi_core_inputbus_width ip_bus_width; -+ enum hdmi_core_dither_trunc op_dither_truc; -+ enum hdmi_core_deepcolor_ed deep_color_pkt; -+ enum hdmi_core_packet_mode pkt_mode; -+ enum hdmi_core_hdmi_dvi hdmi_dvi; -+ enum hdmi_core_tclkselclkmult tclk_sel_clkmult; -+}; -+ -+/* -+ * Refer to section 8.2 in HDMI 1.3 specification for -+ * details about infoframe databytes -+ */ -+struct hdmi_core_infoframe_avi { -+ u8 db1_format; -+ /* Y0, Y1 rgb,yCbCr */ -+ u8 db1_active_info; -+ /* A0 Active information Present */ -+ u8 db1_bar_info_dv; -+ /* B0, B1 Bar info data valid */ -+ u8 db1_scan_info; -+ /* S0, S1 scan information */ -+ u8 db2_colorimetry; -+ /* C0, C1 colorimetry */ -+ u8 db2_aspect_ratio; -+ /* M0, M1 Aspect ratio (4:3, 16:9) */ -+ u8 db2_active_fmt_ar; -+ /* R0...R3 Active format aspect ratio */ -+ u8 db3_itc; -+ /* ITC IT content. */ -+ u8 db3_ec; -+ /* EC0, EC1, EC2 Extended colorimetry */ -+ u8 db3_q_range; -+ /* Q1, Q0 Quantization range */ -+ u8 db3_nup_scaling; -+ /* SC1, SC0 Non-uniform picture scaling */ -+ u8 db4_videocode; -+ /* VIC0..6 Video format identification */ -+ u8 db5_pixel_repeat; -+ /* PR0..PR3 Pixel repetition factor */ -+ u16 db6_7_line_eoftop; -+ /* Line number end of top bar */ -+ u16 db8_9_line_sofbottom; -+ /* Line number start of bottom bar */ -+ u16 db10_11_pixel_eofleft; -+ /* Pixel number end of left bar */ -+ u16 db12_13_pixel_sofright; -+ /* Pixel number start of right bar */ -+}; -+ -+struct hdmi_core_packet_enable_repeat { -+ u32 audio_pkt; -+ u32 audio_pkt_repeat; -+ u32 avi_infoframe; -+ u32 avi_infoframe_repeat; -+ u32 gen_cntrl_pkt; -+ u32 gen_cntrl_pkt_repeat; -+ u32 generic_pkt; -+ u32 generic_pkt_repeat; -+}; -+ -+struct hdmi_video_format { -+ enum hdmi_packing_mode packing_mode; -+ u32 y_res; /* Line per panel */ -+ u32 x_res; /* pixel per line */ -+}; -+ -+struct hdmi_video_interface { -+ int vsp; /* Vsync polarity */ -+ int hsp; /* Hsync polarity */ -+ int interlacing; -+ int tm; /* Timing mode */ -+}; -+ -+struct hdmi_cm { -+ int code; -+ int mode; -+}; -+ -+struct hdmi_config { -+ struct hdmi_timings timings; -+ u16 interlace; -+ struct hdmi_cm cm; -+}; -+ -+#endif --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-305-V5_HDMI_driver_addition_in_the_DSS.patch b/packages/linux/patches/linux-2.6.38-rc8-305-V5_HDMI_driver_addition_in_the_DSS.patch deleted file mode 100644 index 37d58f9b98..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-305-V5_HDMI_driver_addition_in_the_DSS.patch +++ /dev/null @@ -1,1418 +0,0 @@ -Adding the hdmi interface driver(hdmi.c) to the dss driver. -It configures the audio and video portion of HDMI based on -functionality called by the panel driver. - -Signed-off-by: Mythri P K - Yong Zhi ---- - drivers/video/omap2/dss/display.c | 3 + - drivers/video/omap2/dss/dss.h | 34 + - drivers/video/omap2/dss/hdmi.c | 1332 +++++++++++++++++++++++++++++++++++++ - 3 files changed, 1369 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/omap2/dss/hdmi.c - -diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c -index c40bcbd..a85a6f3 100644 ---- a/drivers/video/omap2/dss/display.c -+++ b/drivers/video/omap2/dss/display.c -@@ -418,6 +418,9 @@ void dss_init_device(struct platform_device *pdev, - r = dsi_init_display(dssdev); - break; - #endif -+ case OMAP_DISPLAY_TYPE_HDMI: -+ r = hdmi_init_display(dssdev); -+ break; - default: - DSSERR("Support for display '%s' not compiled in.\n", - dssdev->name); -diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h -index 9f563a6..6bf923c 100644 ---- a/drivers/video/omap2/dss/dss.h -+++ b/drivers/video/omap2/dss/dss.h -@@ -179,6 +179,16 @@ struct dsi_clock_info { - bool use_sys_clk; - }; - -+/* HDMI PLL structure */ -+struct hdmi_pll_info { -+ u16 regn; -+ u16 regm; -+ u32 regmf; -+ u16 regm2; -+ u16 regsd; -+ u16 dcofreq; -+}; -+ - struct seq_file; - struct platform_device; - -@@ -450,6 +460,30 @@ static inline void venc_uninit_platform_driver(void) - } - #endif - -+/* HDMI */ -+#ifdef CONFIG_OMAP4_DSS_HDMI -+int hdmi_init_platform_driver(void); -+void hdmi_uninit_platform_driver(void); -+int hdmi_init_display(struct omap_dss_device *dssdev); -+#else -+static inline int hdmi_init_display(struct omap_dss_device *dssdev) -+{ -+ return 0; -+} -+static inline int hdmi_init_platform_driver(void) -+{ -+ return 0; -+} -+static inline void hdmi_uninit_platform_driver(void) -+{ -+} -+#endif -+int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); -+void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); -+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); -+int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings); -+ - /* RFBI */ - #ifdef CONFIG_OMAP2_DSS_RFBI - int rfbi_init_platform_driver(void); -diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c -new file mode 100644 -index 0000000..e0e2cbb ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi.c -@@ -0,0 +1,1332 @@ -+/* -+ * hdmi.c -+ * -+ * HDMI interface DSS driver setting for TI's OMAP4 family of processor. -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * Authors: Yong Zhi -+ * Mythri pk -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#define DSS_SUBSYS_NAME "HDMI" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dss.h" -+#include "hdmi.h" -+ -+static struct { -+ struct mutex lock; -+ struct omap_display_platform_data *pdata; -+ struct platform_device *pdev; -+ void __iomem *base_wp; /* HDMI wrapper */ -+ int code; -+ int mode; -+ u8 edid[HDMI_EDID_MAX_LENGTH]; -+ u8 edid_set; -+ bool custom_set; -+ struct hdmi_config cfg; -+} hdmi; -+ -+/* -+ * Logic for the below structure : -+ * user enters the CEA or VESA timings by specifying the HDMI/DVI code. -+ * There is a correspondence between CEA/VESA timing and code , Please -+ * refer to section 6.3 in HDMI 1.3 specification for timing code. -+ * In the below structure, cea_vesa_timings corresponds to all OMAP4 -+ * supported CEA and VESA timing values. -+ * code_cea corresponds to the CEA code , It is used to get the timing -+ * from cea_vesa_timing array. Similarly with code_vesa. -+ * code_index is used for back mapping, That is once EDID is read from -+ * the TV, EDID is parsed to find the timing values and then map it to -+ * corresponding CEA or VESA index. -+ */ -+ -+static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { -+ { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, -+ { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, -+ { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, -+ { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, -+ { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, -+ { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, -+ { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, -+ { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, -+ { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, -+ { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, -+ { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, -+ { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, -+ { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, -+ { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, -+ { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, -+ /* VESA From Here */ -+ { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0}, -+ { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1}, -+ { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1}, -+ { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0}, -+ { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0}, -+ { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1}, -+ { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1}, -+ { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1}, -+ { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0}, -+ { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0}, -+ { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0}, -+ { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0}, -+ { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1}, -+ { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1}, -+ { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1}, -+ { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1}, -+ { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1}, -+ { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1}, -+ { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1} -+}; -+ -+/* -+ * This is a static mapping array which maps the timing values -+ * with corresponding CEA / VESA code -+ */ -+static const int code_index[OMAP_HDMI_TIMINGS_NB] = { -+ 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, -+ /* <--15 CEA 17--> vesa*/ -+ 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, -+ 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B -+}; -+ -+/* -+ * This is reverse static mapping which maps the CEA / VESA code -+ * to the corresponding timing values -+ */ -+static const int code_cea[39] = { -+ -1, 0, 3, 3, 2, 8, 5, 5, -1, -1, -+ -1, -1, -1, -1, -1, -1, 9, 10, 10, 1, -+ 7, 6, 6, -1, -1, -1, -1, -1, -1, 11, -+ 11, 12, 14, -1, -1, 13, 13, 4, 4 -+}; -+ -+static const int code_vesa[85] = { -+ -1, -1, -1, -1, 15, -1, -1, -1, -1, 16, -+ -1, -1, -1, -1, 17, -1, 23, -1, -1, -1, -+ -1, -1, 29, 18, -1, -1, -1, 32, 19, -1, -+ -1, -1, 21, -1, -1, 22, -1, -1, -1, 20, -+ -1, 30, 24, -1, -1, -1, -1, 25, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, 31, 26, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -+ -1, 27, 28, -1, 33}; -+ -+static const u8 edid_header[8] = {0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0}; -+ -+static inline void hdmi_write_reg(const struct hdmi_reg idx, u32 val) -+{ -+ __raw_writel(val, hdmi.base_wp + idx.idx); -+} -+ -+static inline u32 hdmi_read_reg(const struct hdmi_reg idx) -+{ -+ return __raw_readl(hdmi.base_wp + idx.idx); -+} -+ -+static inline int hdmi_wait_for_bit_change(const struct hdmi_reg idx, -+ int b2, int b1, u32 val) -+{ -+ u32 t = 0; -+ while (val != REG_GET(idx, b2, b1)) { -+ udelay(1); -+ if (t++ > 10000) -+ return !val; -+ } -+ return val; -+} -+ -+int hdmi_init_display(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("init_display\n"); -+ -+ return 0; -+} -+ -+static int hdmi_pll_init(enum hdmi_clk_refsel refsel, int dcofreq, -+ struct hdmi_pll_info *fmt, u16 sd) -+{ -+ u32 r; -+ -+ /* PLL start always use manual mode */ -+ REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 0, 0); -+ -+ r = hdmi_read_reg(PLLCTRL_CFG1); -+ r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ -+ r = FLD_MOD(r, fmt->regn, 8, 1); /* CFG1_PLL_REGN */ -+ -+ hdmi_write_reg(PLLCTRL_CFG1, r); -+ -+ r = hdmi_read_reg(PLLCTRL_CFG2); -+ -+ r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ -+ r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ -+ r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ -+ -+ if (dcofreq) { -+ /* divider programming for frequency beyond 1000Mhz */ -+ REG_FLD_MOD(PLLCTRL_CFG3, sd, 17, 10); -+ r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ -+ } else { -+ r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ -+ } -+ -+ hdmi_write_reg(PLLCTRL_CFG2, r); -+ -+ r = hdmi_read_reg(PLLCTRL_CFG4); -+ r = FLD_MOD(r, fmt->regm2, 24, 18); -+ r = FLD_MOD(r, fmt->regmf, 17, 0); -+ -+ hdmi_write_reg(PLLCTRL_CFG4, r); -+ -+ /* go now */ -+ REG_FLD_MOD(PLLCTRL_PLL_GO, 0x1, 0, 0); -+ -+ /* wait for bit change */ -+ if (hdmi_wait_for_bit_change(PLLCTRL_PLL_GO, 0, 0, 1) != 1) { -+ DSSERR("PLL GO bit not set\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Wait till the lock bit is set in PLL status */ -+ if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { -+ DSSWARN("cannot lock PLL\n"); -+ DSSWARN("CFG1 0x%x\n", -+ hdmi_read_reg(PLLCTRL_CFG1)); -+ DSSWARN("CFG2 0x%x\n", -+ hdmi_read_reg(PLLCTRL_CFG2)); -+ DSSWARN("CFG4 0x%x\n", -+ hdmi_read_reg(PLLCTRL_CFG4)); -+ return -ETIMEDOUT; -+ } -+ -+ DSSDBG("PLL locked!\n"); -+ -+ return 0; -+} -+ -+/* PHY_PWR_CMD */ -+static int hdmi_set_phy_pwr(enum hdmi_phy_pwr val) -+{ -+ /* Command for power control of HDMI PHY */ -+ REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 7, 6); -+ -+ /* Status of the power control of HDMI PHY */ -+ if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 5, 4, val) != val) { -+ DSSERR("Failed to set PHY power mode to %d\n", val); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+/* PLL_PWR_CMD */ -+static int hdmi_set_pll_pwr(enum hdmi_pll_pwr val) -+{ -+ /* Command for power control of HDMI PLL */ -+ REG_FLD_MOD(HDMI_WP_PWR_CTRL, val, 3, 2); -+ -+ /* wait till PHY_PWR_STATUS is set */ -+ if (hdmi_wait_for_bit_change(HDMI_WP_PWR_CTRL, 1, 0, val) != val) { -+ DSSERR("Failed to set PHY_PWR_STATUS\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int hdmi_pll_reset(void) -+{ -+ /* SYSRESET controlled by power FSM */ -+ REG_FLD_MOD(PLLCTRL_PLL_CONTROL, 0x0, 3, 3); -+ -+ /* READ 0x0 reset is in progress */ -+ if (hdmi_wait_for_bit_change(PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { -+ DSSERR("Failed to sysreset PLL\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int hdmi_phy_init(void) -+{ -+ u16 r = 0; -+ -+ r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_LDOON); -+ if (r) -+ return r; -+ -+ r = hdmi_set_phy_pwr(HDMI_PHYPWRCMD_TXON); -+ if (r) -+ return r; -+ -+ /* -+ * Read address 0 in order to get the SCP reset done completed -+ * Dummy access performed to make sure reset is done -+ */ -+ hdmi_read_reg(HDMI_TXPHY_TX_CTRL); -+ -+ /* -+ * Write to phy address 0 to configure the clock -+ * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field -+ */ -+ REG_FLD_MOD(HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); -+ -+ /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ -+ hdmi_write_reg(HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); -+ -+ /* Setup max LDO voltage */ -+ REG_FLD_MOD(HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); -+ -+ /* Write to phy address 3 to change the polarity control */ -+ REG_FLD_MOD(HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); -+ -+ return 0; -+} -+ -+static int hdmi_wait_softreset(void) -+{ -+ /* reset W1 */ -+ REG_FLD_MOD(HDMI_WP_SYSCONFIG, 0x1, 0, 0); -+ -+ /* wait till SOFTRESET == 0 */ -+ if (hdmi_wait_for_bit_change(HDMI_WP_SYSCONFIG, 0, 0, 0) != 0) { -+ DSSERR("sysconfig reset failed\n"); -+ return -ETIMEDOUT; -+ } -+ -+ return 0; -+} -+ -+static int hdmi_pll_program(struct hdmi_pll_info *fmt) -+{ -+ u16 r = 0; -+ enum hdmi_clk_refsel refsel; -+ -+ /* wait for wrapper reset */ -+ r = hdmi_wait_softreset(); -+ if (r) -+ return r; -+ -+ r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); -+ if (r) -+ return r; -+ -+ r = hdmi_set_pll_pwr(HDMI_PLLPWRCMD_BOTHON_ALLCLKS); -+ if (r) -+ return r; -+ -+ r = hdmi_pll_reset(); -+ if (r) -+ return r; -+ -+ refsel = HDMI_REFSEL_SYSCLK; -+ -+ r = hdmi_pll_init(refsel, fmt->dcofreq, fmt, fmt->regsd); -+ if (r) -+ return r; -+ -+ return 0; -+} -+ -+static void hdmi_phy_off(void) -+{ -+ hdmi_set_phy_pwr(HDMI_PHYPWRCMD_OFF); -+} -+ -+static int hdmi_core_ddc_edid(u8 *pedid, int ext) -+{ -+ u32 i, j; -+ char checksum = 0; -+ u32 offset = 0; -+ -+ /* Turn on CLK for DDC */ -+ REG_FLD_MOD(HDMI_CORE_AV_DPD, 0x7, 2, 0); -+ -+ /* -+ * SW HACK : Without the Delay DDC(i2c bus) reads 0 values / -+ * right shifted values( The behavior is not consistent and seen only -+ * with some TV's) -+ */ -+ usleep_range(800, 1000); -+ -+ if (!ext) { -+ /* Clk SCL Devices */ -+ REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0xA, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_IN_PROG */ -+ if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Failed to program DDC\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Clear FIFO */ -+ REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x9, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_IN_PROG */ -+ if (hdmi_wait_for_bit_change(HDMI_CORE_DDC_STATUS, -+ 4, 4, 0) != 0) { -+ DSSERR("Failed to program DDC\n"); -+ return -ETIMEDOUT; -+ } -+ -+ } else { -+ if (ext % 2 != 0) -+ offset = 0x80; -+ } -+ -+ /* Load Segment Address Register */ -+ REG_FLD_MOD(HDMI_CORE_DDC_SEGM, ext/2, 7, 0); -+ -+ /* Load Slave Address Register */ -+ REG_FLD_MOD(HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1); -+ -+ /* Load Offset Address Register */ -+ REG_FLD_MOD(HDMI_CORE_DDC_OFFSET, offset, 7, 0); -+ -+ /* Load Byte Count */ -+ REG_FLD_MOD(HDMI_CORE_DDC_COUNT1, 0x80, 7, 0); -+ REG_FLD_MOD(HDMI_CORE_DDC_COUNT2, 0x0, 1, 0); -+ -+ /* Set DDC_CMD */ -+ if (ext) -+ REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x4, 3, 0); -+ else -+ REG_FLD_MOD(HDMI_CORE_DDC_CMD, 0x2, 3, 0); -+ -+ /* HDMI_CORE_DDC_STATUS_BUS_LOW */ -+ if (REG_GET(HDMI_CORE_DDC_STATUS, 6, 6) == 1) { -+ DSSWARN("I2C Bus Low?\n"); -+ return -EIO; -+ } -+ /* HDMI_CORE_DDC_STATUS_NO_ACK */ -+ if (REG_GET(HDMI_CORE_DDC_STATUS, 5, 5) == 1) { -+ DSSWARN("I2C No Ack\n"); -+ return -EIO; -+ } -+ -+ i = ext * 128; -+ j = 0; -+ while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) || -+ (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) && -+ j < 128) { -+ -+ if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) { -+ /* FIFO not empty */ -+ pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0); -+ j++; -+ } -+ } -+ -+ for (j = 0; j < 128; j++) -+ checksum += pedid[j]; -+ -+ if (checksum != 0) { -+ DSSERR("E-EDID checksum failed!!\n"); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static int read_edid(u8 *pedid, u16 max_length) -+{ -+ int r = 0, n = 0, i = 0; -+ int max_ext_blocks = (max_length / 128) - 1; -+ -+ r = hdmi_core_ddc_edid(pedid, 0); -+ if (r) { -+ return r; -+ } else { -+ n = pedid[0x7e]; -+ -+ /* -+ * README: need to comply with max_length set by the caller. -+ * Better implementation should be to allocate necessary -+ * memory to store EDID according to nb_block field found -+ * in first block -+ */ -+ if (n > max_ext_blocks) -+ n = max_ext_blocks; -+ -+ for (i = 1; i <= n; i++) { -+ r = hdmi_core_ddc_edid(pedid, i); -+ if (r) -+ return r; -+ } -+ } -+ return 0; -+} -+ -+static int get_timings_index(void) -+{ -+ int code; -+ -+ if (hdmi.mode == 0) -+ code = code_vesa[hdmi.code]; -+ else -+ code = code_cea[hdmi.code]; -+ -+ if (code == -1) { -+ /* HDMI code 4 corresponds to 640 * 480 VGA */ -+ hdmi.code = 4; -+ /* DVI mode 1 corresponds to HDMI 0 to DVI */ -+ hdmi.mode = HDMI_DVI; -+ -+ code = code_vesa[hdmi.code]; -+ } -+ return code; -+} -+ -+static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) -+{ -+ int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; -+ int timing_vsync = 0, timing_hsync = 0; -+ struct omap_video_timings temp; -+ struct hdmi_cm cm = {-1}; -+ DSSDBG("hdmi_get_code\n"); -+ -+ for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { -+ temp = cea_vesa_timings[i].timings; -+ if ((temp.pixel_clock == timing->pixel_clock) && -+ (temp.x_res == timing->x_res) && -+ (temp.y_res == timing->y_res)) { -+ -+ temp_hsync = temp.hfp + temp.hsw + temp.hbp; -+ timing_hsync = timing->hfp + timing->hsw + timing->hbp; -+ temp_vsync = temp.vfp + temp.vsw + temp.vbp; -+ timing_vsync = timing->vfp + timing->vsw + timing->vbp; -+ -+ DSSDBG("temp_hsync = %d , temp_vsync = %d" -+ "timing_hsync = %d, timing_vsync = %d\n", -+ temp_hsync, temp_hsync, -+ timing_hsync, timing_vsync); -+ -+ if ((temp_hsync == timing_hsync) && -+ (temp_vsync == timing_vsync)) { -+ code = i; -+ cm.code = code_index[i]; -+ if (code < 14) -+ cm.mode = HDMI_HDMI; -+ else -+ cm.mode = HDMI_DVI; -+ DSSDBG("Hdmi_code = %d mode = %d\n", -+ cm.code, cm.mode); -+ break; -+ } -+ } -+ } -+ -+ return cm; -+} -+ -+static void get_horz_vert_timing_info(int current_descriptor_addrs, u8 *edid , -+ struct omap_video_timings *timings) -+{ -+ /* X and Y resolution */ -+ timings->x_res = (((edid[current_descriptor_addrs + 4] & 0xF0) << 4) | -+ edid[current_descriptor_addrs + 2]); -+ timings->y_res = (((edid[current_descriptor_addrs + 7] & 0xF0) << 4) | -+ edid[current_descriptor_addrs + 5]); -+ -+ timings->pixel_clock = ((edid[current_descriptor_addrs + 1] << 8) | -+ edid[current_descriptor_addrs]); -+ -+ timings->pixel_clock = 10 * timings->pixel_clock; -+ -+ /* HORIZONTAL FRONT PORCH */ -+ timings->hfp = edid[current_descriptor_addrs + 8] | -+ ((edid[current_descriptor_addrs + 11] & 0xc0) << 2); -+ /* HORIZONTAL SYNC WIDTH */ -+ timings->hsw = edid[current_descriptor_addrs + 9] | -+ ((edid[current_descriptor_addrs + 11] & 0x30) << 4); -+ /* HORIZONTAL BACK PORCH */ -+ timings->hbp = (((edid[current_descriptor_addrs + 4] & 0x0F) << 8) | -+ edid[current_descriptor_addrs + 3]) - -+ (timings->hfp + timings->hsw); -+ /* VERTICAL FRONT PORCH */ -+ timings->vfp = ((edid[current_descriptor_addrs + 10] & 0xF0) >> 4) | -+ ((edid[current_descriptor_addrs + 11] & 0x0f) << 2); -+ /* VERTICAL SYNC WIDTH */ -+ timings->vsw = (edid[current_descriptor_addrs + 10] & 0x0F) | -+ ((edid[current_descriptor_addrs + 11] & 0x03) << 4); -+ /* VERTICAL BACK PORCH */ -+ timings->vbp = (((edid[current_descriptor_addrs + 7] & 0x0F) << 8) | -+ edid[current_descriptor_addrs + 6]) - -+ (timings->vfp + timings->vsw); -+ -+} -+ -+/* Description : This function gets the resolution information from EDID */ -+static void get_edid_timing_data(u8 *edid) -+{ -+ u8 count; -+ u16 current_descriptor_addrs; -+ struct hdmi_cm cm; -+ struct omap_video_timings edid_timings; -+ -+ /* seach block 0, there are 4 DTDs arranged in priority order */ -+ for (count = 0; count < EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR; count++) { -+ current_descriptor_addrs = -+ EDID_DESCRIPTOR_BLOCK0_ADDRESS + -+ count * EDID_TIMING_DESCRIPTOR_SIZE; -+ get_horz_vert_timing_info(current_descriptor_addrs, -+ edid, &edid_timings); -+ cm = hdmi_get_code(&edid_timings); -+ DSSDBG("Block0[%d] value matches code = %d , mode = %d\n", -+ count, cm.code, cm.mode); -+ if (cm.code == -1) { -+ continue; -+ } else { -+ hdmi.code = cm.code; -+ hdmi.mode = cm.mode; -+ DSSDBG("code = %d , mode = %d\n", -+ hdmi.code, hdmi.mode); -+ return; -+ } -+ } -+ if (edid[0x7e] != 0x00) { -+ for (count = 0; count < EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR; -+ count++) { -+ current_descriptor_addrs = -+ EDID_DESCRIPTOR_BLOCK1_ADDRESS + -+ count * EDID_TIMING_DESCRIPTOR_SIZE; -+ get_horz_vert_timing_info(current_descriptor_addrs, -+ edid, &edid_timings); -+ cm = hdmi_get_code(&edid_timings); -+ DSSDBG("Block1[%d] value matches code = %d, mode = %d", -+ count, cm.code, cm.mode); -+ if (cm.code == -1) { -+ continue; -+ } else { -+ hdmi.code = cm.code; -+ hdmi.mode = cm.mode; -+ DSSDBG("code = %d , mode = %d\n", -+ hdmi.code, hdmi.mode); -+ return; -+ } -+ } -+ } -+ -+ DSSINFO("no valid timing found , falling back to VGA\n"); -+ hdmi.code = 4; /* setting default value of 640 480 VGA */ -+ hdmi.mode = HDMI_DVI; -+} -+ -+static void hdmi_read_edid(struct omap_video_timings *dp) -+{ -+ int ret = 0, code; -+ -+ memset(hdmi.edid, 0, HDMI_EDID_MAX_LENGTH); -+ -+ if (!hdmi.edid_set) -+ ret = read_edid(hdmi.edid, HDMI_EDID_MAX_LENGTH); -+ -+ if (!ret) { -+ if (!memcmp(hdmi.edid, edid_header, sizeof(edid_header))) { -+ /* search for timings of default resolution */ -+ get_edid_timing_data(hdmi.edid); -+ hdmi.edid_set = true; -+ } -+ } else { -+ DSSWARN("failed to read E-EDID\n"); -+ } -+ -+ if (!hdmi.edid_set) { -+ DSSINFO("fallback to VGA\n"); -+ hdmi.code = 4; /* setting default value of 640 480 VGA */ -+ hdmi.mode = HDMI_DVI; -+ } -+ -+ code = get_timings_index(); -+ -+ *dp = cea_vesa_timings[code].timings; -+} -+ -+static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, -+ struct hdmi_core_infoframe_avi *avi_cfg, -+ struct hdmi_core_packet_enable_repeat *repeat_cfg) -+{ -+ DSSDBG("Enter hdmi_core_init\n"); -+ -+ /* video core */ -+ video_cfg->ip_bus_width = HDMI_INPUT_8BIT; -+ video_cfg->op_dither_truc = HDMI_OUTPUTTRUNCATION_8BIT; -+ video_cfg->deep_color_pkt = HDMI_DEEPCOLORPACKECTDISABLE; -+ video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE; -+ video_cfg->hdmi_dvi = HDMI_DVI; -+ video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK; -+ -+ /* info frame */ -+ avi_cfg->db1_format = 0; -+ avi_cfg->db1_active_info = 0; -+ avi_cfg->db1_bar_info_dv = 0; -+ avi_cfg->db1_scan_info = 0; -+ avi_cfg->db2_colorimetry = 0; -+ avi_cfg->db2_aspect_ratio = 0; -+ avi_cfg->db2_active_fmt_ar = 0; -+ avi_cfg->db3_itc = 0; -+ avi_cfg->db3_ec = 0; -+ avi_cfg->db3_q_range = 0; -+ avi_cfg->db3_nup_scaling = 0; -+ avi_cfg->db4_videocode = 0; -+ avi_cfg->db5_pixel_repeat = 0; -+ avi_cfg->db6_7_line_eoftop = 0 ; -+ avi_cfg->db8_9_line_sofbottom = 0; -+ avi_cfg->db10_11_pixel_eofleft = 0; -+ avi_cfg->db12_13_pixel_sofright = 0; -+ -+ /* packet enable and repeat */ -+ repeat_cfg->audio_pkt = 0; -+ repeat_cfg->audio_pkt_repeat = 0; -+ repeat_cfg->avi_infoframe = 0; -+ repeat_cfg->avi_infoframe_repeat = 0; -+ repeat_cfg->gen_cntrl_pkt = 0; -+ repeat_cfg->gen_cntrl_pkt_repeat = 0; -+ repeat_cfg->generic_pkt = 0; -+ repeat_cfg->generic_pkt_repeat = 0; -+} -+ -+static void hdmi_core_powerdown_disable(void) -+{ -+ DSSDBG("Enter hdmi_core_powerdown_disable\n"); -+ REG_FLD_MOD(HDMI_CORE_CTRL1, 0x0, 0, 0); -+} -+ -+static void hdmi_core_swreset_release(void) -+{ -+ DSSDBG("Enter hdmi_core_swreset_release\n"); -+ REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x0, 0, 0); -+} -+ -+static void hdmi_core_swreset_assert(void) -+{ -+ DSSDBG("Enter hdmi_core_swreset_assert\n"); -+ REG_FLD_MOD(HDMI_CORE_SYS_SRST, 0x1, 0, 0); -+} -+ -+/* DSS_HDMI_CORE_VIDEO_CONFIG */ -+static void hdmi_core_video_config(struct hdmi_core_video_config *cfg) -+{ -+ u32 r = 0; -+ -+ /* sys_ctrl1 default configuration not tunable */ -+ r = hdmi_read_reg(HDMI_CORE_CTRL1); -+ r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5); -+ r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4); -+ r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2); -+ r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1); -+ hdmi_write_reg(HDMI_CORE_CTRL1, r); -+ -+ REG_FLD_MOD(HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); -+ -+ /* Vid_Mode */ -+ r = hdmi_read_reg(HDMI_CORE_SYS_VID_MODE); -+ -+ /* dither truncation configuration */ -+ if (cfg->op_dither_truc > HDMI_OUTPUTTRUNCATION_12BIT) { -+ r = FLD_MOD(r, cfg->op_dither_truc - 3, 7, 6); -+ r = FLD_MOD(r, 1, 5, 5); -+ } else { -+ r = FLD_MOD(r, cfg->op_dither_truc, 7, 6); -+ r = FLD_MOD(r, 0, 5, 5); -+ } -+ hdmi_write_reg(HDMI_CORE_SYS_VID_MODE, r); -+ -+ /* HDMI_Ctrl */ -+ r = hdmi_read_reg(HDMI_CORE_AV_HDMI_CTRL); -+ r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6); -+ r = FLD_MOD(r, cfg->pkt_mode, 5, 3); -+ r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); -+ hdmi_write_reg(HDMI_CORE_AV_HDMI_CTRL, r); -+ -+ /* TMDS_CTRL */ -+ REG_FLD_MOD(HDMI_CORE_SYS_TMDS_CTRL, -+ cfg->tclk_sel_clkmult, 6, 5); -+} -+ -+static void hdmi_core_aux_infoframe_avi_config( -+ struct hdmi_core_infoframe_avi info_avi) -+{ -+ u32 val; -+ char sum = 0, checksum = 0; -+ -+ sum += 0x82 + 0x002 + 0x00D; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_TYPE, 0x082); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_VERS, 0x002); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_LEN, 0x00D); -+ -+ val = (info_avi.db1_format << 5) | -+ (info_avi.db1_active_info << 4) | -+ (info_avi.db1_bar_info_dv << 2) | -+ (info_avi.db1_scan_info); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(0), val); -+ sum += val; -+ -+ val = (info_avi.db2_colorimetry << 6) | -+ (info_avi.db2_aspect_ratio << 4) | -+ (info_avi.db2_active_fmt_ar); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(1), val); -+ sum += val; -+ -+ val = (info_avi.db3_itc << 7) | -+ (info_avi.db3_ec << 4) | -+ (info_avi.db3_q_range << 2) | -+ (info_avi.db3_nup_scaling); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(2), val); -+ sum += val; -+ -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(3), info_avi.db4_videocode); -+ sum += info_avi.db4_videocode; -+ -+ val = info_avi.db5_pixel_repeat; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(4), val); -+ sum += val; -+ -+ val = info_avi.db6_7_line_eoftop & 0x00FF; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(5), val); -+ sum += val; -+ -+ val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(6), val); -+ sum += val; -+ -+ val = info_avi.db8_9_line_sofbottom & 0x00FF; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(7), val); -+ sum += val; -+ -+ val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(8), val); -+ sum += val; -+ -+ val = info_avi.db10_11_pixel_eofleft & 0x00FF; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(9), val); -+ sum += val; -+ -+ val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(10), val); -+ sum += val; -+ -+ val = info_avi.db12_13_pixel_sofright & 0x00FF; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(11), val); -+ sum += val; -+ -+ val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF); -+ hdmi_write_reg(HDMI_CORE_AV_AVI_DBYTE(12), val); -+ sum += val; -+ -+ checksum = 0x100 - sum; -+ hdmi_write_reg(HDMI_CORE_AV_AVI_CHSUM, checksum); -+} -+ -+static void hdmi_core_av_packet_config( -+ struct hdmi_core_packet_enable_repeat repeat_cfg) -+{ -+ /* enable/repeat the infoframe */ -+ hdmi_write_reg(HDMI_CORE_AV_PB_CTRL1, -+ (repeat_cfg.audio_pkt << 5) | -+ (repeat_cfg.audio_pkt_repeat << 4) | -+ (repeat_cfg.avi_infoframe << 1) | -+ (repeat_cfg.avi_infoframe_repeat)); -+ -+ /* enable/repeat the packet */ -+ hdmi_write_reg(HDMI_CORE_AV_PB_CTRL2, -+ (repeat_cfg.gen_cntrl_pkt << 3) | -+ (repeat_cfg.gen_cntrl_pkt_repeat << 2) | -+ (repeat_cfg.generic_pkt << 1) | -+ (repeat_cfg.generic_pkt_repeat)); -+} -+ -+static void hdmi_wp_init(struct omap_video_timings *timings, -+ struct hdmi_video_format *video_fmt, -+ struct hdmi_video_interface *video_int) -+{ -+ DSSDBG("Enter hdmi_wp_init\n"); -+ -+ timings->hbp = 0; -+ timings->hfp = 0; -+ timings->hsw = 0; -+ timings->vbp = 0; -+ timings->vfp = 0; -+ timings->vsw = 0; -+ -+ video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; -+ video_fmt->y_res = 0; -+ video_fmt->x_res = 0; -+ -+ video_int->vsp = 0; -+ video_int->hsp = 0; -+ -+ video_int->interlacing = 0; -+ video_int->tm = 0; /* HDMI_TIMING_SLAVE */ -+ -+} -+ -+static void hdmi_wp_video_start(bool start) -+{ -+ REG_FLD_MOD(HDMI_WP_VIDEO_CFG, start, 31, 31); -+} -+ -+static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, -+ struct omap_video_timings *timings, struct hdmi_config *param) -+{ -+ DSSDBG("Enter hdmi_wp_video_init_format\n"); -+ -+ video_fmt->y_res = param->timings.timings.y_res; -+ video_fmt->x_res = param->timings.timings.x_res; -+ -+ timings->hbp = param->timings.timings.hbp; -+ timings->hfp = param->timings.timings.hfp; -+ timings->hsw = param->timings.timings.hsw; -+ timings->vbp = param->timings.timings.vbp; -+ timings->vfp = param->timings.timings.vfp; -+ timings->vsw = param->timings.timings.vsw; -+} -+ -+static void hdmi_wp_video_config_format( -+ struct hdmi_video_format *video_fmt) -+{ -+ u32 l = 0; -+ -+ REG_FLD_MOD(HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, 10, 8); -+ -+ l |= FLD_VAL(video_fmt->y_res, 31, 16); -+ l |= FLD_VAL(video_fmt->x_res, 15, 0); -+ hdmi_write_reg(HDMI_WP_VIDEO_SIZE, l); -+} -+ -+static void hdmi_wp_video_config_interface( -+ struct hdmi_video_interface *video_int) -+{ -+ u32 r; -+ DSSDBG("Enter hdmi_wp_video_config_interface\n"); -+ -+ r = hdmi_read_reg(HDMI_WP_VIDEO_CFG); -+ r = FLD_MOD(r, video_int->vsp, 7, 7); -+ r = FLD_MOD(r, video_int->hsp, 6, 6); -+ r = FLD_MOD(r, video_int->interlacing, 3, 3); -+ r = FLD_MOD(r, video_int->tm, 1, 0); -+ hdmi_write_reg(HDMI_WP_VIDEO_CFG, r); -+} -+ -+static void hdmi_wp_video_config_timing( -+ struct omap_video_timings *timings) -+{ -+ u32 timing_h = 0; -+ u32 timing_v = 0; -+ -+ DSSDBG("Enter hdmi_wp_video_config_timing\n"); -+ -+ timing_h |= FLD_VAL(timings->hbp, 31, 20); -+ timing_h |= FLD_VAL(timings->hfp, 19, 8); -+ timing_h |= FLD_VAL(timings->hsw, 7, 0); -+ hdmi_write_reg(HDMI_WP_VIDEO_TIMING_H, timing_h); -+ -+ timing_v |= FLD_VAL(timings->vbp, 31, 20); -+ timing_v |= FLD_VAL(timings->vfp, 19, 8); -+ timing_v |= FLD_VAL(timings->vsw, 7, 0); -+ hdmi_write_reg(HDMI_WP_VIDEO_TIMING_V, timing_v); -+} -+ -+static void hdmi_basic_configure(struct hdmi_config *cfg) -+{ -+ /* HDMI */ -+ struct omap_video_timings video_timing; -+ struct hdmi_video_format video_format; -+ struct hdmi_video_interface video_interface; -+ /* HDMI core */ -+ struct hdmi_core_infoframe_avi avi_cfg; -+ struct hdmi_core_video_config v_core_cfg; -+ struct hdmi_core_packet_enable_repeat repeat_cfg; -+ -+ hdmi_wp_init(&video_timing, &video_format, -+ &video_interface); -+ -+ hdmi_core_init(&v_core_cfg, -+ &avi_cfg, -+ &repeat_cfg); -+ -+ hdmi_wp_video_init_format(&video_format, -+ &video_timing, cfg); -+ -+ hdmi_wp_video_config_timing(&video_timing); -+ -+ /* video config */ -+ video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; -+ -+ hdmi_wp_video_config_format(&video_format); -+ -+ video_interface.vsp = cfg->timings.vsync_pol; -+ video_interface.hsp = cfg->timings.hsync_pol; -+ video_interface.interlacing = cfg->interlace; -+ video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */ -+ -+ hdmi_wp_video_config_interface(&video_interface); -+ -+ /* -+ * configure core video part -+ * set software reset in the core -+ */ -+ hdmi_core_swreset_assert(); -+ -+ /* power down off */ -+ hdmi_core_powerdown_disable(); -+ -+ v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL; -+ v_core_cfg.hdmi_dvi = cfg->cm.mode; -+ -+ hdmi_core_video_config(&v_core_cfg); -+ -+ /* release software reset in the core */ -+ hdmi_core_swreset_release(); -+ -+ /* -+ * configure packet -+ * info frame video see doc CEA861-D page 65 -+ */ -+ avi_cfg.db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; -+ avi_cfg.db1_active_info = -+ HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; -+ avi_cfg.db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; -+ avi_cfg.db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; -+ avi_cfg.db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; -+ avi_cfg.db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; -+ avi_cfg.db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; -+ avi_cfg.db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; -+ avi_cfg.db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; -+ avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; -+ avi_cfg.db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; -+ avi_cfg.db4_videocode = cfg->cm.code; -+ avi_cfg.db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; -+ avi_cfg.db6_7_line_eoftop = 0; -+ avi_cfg.db8_9_line_sofbottom = 0; -+ avi_cfg.db10_11_pixel_eofleft = 0; -+ avi_cfg.db12_13_pixel_sofright = 0; -+ -+ hdmi_core_aux_infoframe_avi_config(avi_cfg); -+ -+ /* enable/repeat the infoframe */ -+ repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; -+ repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON; -+ /* wakeup */ -+ repeat_cfg.audio_pkt = HDMI_PACKETENABLE; -+ repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; -+ hdmi_core_av_packet_config(repeat_cfg); -+} -+ -+static void update_hdmi_timings(struct hdmi_config *cfg, -+ struct omap_video_timings *timings, int code) -+{ -+ cfg->timings.timings.x_res = timings->x_res; -+ cfg->timings.timings.y_res = timings->y_res; -+ cfg->timings.timings.hbp = timings->hbp; -+ cfg->timings.timings.hfp = timings->hfp; -+ cfg->timings.timings.hsw = timings->hsw; -+ cfg->timings.timings.vbp = timings->vbp; -+ cfg->timings.timings.vfp = timings->vfp; -+ cfg->timings.timings.vsw = timings->vsw; -+ cfg->timings.timings.pixel_clock = timings->pixel_clock; -+ cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol; -+ cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; -+} -+ -+static void hdmi_compute_pll(unsigned long clkin, int phy, -+ int n, struct hdmi_pll_info *pi) -+{ -+ unsigned long refclk; -+ u32 mf; -+ -+ /* -+ * Input clock is predivided by N + 1 -+ * out put of which is reference clk -+ */ -+ refclk = clkin / (n + 1); -+ pi->regn = n; -+ -+ /* -+ * multiplier is pixel_clk/ref_clk -+ * Multiplying by 100 to avoid fractional part removal -+ */ -+ pi->regm = (phy * 100/(refclk))/100; -+ pi->regm2 = 1; -+ -+ /* -+ * fractional multiplier is remainder of the difference between -+ * multiplier and actual phy(required pixel clock thus should be -+ * multiplied by 218(262144) divided by the reference clock -+ */ -+ mf = (phy - pi->regm * refclk) * 262144; -+ pi->regmf = mf/(refclk); -+ -+ /* -+ * Dcofreq should be set to 1 if required pixel clock -+ * is greater than 1000MHz -+ */ -+ pi->dcofreq = phy > 1000 * 100; -+ pi->regsd = ((pi->regm * clkin / 10) / ((n + 1) * 250) + 5) / 10; -+ -+ DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); -+ DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); -+} -+ -+static void hdmi_enable_clocks(int enable) -+{ -+ if (enable) -+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | -+ DSS_CLK_SYSCK | DSS_CLK_VIDFCK); -+ else -+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | -+ DSS_CLK_SYSCK | DSS_CLK_VIDFCK); -+} -+ -+static int hdmi_power_on(struct omap_dss_device *dssdev) -+{ -+ int r, code = 0; -+ struct hdmi_pll_info pll_data; -+ struct omap_video_timings *p; -+ int clkin, n, phy; -+ -+ hdmi_enable_clocks(1); -+ -+ dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); -+ -+ p = &dssdev->panel.timings; -+ -+ DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", -+ dssdev->panel.timings.x_res, -+ dssdev->panel.timings.y_res); -+ -+ if (!hdmi.custom_set) { -+ DSSDBG("Read EDID as no EDID is not set on poweron\n"); -+ hdmi_read_edid(p); -+ } -+ code = get_timings_index(); -+ dssdev->panel.timings = cea_vesa_timings[code].timings; -+ update_hdmi_timings(&hdmi.cfg, p, code); -+ -+ clkin = 3840; /* 38.4 MHz */ -+ n = 15; /* this is a constant for our math */ -+ phy = p->pixel_clock; -+ -+ hdmi_compute_pll(clkin, phy, n, &pll_data); -+ -+ hdmi_wp_video_start(0); -+ -+ /* config the PLL and PHY first */ -+ r = hdmi_pll_program(&pll_data); -+ if (r) { -+ DSSDBG("Failed to lock PLL\n"); -+ goto err; -+ } -+ -+ r = hdmi_phy_init(); -+ if (r) { -+ DSSDBG("Failed to start PHY\n"); -+ goto err; -+ } -+ -+ hdmi.cfg.cm.mode = hdmi.mode; -+ hdmi.cfg.cm.code = hdmi.code; -+ hdmi_basic_configure(&hdmi.cfg); -+ -+ /* Make selection of HDMI in DSS */ -+ dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); -+ -+ /* Select the dispc clock source as PRCM clock, to ensure that it is not -+ * DSI PLL source as the clock selected by DSI PLL might not be -+ * sufficient for the resolution selected / that can be changed -+ * dynamically by user. This can be moved to single location , say -+ * Boardfile. -+ */ -+ dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); -+ -+ /* bypass TV gamma table */ -+ dispc_enable_gamma_table(0); -+ -+ /* tv size */ -+ dispc_set_digit_size(dssdev->panel.timings.x_res, -+ dssdev->panel.timings.y_res); -+ -+ dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 1); -+ -+ hdmi_wp_video_start(1); -+ -+ return 0; -+err: -+ hdmi_enable_clocks(0); -+ return -EIO; -+} -+ -+static void hdmi_power_off(struct omap_dss_device *dssdev) -+{ -+ dispc_enable_channel(OMAP_DSS_CHANNEL_DIGIT, 0); -+ -+ hdmi_wp_video_start(0); -+ hdmi_phy_off(); -+ hdmi_set_pll_pwr(HDMI_PLLPWRCMD_ALLOFF); -+ hdmi_enable_clocks(0); -+ -+ hdmi.edid_set = 0; -+} -+ -+int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ struct hdmi_cm cm; -+ -+ cm = hdmi_get_code(timings); -+ if (cm.code == -1) { -+ DSSERR("Invalid timing entered\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+ -+} -+ -+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) -+{ -+ struct hdmi_cm cm; -+ -+ hdmi.custom_set = 1; -+ cm = hdmi_get_code(&dssdev->panel.timings); -+ hdmi.code = cm.code; -+ hdmi.mode = cm.mode; -+ omapdss_hdmi_display_enable(dssdev); -+ hdmi.custom_set = 0; -+} -+ -+int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ -+ DSSDBG("ENTER hdmi_display_enable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ r = omap_dss_start_device(dssdev); -+ if (r) { -+ DSSERR("failed to start device\n"); -+ goto err0; -+ } -+ -+ if (dssdev->platform_enable) { -+ r = dssdev->platform_enable(dssdev); -+ if (r) { -+ DSSERR("failed to enable GPIO's\n"); -+ goto err1; -+ } -+ } -+ -+ r = hdmi_power_on(dssdev); -+ if (r) { -+ DSSERR("failed to power on device\n"); -+ goto err2; -+ } -+ -+ mutex_unlock(&hdmi.lock); -+ return 0; -+ -+err2: -+ if (dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+err1: -+ omap_dss_stop_device(dssdev); -+err0: -+ mutex_unlock(&hdmi.lock); -+ return r; -+} -+ -+void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("Enter hdmi_display_disable\n"); -+ -+ mutex_lock(&hdmi.lock); -+ -+ hdmi_power_off(dssdev); -+ -+ if (dssdev->platform_disable) -+ dssdev->platform_disable(dssdev); -+ -+ omap_dss_stop_device(dssdev); -+ -+ mutex_unlock(&hdmi.lock); -+} -+ -+/* HDMI HW IP initialisation */ -+static int omapdss_hdmihw_probe(struct platform_device *pdev) -+{ -+ struct resource *hdmi_mem; -+ -+ hdmi.pdata = pdev->dev.platform_data; -+ hdmi.pdev = pdev; -+ -+ mutex_init(&hdmi.lock); -+ -+ hdmi_mem = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); -+ if (!hdmi_mem) { -+ DSSERR("can't get IORESOURCE_MEM HDMI\n"); -+ return -EINVAL; -+ } -+ -+ /* Base address taken from platform */ -+ hdmi.base_wp = ioremap(hdmi_mem->start, resource_size(hdmi_mem)); -+ if (!hdmi.base_wp) { -+ DSSERR("can't ioremap WP\n"); -+ return -ENOMEM; -+ } -+ -+ hdmi_panel_init(); -+ -+ return 0; -+} -+ -+static int omapdss_hdmihw_remove(struct platform_device *pdev) -+{ -+ hdmi_panel_exit(); -+ -+ iounmap(hdmi.base_wp); -+ -+ return 0; -+} -+ -+static struct platform_driver omapdss_hdmihw_driver = { -+ .probe = omapdss_hdmihw_probe, -+ .remove = omapdss_hdmihw_remove, -+ .driver = { -+ .name = "omapdss_hdmi", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int hdmi_init_platform_driver(void) -+{ -+ return platform_driver_register(&omapdss_hdmihw_driver); -+} -+ -+void hdmi_uninit_platform_driver(void) -+{ -+ return platform_driver_unregister(&omapdss_hdmihw_driver); -+} --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-306-V5_HDMI_panel_driver_addition_in_the_DSS.patch b/packages/linux/patches/linux-2.6.38-rc8-306-V5_HDMI_panel_driver_addition_in_the_DSS.patch deleted file mode 100644 index 8d2cdcc739..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-306-V5_HDMI_panel_driver_addition_in_the_DSS.patch +++ /dev/null @@ -1,252 +0,0 @@ -The panel driver(hdmi_omap4_panel.c) in omap2/dss acts as a controller -to manage the enable and disable requests and synchronize audio and video. - -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/dss.h | 2 + - drivers/video/omap2/dss/hdmi_omap4_panel.c | 222 ++++++++++++++++++++++++++++ - 2 files changed, 224 insertions(+), 0 deletions(-) - create mode 100644 drivers/video/omap2/dss/hdmi_omap4_panel.c - -diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h -index 6bf923c..05ccd00 100644 ---- a/drivers/video/omap2/dss/dss.h -+++ b/drivers/video/omap2/dss/dss.h -@@ -483,6 +483,8 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); - void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev); - int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, - struct omap_video_timings *timings); -+int hdmi_panel_init(void); -+void hdmi_panel_exit(void); - - /* RFBI */ - #ifdef CONFIG_OMAP2_DSS_RFBI -diff --git a/drivers/video/omap2/dss/hdmi_omap4_panel.c b/drivers/video/omap2/dss/hdmi_omap4_panel.c -new file mode 100644 -index 0000000..ffb5de9 ---- /dev/null -+++ b/drivers/video/omap2/dss/hdmi_omap4_panel.c -@@ -0,0 +1,222 @@ -+/* -+ * hdmi_omap4_panel.c -+ * -+ * HDMI library support functions for TI OMAP4 processors. -+ * -+ * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ -+ * Authors: Mythri P k -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published by -+ * the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -+ * more details. -+ * -+ * You should have received a copy of the GNU General Public License along with -+ * this program. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "dss.h" -+ -+static struct { -+ struct mutex hdmi_lock; -+} hdmi; -+ -+ -+static int hdmi_panel_probe(struct omap_dss_device *dssdev) -+{ -+ DSSDBG("ENTER hdmi_panel_probe\n"); -+ -+ dssdev->panel.config = OMAP_DSS_LCD_TFT | -+ OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; -+ -+ /* -+ * Initialize the timings to 640 * 480 -+ * This is only for framebuffer update not for TV timing setting -+ * Setting TV timing will be done only on enable -+ */ -+ dssdev->panel.timings.x_res = 640; -+ dssdev->panel.timings.y_res = 480; -+ -+ DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n", -+ dssdev->panel.timings.x_res, -+ dssdev->panel.timings.y_res); -+ return 0; -+} -+ -+static void hdmi_panel_remove(struct omap_dss_device *dssdev) -+{ -+ -+} -+ -+static int hdmi_panel_enable(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ DSSDBG("ENTER hdmi_panel_enable\n"); -+ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { -+ r = -EINVAL; -+ goto err; -+ } -+ -+ r = omapdss_hdmi_display_enable(dssdev); -+ if (r) { -+ DSSERR("failed to power on\n"); -+ goto err; -+ } -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+err: -+ mutex_unlock(&hdmi.hdmi_lock); -+ -+ return r; -+} -+ -+static void hdmi_panel_disable(struct omap_dss_device *dssdev) -+{ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) -+ omapdss_hdmi_display_disable(dssdev); -+ -+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -+ -+ mutex_unlock(&hdmi.hdmi_lock); -+} -+ -+static int hdmi_panel_suspend(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { -+ r = -EINVAL; -+ goto err; -+ } -+ -+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; -+ -+ omapdss_hdmi_display_disable(dssdev); -+ -+err: -+ mutex_unlock(&hdmi.hdmi_lock); -+ -+ return r; -+} -+ -+static int hdmi_panel_resume(struct omap_dss_device *dssdev) -+{ -+ int r = 0; -+ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { -+ r = -EINVAL; -+ goto err; -+ } -+ -+ r = omapdss_hdmi_display_enable(dssdev); -+ if (r) { -+ DSSERR("failed to power on\n"); -+ goto err; -+ } -+ -+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; -+ -+err: -+ mutex_unlock(&hdmi.hdmi_lock); -+ -+ return r; -+} -+ -+static void hdmi_get_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ *timings = dssdev->panel.timings; -+ -+ mutex_unlock(&hdmi.hdmi_lock); -+} -+ -+static void hdmi_set_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ DSSDBG("hdmi_set_timings\n"); -+ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ dssdev->panel.timings = *timings; -+ -+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { -+ /* turn the hdmi off and on to get new timings to use */ -+ omapdss_hdmi_display_disable(dssdev); -+ omapdss_hdmi_display_set_timing(dssdev); -+ } -+ -+ mutex_unlock(&hdmi.hdmi_lock); -+} -+ -+static int hdmi_check_timings(struct omap_dss_device *dssdev, -+ struct omap_video_timings *timings) -+{ -+ int r = 0; -+ -+ DSSDBG("hdmi_check_timings\n"); -+ -+ mutex_lock(&hdmi.hdmi_lock); -+ -+ r = omapdss_hdmi_display_check_timing(dssdev, timings); -+ if (r) { -+ DSSERR("Timing cannot be applied\n"); -+ goto err; -+ } -+err: -+ mutex_unlock(&hdmi.hdmi_lock); -+ return r; -+} -+ -+static struct omap_dss_driver hdmi_driver = { -+ .probe = hdmi_panel_probe, -+ .remove = hdmi_panel_remove, -+ .enable = hdmi_panel_enable, -+ .disable = hdmi_panel_disable, -+ .suspend = hdmi_panel_suspend, -+ .resume = hdmi_panel_resume, -+ .get_timings = hdmi_get_timings, -+ .set_timings = hdmi_set_timings, -+ .check_timings = hdmi_check_timings, -+ .driver = { -+ .name = "hdmi_panel", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+int hdmi_panel_init(void) -+{ -+ mutex_init(&hdmi.hdmi_lock); -+ -+ omap_dss_register_driver(&hdmi_driver); -+ -+ return 0; -+} -+ -+void hdmi_panel_exit(void) -+{ -+ omap_dss_unregister_driver(&hdmi_driver); -+ -+} --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-307-V5_Add_makefile_and_kconfig_changes_to_enable_HDMI_in_OMAP4.patch b/packages/linux/patches/linux-2.6.38-rc8-307-V5_Add_makefile_and_kconfig_changes_to_enable_HDMI_in_OMAP4.patch deleted file mode 100644 index f95348bc66..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-307-V5_Add_makefile_and_kconfig_changes_to_enable_HDMI_in_OMAP4.patch +++ /dev/null @@ -1,36 +0,0 @@ -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/Kconfig | 8 ++++++++ - drivers/video/omap2/dss/Makefile | 2 ++ - 2 files changed, 10 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig -index db01473..bfc5da0 100644 ---- a/drivers/video/omap2/dss/Kconfig -+++ b/drivers/video/omap2/dss/Kconfig -@@ -60,6 +60,14 @@ config OMAP2_DSS_VENC - help - OMAP Video Encoder support for S-Video and composite TV-out. - -+config OMAP4_DSS_HDMI -+ bool "HDMI support" -+ depends on ARCH_OMAP4 -+ default y -+ help -+ HDMI Interface. This adds the High Definition Multimedia Interface. -+ See http://www.hdmi.org/ for HDMI specification. -+ - config OMAP2_DSS_SDI - bool "SDI support" - depends on ARCH_OMAP3 -diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile -index 7db17b5..10d9d3b 100644 ---- a/drivers/video/omap2/dss/Makefile -+++ b/drivers/video/omap2/dss/Makefile -@@ -5,3 +5,5 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o - omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o - omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o - omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o -+omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \ -+ hdmi_omap4_panel.o --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-308-V5_Call_to_HDMI_module_init_to_register_driver.patch b/packages/linux/patches/linux-2.6.38-rc8-308-V5_Call_to_HDMI_module_init_to_register_driver.patch deleted file mode 100644 index 75ca4de0c8..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-308-V5_Call_to_HDMI_module_init_to_register_driver.patch +++ /dev/null @@ -1,43 +0,0 @@ -calling the platform registration of HDMI driver from core -during initialization. - -Signed-off-by: Mythri P K ---- - drivers/video/omap2/dss/core.c | 9 +++++++++ - 1 files changed, 9 insertions(+), 0 deletions(-) - -diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c -index c2f930b..1aa2ed1 100644 ---- a/drivers/video/omap2/dss/core.c -+++ b/drivers/video/omap2/dss/core.c -@@ -209,6 +209,12 @@ static int omap_dss_probe(struct platform_device *pdev) - goto err_dsi; - } - -+ r = hdmi_init_platform_driver(); -+ if (r) { -+ DSSERR("Failed to initialize hdmi\n"); -+ goto err_hdmi; -+ } -+ - r = dss_initialize_debugfs(); - if (r) - goto err_debugfs; -@@ -238,6 +244,8 @@ static int omap_dss_probe(struct platform_device *pdev) - err_register: - dss_uninitialize_debugfs(); - err_debugfs: -+ hdmi_uninit_platform_driver(); -+err_hdmi: - dsi_uninit_platform_driver(); - err_dsi: - venc_uninit_platform_driver(); -@@ -263,6 +271,7 @@ static int omap_dss_remove(struct platform_device *pdev) - dispc_uninit_platform_driver(); - rfbi_uninit_platform_driver(); - dsi_uninit_platform_driver(); -+ hdmi_uninit_platform_driver(); - dss_uninit_platform_driver(); - - dss_uninit_overlays(pdev); --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-309-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4_SDP.patch b/packages/linux/patches/linux-2.6.38-rc8-309-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4_SDP.patch deleted file mode 100644 index 491cc89a66..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-309-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4_SDP.patch +++ /dev/null @@ -1,118 +0,0 @@ -Adding board file structure for display which adds the display -structure with HDMI as the default driver when the display init -is called. -HDMI GPIO configurations are also done in this file. - -Signed-off-by: Mythri P K ---- - arch/arm/mach-omap2/board-4430sdp.c | 75 +++++++++++++++++++++++++++++++++++ - 1 files changed, 75 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c -index 85805d4..f5fcc5f 100644 ---- a/arch/arm/mach-omap2/board-4430sdp.c -+++ b/arch/arm/mach-omap2/board-4430sdp.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include "mux.h" - #include "hsmmc.h" -@@ -47,6 +48,8 @@ - #define ETH_KS8851_QUART 138 - #define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 - #define OMAP4_SFH7741_ENABLE_GPIO 188 -+#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ -+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ - - static const int sdp4430_keymap[] = { - KEY(0, 0, KEY_E), -@@ -620,6 +623,76 @@ static void __init omap_sfh7741prox_init(void) - } - } - -+static void sdp4430_hdmi_mux_init(void) -+{ -+ /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ -+ omap_mux_init_signal("hdmi_hpd", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("hdmi_cec", -+ OMAP_PIN_INPUT_PULLUP); -+ /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ -+ omap_mux_init_signal("hdmi_ddc_scl", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("hdmi_ddc_sda", -+ OMAP_PIN_INPUT_PULLUP); -+} -+ -+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) -+{ -+ int status; -+ -+ status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, -+ "hdmi_gpio_hpd"); -+ if (status) { -+ pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD); -+ return status; -+ } -+ status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, -+ "hdmi_gpio_ls_oe"); -+ if (status) { -+ pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE); -+ goto error1; -+ } -+ -+ return 0; -+ -+error1: -+ gpio_free(HDMI_GPIO_HPD); -+ -+ return status; -+} -+ -+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) -+{ -+ gpio_free(HDMI_GPIO_LS_OE); -+ gpio_free(HDMI_GPIO_HPD); -+} -+ -+static struct omap_dss_device sdp4430_hdmi_device = { -+ .name = "hdmi", -+ .driver_name = "hdmi_panel", -+ .type = OMAP_DISPLAY_TYPE_HDMI, -+ .platform_enable = sdp4430_panel_enable_hdmi, -+ .platform_disable = sdp4430_panel_disable_hdmi, -+ .channel = OMAP_DSS_CHANNEL_DIGIT, -+}; -+ -+static struct omap_dss_device *sdp4430_dss_devices[] = { -+ &sdp4430_hdmi_device, -+}; -+ -+static struct omap_dss_board_info sdp4430_dss_data = { -+ .num_devices = ARRAY_SIZE(sdp4430_dss_devices), -+ .devices = sdp4430_dss_devices, -+ .default_device = &sdp4430_hdmi_device, -+}; -+ -+void omap_4430sdp_display_init(void) -+{ -+ sdp4430_hdmi_mux_init(); -+ omap_display_init(&sdp4430_dss_data); -+} -+ - #ifdef CONFIG_OMAP_MUX - static struct omap_board_mux board_mux[] __initdata = { - OMAP4_MUX(USBB2_ULPITLL_CLK, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), -@@ -661,6 +734,8 @@ static void __init omap_4430sdp_init(void) - status = omap4_keyboard_init(&sdp4430_keypad_data); - if (status) - pr_err("Keypad initialization failed: %d\n", status); -+ -+ omap_4430sdp_display_init(); - } - - static void __init omap_4430sdp_map_io(void) --- 1.5.6.3 diff --git a/packages/linux/patches/linux-2.6.38-rc8-310-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4__PANDA.patch b/packages/linux/patches/linux-2.6.38-rc8-310-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4__PANDA.patch deleted file mode 100644 index 9c4b26ec9e..0000000000 --- a/packages/linux/patches/linux-2.6.38-rc8-310-V5_Add_HDMI_structure_in_the_board_file_for_OMAP4__PANDA.patch +++ /dev/null @@ -1,117 +0,0 @@ -Adding board file structure for display which adds the display -structure with HDMI as the default driver when the display init -is called. -HDMI GPIO configurations are also done in this file. - -Signed-off-by: Mythri P K ---- - arch/arm/mach-omap2/board-omap4panda.c | 74 ++++++++++++++++++++++++++++++++ - 1 files changed, 74 insertions(+), 0 deletions(-) - -diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c -index a94ce07..4869c0f 100644 ---- a/arch/arm/mach-omap2/board-omap4panda.c -+++ b/arch/arm/mach-omap2/board-omap4panda.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -49,6 +50,8 @@ - #define GPIO_HUB_NRESET 62 - #define GPIO_WIFI_PMENA 43 - #define GPIO_WIFI_IRQ 53 -+#define HDMI_GPIO_HPD 60 /* Hot plug pin for HDMI */ -+#define HDMI_GPIO_LS_OE 41 /* Level shifter for HDMI */ - - /* wl127x BT, FM, GPS connectivity chip */ - static int wl1271_gpios[] = {46, -1, -1}; -@@ -467,6 +470,76 @@ static struct omap_board_mux board_mux[] __initdata = { - #define board_mux NULL - #endif - -+static void sdp4430_hdmi_mux_init(void) -+{ -+ /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */ -+ omap_mux_init_signal("hdmi_hpd", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("hdmi_cec", -+ OMAP_PIN_INPUT_PULLUP); -+ /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */ -+ omap_mux_init_signal("hdmi_ddc_scl", -+ OMAP_PIN_INPUT_PULLUP); -+ omap_mux_init_signal("hdmi_ddc_sda", -+ OMAP_PIN_INPUT_PULLUP); -+} -+ -+static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev) -+{ -+ int status; -+ -+ status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, -+ "hdmi_gpio_hpd"); -+ if (status) { -+ pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD); -+ return status; -+ } -+ status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, -+ "hdmi_gpio_ls_oe"); -+ if (status) { -+ pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE); -+ goto error1; -+ } -+ -+ return 0; -+ -+error1: -+ gpio_free(HDMI_GPIO_HPD); -+ -+ return status; -+} -+ -+static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev) -+{ -+ gpio_free(HDMI_GPIO_LS_OE); -+ gpio_free(HDMI_GPIO_HPD); -+} -+ -+static struct omap_dss_device sdp4430_hdmi_device = { -+ .name = "hdmi", -+ .driver_name = "hdmi_panel", -+ .type = OMAP_DISPLAY_TYPE_HDMI, -+ .platform_enable = sdp4430_panel_enable_hdmi, -+ .platform_disable = sdp4430_panel_disable_hdmi, -+ .channel = OMAP_DSS_CHANNEL_DIGIT, -+}; -+ -+static struct omap_dss_device *sdp4430_dss_devices[] = { -+ &sdp4430_hdmi_device, -+}; -+ -+static struct omap_dss_board_info sdp4430_dss_data = { -+ .num_devices = ARRAY_SIZE(sdp4430_dss_devices), -+ .devices = sdp4430_dss_devices, -+ .default_device = &sdp4430_hdmi_device, -+}; -+ -+void omap_panda_display_init(void) -+{ -+ sdp4430_hdmi_mux_init(); -+ omap_display_init(&sdp4430_dss_data); -+} -+ - static void __init omap4_panda_init(void) - { - int package = OMAP_PACKAGE_CBS; -@@ -485,6 +558,7 @@ static void __init omap4_panda_init(void) - omap4_twl6030_hsmmc_init(mmc); - omap4_ehci_init(); - usb_musb_init(&musb_board_data); -+ omap_panda_display_init(); - } - - static void __init omap4_panda_map_io(void) --- 1.5.6.3 diff --git a/packages/network/connman/meta b/packages/network/connman/meta index b4961b6136..b8fa628ca2 100644 --- a/packages/network/connman/meta +++ b/packages/network/connman/meta @@ -19,13 +19,13 @@ ################################################################################ PKG_NAME="connman" -PKG_VERSION="3634185" +PKG_VERSION="0.71" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.connman.net" -#PKG_URL="http://www.kernel.org/pub/linux/network/connman/$PKG_NAME-$PKG_VERSION.tar.bz2" -PKG_URL="$OPENELEC_SRC/$PKG_NAME-$PKG_VERSION.tar.bz2" +PKG_URL="http://www.kernel.org/pub/linux/network/connman/$PKG_NAME-$PKG_VERSION.tar.bz2" +#PKG_URL="$OPENELEC_SRC/$PKG_NAME-$PKG_VERSION.tar.bz2" PKG_DEPENDS="glib dbus udev iptables wpa_supplicant ntp netstatus" PKG_BUILD_DEPENDS="toolchain glib dbus udev iptables" PKG_PRIORITY="optional" diff --git a/packages/network/samba/config/smb.conf b/packages/network/samba/config/smb.conf index a5784365bf..d52f351f78 100644 --- a/packages/network/samba/config/smb.conf +++ b/packages/network/samba/config/smb.conf @@ -126,6 +126,14 @@ writable = yes root preexec = mkdir -p /storage/screenshots +[Media] + path = /media + available = yes + browsable = yes + public = yes + writable = yes + root preexec = mkdir -p /media + [Logfiles] path = /storage/logfiles available = yes diff --git a/packages/other/enca/install b/packages/other/enca/install index 6a597fbd62..cf638e84d4 100755 --- a/packages/other/enca/install +++ b/packages/other/enca/install @@ -23,5 +23,5 @@ . config/options $1 mkdir -p $INSTALL/usr/lib - cp $PKG_BUILD/lib/.libs/*.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/lib/.libs/*.so* $INSTALL/usr/lib diff --git a/packages/security/gnutls/install b/packages/security/gnutls/install index ee8d975151..baec342186 100755 --- a/packages/security/gnutls/install +++ b/packages/security/gnutls/install @@ -23,5 +23,10 @@ . config/options mkdir -p $INSTALL/usr/lib - cp -P $PKG_BUILD/lib/.libs/*.so* $INSTALL/usr/lib - cp -P $PKG_BUILD/libextra/.libs/*.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/lib/.libs/libgnutls.so* $INSTALL/usr/lib + cp -P $PKG_BUILD/lib/.libs/libgnutlsxx.so* $INSTALL/usr/lib + rm -rf $INSTALL/usr/lib/libgnutlsxx.so*T + cp -P $PKG_BUILD/libextra/.libs/libgnutls-extra.so* $INSTALL/usr/lib + rm -rf $INSTALL/usr/lib/libgnutls-extra.so*T + cp -P $PKG_BUILD/libextra/.libs/libgnutls-openssl.so* $INSTALL/usr/lib + rm -rf $INSTALL/usr/lib/libgnutls-openssl.so*T diff --git a/packages/toolchain/devel/binutils/build b/packages/toolchain/devel/binutils/build index 4d8c0d5de9..ebe6e469e1 100755 --- a/packages/toolchain/devel/binutils/build +++ b/packages/toolchain/devel/binutils/build @@ -52,7 +52,7 @@ mkdir -p objdir && cd objdir --enable-version-specific-runtime-libs \ $WITH_64B_BFD \ --enable-plugins \ - --enable-gold \ + --enable-gold=yes \ --enable-ld=default \ --enable-lto \ --disable-nls diff --git a/packages/toolchain/devel/binutils/meta b/packages/toolchain/devel/binutils/meta index 9fd0df27d8..d858800b64 100644 --- a/packages/toolchain/devel/binutils/meta +++ b/packages/toolchain/devel/binutils/meta @@ -19,13 +19,13 @@ ################################################################################ PKG_NAME="binutils" -PKG_VERSION="2.21" +PKG_VERSION="2.21.51.0.7" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" PKG_SITE="http://www.gnu.org/software/binutils/binutils.html" -PKG_URL="http://ftp.gnu.org/gnu/binutils/$PKG_NAME-$PKG_VERSION.tar.bz2" -#PKG_URL="ftp://ftp.kernel.org/pub/linux/devel/binutils/$PKG_NAME-$PKG_VERSION.tar.bz2" +#PKG_URL="http://ftp.gnu.org/gnu/binutils/$PKG_NAME-$PKG_VERSION.tar.bz2" +PKG_URL="ftp://ftp.kernel.org/pub/linux/devel/binutils/$PKG_NAME-$PKG_VERSION.tar.bz2" PKG_DEPENDS="" PKG_BUILD_DEPENDS="ccache linux-headers gmp mpfr ppl cloog-ppl libelf" PKG_PRIORITY="optional" diff --git a/packages/toolchain/devel/binutils/patches/binutils-2.21-multi_os_directory.patch b/packages/toolchain/devel/binutils/patches/binutils-2.21.51.0.7-multi_os_directory.patch similarity index 100% rename from packages/toolchain/devel/binutils/patches/binutils-2.21-multi_os_directory.patch rename to packages/toolchain/devel/binutils/patches/binutils-2.21.51.0.7-multi_os_directory.patch diff --git a/packages/toolchain/devel/binutils/patches/binutils-2.21-visibility.patch b/packages/toolchain/devel/binutils/patches/binutils-2.21.51.0.7-visibility.patch similarity index 100% rename from packages/toolchain/devel/binutils/patches/binutils-2.21-visibility.patch rename to packages/toolchain/devel/binutils/patches/binutils-2.21.51.0.7-visibility.patch diff --git a/packages/toolchain/devel/eglibc/build b/packages/toolchain/devel/eglibc/build index 62f4dabea4..882b8a59dc 100755 --- a/packages/toolchain/devel/eglibc/build +++ b/packages/toolchain/devel/eglibc/build @@ -26,7 +26,8 @@ strip_lto # Fails to compile with GCC's link time optimization. strip_gold # Fails to compile using the gold linker. # Filter out some problematic CFLAGS - CFLAGS=`echo $CFLAGS | sed -e "s|-ffast-math||" -e "s|-O.|-O2|"` + CFLAGS=`echo $CFLAGS | sed -e "s|-ffast-math||"` + CFLAGS=`echo $CFLAGS | sed -e "s|-O.|-O2|"` # set some CFLAGS we need CFLAGS="$CFLAGS -g -fno-stack-protector" @@ -114,7 +115,7 @@ EOF --enable-bind-now \ --with-elf \ --with-tls \ - --enable-kernel=2.6.37 \ + --enable-kernel=2.6.35 \ --with-__thread \ --with-binutils=$BUILD/toolchain/bin \ --with-headers=$SYSROOT_PREFIX/usr/include \ diff --git a/packages/toolchain/devel/eglibc/meta b/packages/toolchain/devel/eglibc/meta index 22e7bc22b9..b8f933ac94 100644 --- a/packages/toolchain/devel/eglibc/meta +++ b/packages/toolchain/devel/eglibc/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="eglibc" -PKG_VERSION="2.12-12750" +PKG_VERSION="2.13-13177" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="GPL" diff --git a/packages/toolchain/devel/eglibc/patches/eglibc-2.12-12750-libgcc_eh-1.patch b/packages/toolchain/devel/eglibc/patches/eglibc-2.13-13177-libgcc_eh-1.patch similarity index 100% rename from packages/toolchain/devel/eglibc/patches/eglibc-2.12-12750-libgcc_eh-1.patch rename to packages/toolchain/devel/eglibc/patches/eglibc-2.13-13177-libgcc_eh-1.patch diff --git a/packages/toolchain/devel/eglibc/patches/eglibc-2.12-12750-select_fd_type.patch b/packages/toolchain/devel/eglibc/patches/eglibc-2.13-13177-select_fd_type.patch similarity index 100% rename from packages/toolchain/devel/eglibc/patches/eglibc-2.12-12750-select_fd_type.patch rename to packages/toolchain/devel/eglibc/patches/eglibc-2.13-13177-select_fd_type.patch diff --git a/packages/tools/installer/scripts/installer b/packages/tools/installer/scripts/installer old mode 100755 new mode 100644 index 36fc9cfdcf..9d0eff4f2c --- a/packages/tools/installer/scripts/installer +++ b/packages/tools/installer/scripts/installer @@ -137,7 +137,7 @@ do_install_mbr() { # show menu MSG_TITLE="\Z4[ (RE)INSTALL MBR ]\Zn" - MSG_MENU="\n Please select the Device to install MBR\n\n Please choose an item:" + MSG_MENU="\n Please select where to install MBR.\n\n Please select a device:" MSG_CANCEL="Back" create_device_list @@ -169,7 +169,7 @@ do_install_quick() { # show menu MSG_TITLE="\Z4[ QUICK INSTALL MENU ]\Zn" - MSG_MENU="\n You can use the UP/DOWN arrow keys,\n the No. of the choice as a hot key,\n to choose an option.\n\n Please choose an item:" + MSG_MENU="\n You can use the UP/DOWN arrow keys,\n or the number of the choice as a hotkey,\n to choose an option.\n\n Please select a device:" MSG_CANCEL="Back" create_device_list @@ -195,7 +195,7 @@ do_install_quick() { msg_progress_install "7" "creating label on $INSTALL_DEVICE" parted -s $INSTALL_DEVICE mklabel msdos >> $LOGFILE 2>&1 - msg_progress_install "9" "writing MBR on $INSTALL_DEVICE" + msg_progress_install "9" "writing Master Boot Record on $INSTALL_DEVICE" cat /usr/share/syslinux/mbr.bin > $INSTALL_DEVICE msg_progress_install "10" "creating partition on $INSTALL_DEVICE" @@ -207,7 +207,7 @@ do_install_quick() { msg_progress_install "16" "setup bootflag on partition 1 of $INSTALL_DEVICE" parted -s $INSTALL_DEVICE set 1 boot on >> $LOGFILE 2>&1 - msg_progress_install "20" "tell kernel we have a new partitiontable on $INSTALL_DEVICE" + msg_progress_install "20" "tell the kernel we have a new partitiontable on $INSTALL_DEVICE" partprobe $INSTALL_DEVICE >> $LOGFILE 2>&1 # create filesystem @@ -273,7 +273,7 @@ do_install_quick() { msg_not_implemented() { # show an dialog that this function is not yet implemented MSG_TITLE="\Z2[ WORK IN PROGRESS ]\Zn" - MSG_INFOBOX=" This function is not yet implemented \n stay tuned!!!" + MSG_INFOBOX=" This function is not implemented yet." dialog --colors --backtitle "$BACKTITLE" --title "$MSG_TITLE" --msgbox "$MSG_INFOBOX" 7 70 } @@ -281,7 +281,7 @@ msg_not_implemented() { msg_oem_only() { # show an dialog that this function is only implemented on special builds MSG_TITLE="\Z2[ FOR OEM ONLY ]\Zn" - MSG_INFOBOX=" OEM only feature, this function is not implemented in this build! \n if you have questions about this feature \n visit http://www.openelec.tv!!!" + MSG_INFOBOX=" OEM only feature, this function is not implemented in this build. \n if you have questions about this feature \n visit http://www.openelec.tv" dialog --colors --backtitle "$BACKTITLE" --title "$MSG_TITLE" --msgbox "$MSG_INFOBOX" 7 70 } @@ -289,15 +289,15 @@ msg_oem_only() { msg_warning_beta() { # show an warning dialog if we use beta software MSG_TITLE="\Z1[ BETA WARNING ]\Zn" - MSG_INFOBOX=" This installer is Beta \n use it on your own risk!!! \n Please make first an backup !" + MSG_INFOBOX=" This installer is for beta versions. \n This means this sofware have not been tested yet. \n Please make sure you have a backup of \n your files before going any further." dialog --colors --backtitle "$BACKTITLE" --title "$MSG_TITLE" --msgbox "$MSG_INFOBOX" 7 70 } msg_no_device() { # show an warning dialog if we dont find not mounted devices for install and return to main menu - MSG_TITLE="\Z1[ INFORMATION ]\Zn" - MSG_INFOBOX=" Not found any devices to install. \n be sure you have connected your device via USB or (e)SATA. \n Please try again !" + MSG_TITLE="\Z1[ WARNING ]\Zn" + MSG_INFOBOX=" No devices were found. \n If you are trying to install on a \n brand new harddisk you must create atleast \n one partition. Otherwise it won't be found. \n If you dont know how, ask in the forum or on IRC." dialog --colors --backtitle "$BACKTITLE" --title "$MSG_TITLE" --msgbox "$MSG_INFOBOX" 7 70 @@ -336,8 +336,8 @@ menu_main() { dialog --colors --backtitle "$BACKTITLE" --cancel-label "$MSG_CANCEL" \ --title "$MSG_TITLE" --menu "$MSG_MENU" 20 70 5 \ - 1 "Quick Install OpenELEC" \ - 2 "Custom Install OpenELEC" \ + 1 "Quick Install of OpenELEC" \ + 2 "Custom Install of OpenELEC" \ 3 "Setup OpenELEC" \ 4 "BIOS update (only for OEM's)" \ 5 "Show logfile" 2> $TMPDIR/mainmenu @@ -371,7 +371,7 @@ menu_setup() { menu_bios() { # show the biosmenu MSG_TITLE="\Z4[ BIOS MENU ]\Zn" - MSG_MENU="\n You can use the UP/DOWN arrow keys,\n the No. of the choice as a hot key,\n to choose an option.\n\n Please choose an item:" + MSG_MENU="\n You can use the UP/DOWN arrow keys,\n or the number of the choice as a hotkey,\n to choose an option.\n\n Please choose a device:" MSG_CANCEL="Back" dialog --colors --backtitle "$BACKTITLE" --cancel-label "$MSG_CANCEL" \ diff --git a/packages/x11/driver/xf86-video-ati/meta b/packages/x11/driver/xf86-video-ati/meta index 005c1c721c..76eb96e907 100644 --- a/packages/x11/driver/xf86-video-ati/meta +++ b/packages/x11/driver/xf86-video-ati/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="xf86-video-ati" -PKG_VERSION="6.14.0" +PKG_VERSION="6.14.1" PKG_REV="1" PKG_ARCH="i386 x86_64" PKG_LICENSE="OSS" diff --git a/packages/x11/driver/xf86-video-ati/patches/xf86-video-ati-6.14.0-01-fix_build_with_xorg-server-1.10.patch b/packages/x11/driver/xf86-video-ati/patches/xf86-video-ati-6.14.0-01-fix_build_with_xorg-server-1.10.patch deleted file mode 100644 index 5b47bc05a3..0000000000 --- a/packages/x11/driver/xf86-video-ati/patches/xf86-video-ati-6.14.0-01-fix_build_with_xorg-server-1.10.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ecfdb209afe2aafc378baab8c511f5df7b000270 Mon Sep 17 00:00:00 2001 -From: Sedat Dilek -Date: Fri, 25 Feb 2011 20:48:14 +0000 -Subject: UMS: Fix build against xserver 1.10-rc3 - -This issue was introduced due to last minute backout of RandR-1.4 -in xserver 1.10-rc3. - -Switch to "#ifdef RANDR_14_INTERFACE" as suggested by Keith Packard. -See also . - -Note: -The ddx needs a rebuild as the X video driver ABI changed to version 10.0. - -Reported-by: Alex Deucher -CC: Keith Packard -Signed-off-by: Sedat Dilek ---- -diff --git a/src/radeon_output.c b/src/radeon_output.c -index 15cef06..ccde346 100644 ---- a/src/radeon_output.c -+++ b/src/radeon_output.c -@@ -1622,7 +1622,7 @@ radeon_set_mode_for_property(xf86OutputPtr output) - xf86CrtcPtr crtc = output->crtc; - - if (crtc->enabled) { --#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0) -+#ifdef RANDR_14_INTERFACE - xf86CrtcSetRec crtc_set_rec; - - crtc_set_rec.flags = (XF86CrtcSetMode | --- -cgit v0.8.3-6-g21f6 diff --git a/packages/x11/driver/xf86-video-omapfb/build b/packages/x11/driver/xf86-video-omapfb/build new file mode 100755 index 0000000000..4affb49796 --- /dev/null +++ b/packages/x11/driver/xf86-video-omapfb/build @@ -0,0 +1,41 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# 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, 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 OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options + +if [ "$TARGET_FPU" = neon -o "$TARGET_FPU" = neon-fp16 ]; then + CFG_NEON="--enable-neon" +else + CFG_NEON="--disable-neon" +fi + +cd $PKG_BUILD +./configure --host=$TARGET_NAME \ + --build=$HOST_NAME \ + --prefix=/usr \ + --sysconfdir=/etc \ + --disable-static \ + --enable-shared \ + --with-xorg-module-dir=$XORG_PATH_MODULES \ + $CFG_NEON \ + +make diff --git a/packages/x11/driver/xf86-video-omapfb/install b/packages/x11/driver/xf86-video-omapfb/install new file mode 100755 index 0000000000..ad33d54801 --- /dev/null +++ b/packages/x11/driver/xf86-video-omapfb/install @@ -0,0 +1,26 @@ +#!/bin/sh + +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# 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, 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 OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +. config/options + +mkdir -p $INSTALL/$XORG_PATH_MODULES/drivers + cp $PKG_BUILD/src/.libs/*_drv.so $INSTALL/$XORG_PATH_MODULES/drivers diff --git a/packages/x11/driver/xf86-video-omapfb/meta b/packages/x11/driver/xf86-video-omapfb/meta new file mode 100644 index 0000000000..cb7ecdb643 --- /dev/null +++ b/packages/x11/driver/xf86-video-omapfb/meta @@ -0,0 +1,36 @@ +################################################################################ +# This file is part of OpenELEC - http://www.openelec.tv +# Copyright (C) 2009-2011 Stephan Raue (stephan@openelec.tv) +# +# 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, 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 OpenELEC.tv; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +# http://www.gnu.org/copyleft/gpl.html +################################################################################ + +PKG_NAME="xf86-video-omapfb" +PKG_VERSION="0446176" +PKG_REV="1" +PKG_ARCH="arm" +PKG_LICENSE="OSS" +PKG_SITE="http://cgit.pingu.fi/xf86-video-omapfb" +PKG_URL="$OPENELEC_SRC/$PKG_NAME-$PKG_VERSION.tar.bz2" +PKG_DEPENDS="libXrender libXext libX11" +PKG_BUILD_DEPENDS="toolchain libXrender libXext xorg-server" +PKG_PRIORITY="optional" +PKG_SECTION="x11/driver" +PKG_SHORTDESC="xf86-video-ompafb: OMAP3/4 framebuffer display driver" +PKG_LONGDESC="This driver for the X.Org X server (see xserver-xorg for a further description) provides support for OMAP3/4 framebuffer devices." +PKG_IS_ADDON="no" + +PKG_AUTORECONF="yes" diff --git a/packages/x11/lib/libX11/meta b/packages/x11/lib/libX11/meta index 0d79783751..acaf430fa2 100644 --- a/packages/x11/lib/libX11/meta +++ b/packages/x11/lib/libX11/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="libX11" -PKG_VERSION="1.4.1" +PKG_VERSION="1.4.2" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="OSS" diff --git a/packages/x11/lib/libXi/meta b/packages/x11/lib/libXi/meta index 20bf5c8194..3d9e780cd0 100644 --- a/packages/x11/lib/libXi/meta +++ b/packages/x11/lib/libXi/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="libXi" -PKG_VERSION="1.4.1" +PKG_VERSION="1.4.2" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="OSS" diff --git a/packages/x11/util/util-macros/meta b/packages/x11/util/util-macros/meta index 70e998e812..9af195d62e 100644 --- a/packages/x11/util/util-macros/meta +++ b/packages/x11/util/util-macros/meta @@ -19,7 +19,7 @@ ################################################################################ PKG_NAME="util-macros" -PKG_VERSION="1.12.0" +PKG_VERSION="1.13.0" PKG_REV="1" PKG_ARCH="any" PKG_LICENSE="OSS" diff --git a/projects/ATV/options b/projects/ATV/options index fa368909e5..3df64087be 100644 --- a/projects/ATV/options +++ b/projects/ATV/options @@ -83,6 +83,14 @@ # Configuration for u-boot UBOOT_CONFIG="" +# Kernel to use. values can be: +# default: default mainline kernel +# ti-omap4: Ti's OMAP4 kernel + LINUX="default" + +# use linux-next (latest rc) instead latest released version + LINUX_NEXT="no" + # Mediacenter to use (xbmc / xbmc-pvr / no) MEDIACENTER="xbmc-pvr" diff --git a/projects/Generic/options b/projects/Generic/options index f4c183d30b..848f0e6294 100644 --- a/projects/Generic/options +++ b/projects/Generic/options @@ -83,6 +83,14 @@ # Configuration for u-boot UBOOT_CONFIG="" +# Kernel to use. values can be: +# default: default mainline kernel +# ti-omap4: Ti's OMAP4 kernel + LINUX="default" + +# use linux-next (latest rc) instead latest released version + LINUX_NEXT="no" + # Mediacenter to use (xbmc / xbmc-pvr / no) MEDIACENTER="xbmc-pvr" diff --git a/projects/ION/options b/projects/ION/options index 498ee472a7..69032d9596 100644 --- a/projects/ION/options +++ b/projects/ION/options @@ -83,6 +83,14 @@ # Configuration for u-boot UBOOT_CONFIG="" +# Kernel to use. values can be: +# default: default mainline kernel +# ti-omap4: Ti's OMAP4 kernel + LINUX="default" + +# use linux-next (latest rc) instead latest released version + LINUX_NEXT="no" + # Mediacenter to use (xbmc / xbmc-pvr / no) MEDIACENTER="xbmc-pvr" diff --git a/projects/Intel/options b/projects/Intel/options index 033c53b298..81dbfa2f72 100644 --- a/projects/Intel/options +++ b/projects/Intel/options @@ -83,6 +83,14 @@ # Configuration for u-boot UBOOT_CONFIG="" +# Kernel to use. values can be: +# default: default mainline kernel +# ti-omap4: Ti's OMAP4 kernel + LINUX="default" + +# use linux-next (latest rc) instead latest released version + LINUX_NEXT="no" + # Mediacenter to use (xbmc / xbmc-pvr / no) MEDIACENTER="xbmc-pvr" diff --git a/tools/mkpkg/mkpkg_libjpeg-turbo b/tools/mkpkg/mkpkg_eglibc-2.13 similarity index 67% rename from tools/mkpkg/mkpkg_libjpeg-turbo rename to tools/mkpkg/mkpkg_eglibc-2.13 index 864de8441e..93c64c1293 100755 --- a/tools/mkpkg/mkpkg_libjpeg-turbo +++ b/tools/mkpkg/mkpkg_eglibc-2.13 @@ -20,23 +20,26 @@ ################################################################################ echo "getting sources..." - svn co https://libjpeg-turbo.svn.sourceforge.net/svnroot/libjpeg-turbo/trunk libjpeg-turbo-latest + svn co svn://svn.eglibc.org/branches/eglibc-2_13/libc eglibc-2.13-latest + svn co svn://svn.eglibc.org/branches/eglibc-2_13/ports eglibc-2.13-latest/ports + svn co svn://svn.eglibc.org/branches/eglibc-2_13/linuxthreads/linuxthreads eglibc-2.13-latest/linuxthreads + svn co svn://svn.eglibc.org/branches/eglibc-2_13/linuxthreads/linuxthreads_db eglibc-2.13-latest/linuxthreads_db echo "getting version..." - cd libjpeg-turbo-latest + cd eglibc-2.13-latest SVN_REV=`LANG=C svn info 2>/dev/null | grep Revision: | sed -e 's/.*\: //'` echo $SVN_REV cd .. echo "copying sources..." - rm -rf libjpeg-turbo-$SVN_REV - cp -R libjpeg-turbo-latest libjpeg-turbo-$SVN_REV + rm -rf eglibc-2.13-$SVN_REV + cp -R eglibc-2.13-latest eglibc-2.13-$SVN_REV echo "cleaning sources..." - find libjpeg-turbo-$SVN_REV -name .svn -exec rm -rf {} ";" + find eglibc-2.13-$SVN_REV -name .svn -exec rm -rf {} ";" echo "packing sources..." - tar cvjf libjpeg-turbo-$SVN_REV.tar.bz2 libjpeg-turbo-$SVN_REV + tar cvjf eglibc-2.13-$SVN_REV.tar.bz2 eglibc-2.13-$SVN_REV echo "remove temporary sourcedir..." - rm -rf libjpeg-turbo-$SVN_REV + rm -rf eglibc-2.13-$SVN_REV