aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/linux
diff options
context:
space:
mode:
authorThilo Fromm <fromm@dresearch-fe.de>2011-05-20 10:36:37 +0000
committerSteffen Sledz <sledz@dresearch-fe.de>2011-06-06 11:35:14 +0200
commitf04f5a81aca703bb507d0051332527db3a3c903a (patch)
treeace15b7c6b0ca6861b7ab62407ea8af46cc5ee15 /recipes/linux
parent3dfcd3a76e60b8186b50cde3e1198f090dc1937e (diff)
downloadopenembedded-f04f5a81aca703bb507d0051332527db3a3c903a.tar.gz
linux-2.6.24: add PCI abort handler (hipox machine only)
Signed-off-by: Thilo Fromm <fromm@dresearch-fe.de>
Diffstat (limited to 'recipes/linux')
-rw-r--r--recipes/linux/linux-2.6.24/hipox/ox810-pci-abort-handler.patch1009
-rw-r--r--recipes/linux/linux_2.6.24.bb3
2 files changed, 1011 insertions, 1 deletions
diff --git a/recipes/linux/linux-2.6.24/hipox/ox810-pci-abort-handler.patch b/recipes/linux/linux-2.6.24/hipox/ox810-pci-abort-handler.patch
new file mode 100644
index 0000000000..f85954be8b
--- /dev/null
+++ b/recipes/linux/linux-2.6.24/hipox/ox810-pci-abort-handler.patch
@@ -0,0 +1,1009 @@
+--- old/arch/arm/mach-hipox/pci.c 2011-05-16 11:00:10.665564998 +0200
++++ new/arch/arm/mach-hipox/pci.c 2011-05-17 17:13:33.845565008 +0200
+@@ -667,6 +667,44 @@
+ .postinit = hipox_pci_postinit,
+ };
+
++static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
++{
++ unsigned long pc = instruction_pointer(regs);
++ unsigned long instr = *(unsigned long *)pc;
++
++ static unsigned int mod = 1;
++
++ CheckAndClearBusError();
++
++ if ( 0 == (++mod % 100000) )
++ printk(KERN_ERR "PCI: Bus error happened %u times; last is at address 0x%lX.\n", mod, addr);
++
++ /* set return value to -1 if this was a read */
++ if ((instr & 0x0c100000) == 0x04100000) {
++ int reg = (instr >> 12) & 15;
++ unsigned long val;
++
++ if (instr & 0x00400000)
++ val = 255; /* byte read */
++ else
++ val = -1;
++
++ regs->uregs[reg] = val;
++ regs->ARM_pc += 4;
++ return 0;
++ }
++
++ if ((instr & 0x0e100090) == 0x00100090) {
++ int reg = (instr >> 12) & 15;
++
++ regs->uregs[reg] = -1;
++ regs->ARM_pc += 4;
++ return 0;
++ }
++
++ return 0;
++}
++
+ static int __init hipox_pci_init(void)
+ {
+ #ifdef CONFIG_HIPOX_PCI_RESET
+@@ -679,6 +717,7 @@
+ printk(KERN_DEBUG "PCI: hipox_pci_init now it's %lu, will wait till %lu to become ready for config\n", pci_trhfa_startwait, pci_trhfa_timeout);
+ #endif // CONFIG_HIPOX_PCI_RESET
+
++ hook_fault_code(8, abort_handler, SIGBUS, "PCI external abort on non-linefetch");
+ pci_common_init(&hipox_pci);
+ return 0;
+ }
+--- old/arch/arm/mach-hipox/smc.c 2011-05-16 11:00:09.165565000 +0200
++++ new/arch/arm/mach-hipox/smc.c 2011-05-19 16:17:55.335565001 +0200
+@@ -20,17 +20,17 @@
+
+ #include <asm/io.h>
+ #include <asm/hardware.h>
++#include <asm/semaphore.h>
+ #include <asm/arch/smc.h>
+ #include <linux/delay.h>
+ #include <linux/jiffies.h>
+ #include <linux/module.h>
+-#include <linux/hrtimer.h>
+
+-static ktime_t request_pci_timestamp = {0};
++static unsigned int request_pci_timestamp = 0;
+ /*
+ * Request PCI_ARB to grant access to the STATIC core.
+ */
+-void hipox_smc_request_pci_ad_31_0(void)
++static int _hipox_smc_request_pci_ad_31_0(void)
+ {
+ unsigned maxtries = 10; /* wait for maxtries jiffies at maximum */
+
+@@ -50,25 +50,185 @@
+ if (!(readl(SYS_CTRL_PCI_STAT) & (1UL << SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT)))
+ printk(KERN_WARNING "%s: timeout requesting access to PCI bus for static memory interface\n", __func__);
+
+- request_pci_timestamp = ktime_get();
++ request_pci_timestamp = jiffies_to_msecs(get_jiffies_64());
++
++ return ( 0 != ( readl(SYS_CTRL_PCI_STAT) & (1UL << SYSCTL_PCI_STAT_SYSPCI_STATIC_GNT) ) ? 0 : 1 );
+ }
+
+ /*
+ * Release access to PCI bus.
+ */
+-void hipox_smc_release_pci_ad_31_0(void)
++static void _hipox_smc_release_pci_ad_31_0(void)
+ {
+- const s64 timeout = 400; /* us */
+- s64 delta = ktime_us_delta(ktime_get(), request_pci_timestamp);
++ const unsigned int timeout = 100; /* ms */
++ unsigned int delta = jiffies_to_msecs(get_jiffies_64()) - request_pci_timestamp;
+
+ /* set PCI_ARB request bit in Sysctrl_PCI_Ctrl1 */
+ writel(readl(SYS_CTRL_PCI_CTRL1) & ~(1UL << SYSCTL_PCI_CTRL1_SYSPCI_STATIC_REQ), SYS_CTRL_PCI_CTRL1);
+
+ if (delta > timeout)
+ {
+- printk(KERN_WARNING "%s: static memory interface blocked PCI bus for %llu us\n", __func__, delta);
++ printk(KERN_WARNING "%s: static memory interface blocked PCI bus for %u ms\n", __func__, delta);
+ }
+ }
+
+-EXPORT_SYMBOL(hipox_smc_request_pci_ad_31_0);
+-EXPORT_SYMBOL(hipox_smc_release_pci_ad_31_0);
++/*
++ * PCI / PNX / Flash interlock handling
++ *
++ */
++
++enum pci_semaphore_id {
++ no_one = 0,
++ ox810_pci = 1,
++ ox810_flash = 2,
++ remote_pci = 3
++};
++
++DECLARE_MUTEX(_pci_bus_linux_semaphore); // don't be fooled; this actually declares a _semaphore_ (see asm-arm/semaphore.h)
++struct pci_semaphore {
++ struct semaphore *linux_sem; /**< lock the bus for flash or pci accesses */
++ enum pci_semaphore_id current_owner;
++ uint32_t current_count;
++};
++
++static struct pci_semaphore _pnx_pci_semaphore = {
++ &_pci_bus_linux_semaphore,
++ no_one,
++ 0
++};
++/* ---- */
++
++static int default_sem_acquire( void *ignored, uint32_t ignored2)
++{
++ return 0;
++}
++/* ---- */
++
++static int default_sem_release ( void *ignored )
++{
++ return 0;
++}
++/* ---- */
++
++static int (*pci_sem_acquire)( void * ctx, uint32_t value ) = default_sem_acquire;
++static int (*pci_sem_release)( void * ctx ) = default_sem_release;
++static void * pci_sem_context = NULL;
++
++void ox810_pci_register_semaphore_callbacks( int (*acquire)(void*, uint32_t), int (*release)(void*), void * ctx )
++{
++ pci_sem_acquire = acquire;
++ pci_sem_release = release;
++ pci_sem_context = ctx;
++}
++/* ---- */
++
++void ox810_pci_reset_semaphore_callbacks( void )
++{
++ pci_sem_acquire = default_sem_acquire;
++ pci_sem_release = default_sem_release;
++}
++/* ---- */
++
++static int sem_acquire( enum pci_semaphore_id caller_id )
++{
++ if ( 0 != down_trylock( _pnx_pci_semaphore.linux_sem ) ) {
++ if ( _pnx_pci_semaphore.current_owner == caller_id ) {
++ _pnx_pci_semaphore.current_count++;
++ return 0;
++ }
++
++ down( _pnx_pci_semaphore.linux_sem );
++ }
++
++ if ( 0 == pci_sem_acquire( pci_sem_context, caller_id) ) {
++
++ if ( ( caller_id == ox810_flash )
++ && ( 0 != _hipox_smc_request_pci_ad_31_0() ) ) {
++ up( _pnx_pci_semaphore.linux_sem );
++ return 1;
++ }
++
++ _pnx_pci_semaphore.current_owner = caller_id;
++ _pnx_pci_semaphore.current_count = 1;
++
++ return 0;
++ }
++
++ up( _pnx_pci_semaphore.linux_sem );
++
++ return 1;
++}
++/* ---- */
++
++static int sem_release( enum pci_semaphore_id caller_id )
++{
++ if ( _pnx_pci_semaphore.current_owner != caller_id )
++ return 1;
++
++ _pnx_pci_semaphore.current_count--;
++ if ( 0 != _pnx_pci_semaphore.current_count )
++ return 0;
++
++ if ( caller_id == ox810_flash )
++ _hipox_smc_release_pci_ad_31_0();
++
++ if ( 0 != pci_sem_release( pci_sem_context ))
++ return 1;
++
++ _pnx_pci_semaphore.current_owner = no_one;
++ up( _pnx_pci_semaphore.linux_sem );
++
++ return 0;
++}
++/* ---- */
++
++int ox810_pci_acquire_bus( void )
++{
++ return sem_acquire ( ox810_pci );
++}
++/* ---- */
++
++int ox810_pci_release_bus( void )
++{
++ return sem_release ( ox810_pci );
++}
++/* ---- */
++
++int ox810_flash_acquire_bus( void )
++{
++ return sem_acquire( ox810_flash );
++}
++/* ---- */
++
++int ox810_flash_release_bus( void )
++{
++ return sem_release( ox810_flash );
++}
++/* ---- */
++
++void hipox_smc_request_pci_ad_31_0( void )
++{
++ static uint32_t warned = 0;
++ if ( 0 == (warned++ % 10000) )
++ printk( KERN_ERR "ERROR in arch/arm/mach-hipox/smc.c: deprecated hipox_smc_request_pci_ad_31_0() called instead of ox810_flash_acquire_bus(). This interface will die soon. PLEASE UPDATE YOUR DRIVER.\n");
++ ox810_flash_acquire_bus();
++}
++void hipox_smc_release_pci_ad_31_0( void )
++{
++ static uint32_t warned = 0;
++ if ( 0 == (warned++ % 10000) )
++ printk( KERN_ERR "ERROR in arch/arm/mach-hipox/smc.c: deprecated hipox_smc_release_pci_ad_31_0() called instead of ox810_flash_release_bus(). This interface will die soon. PLEASE UPDATE YOUR DRIVER.\n");
++ ox810_flash_release_bus();
++}
++/* ---- */
++
++EXPORT_SYMBOL( hipox_smc_request_pci_ad_31_0 );
++EXPORT_SYMBOL( hipox_smc_release_pci_ad_31_0 );
++
++EXPORT_SYMBOL(ox810_pci_acquire_bus);
++EXPORT_SYMBOL(ox810_pci_release_bus);
++EXPORT_SYMBOL(ox810_flash_acquire_bus);
++EXPORT_SYMBOL(ox810_flash_release_bus);
++
++EXPORT_SYMBOL(ox810_pci_register_semaphore_callbacks);
++EXPORT_SYMBOL(ox810_pci_reset_semaphore_callbacks);
+--- old/include/asm-arm/arch-hipox/smc.h 2011-05-16 11:00:09.165565000 +0200
++++ new/include/asm-arm/arch-hipox/smc.h 2011-05-19 14:28:04.805564999 +0200
+@@ -15,14 +15,43 @@
+ */
+ extern struct mutex hipox_flash_mutex;
+
++
++/* Low level PCI BUS semaphore acquisition
++ *
++ * This handler will claim the linux semaphore and the PCI bus semaphore
++ * for the caller's ID.
++ *
++ * Returns 0 if the claim was successful and both semaphores are held; !=0 otherwise.
++ * */
++int ox810_pci_acquire_bus( void );
++int ox810_flash_acquire_bus( void );
++
++/* Low level PCI BUS semaphore release
++ *
++ * Returns 0 if release was successful, !=0 otherwise.
++ */
++int ox810_pci_release_bus( void );
++int ox810_flash_release_bus( void );
++
+ /*
+- * Request PCI_ARB to grant access to the STATIC core.
++ * PCI Driver bus semaphore registration / deregistration.
++ * This is used by the PCI driver which implements the low level bus semaphore logic:
++ * - int acquire (void * context, uint32_t owner):
++ * acquire the semaphore for an owner ID. Returns 0 if successful,
++ * !=0 otherwise.
++ * - int release (void * context):
++ * release the bus semaphore. There will be no owner check of the
++ * semaphore. Returns 0 if successful, !=0 otherwise.
++ *
++ * Deregistration must be done by the PCI driver upon unloading.
+ */
+-void hipox_smc_request_pci_ad_31_0(void);
++void ox810_pci_register_semaphore_callbacks( int (*acquire)(void*, uint32_t), int (*release)(void*), void * ctx );
++void ox810_pci_reset_semaphore_callbacks( void );
+
+ /*
+- * Release access to PCI bus.
++ * LEGACY interface. Will print ugly error messages if used. Do not use. Use ox810_flash_[release|request]_bus() instead.
+ */
+-void hipox_smc_release_pci_ad_31_0(void);
++void hipox_smc_release_pci_ad_31_0( void );
++void hipox_smc_request_pci_ad_31_0( void );
+
+ #endif // __ASM_ARCH_SMC_H
+--- old/drivers/mtd/nand/hipox_nand.c 2011-05-16 11:00:10.895565009 +0200
++++ new/drivers/mtd/nand/hipox_nand.c 2011-05-19 15:44:46.705564993 +0200
+@@ -23,6 +23,7 @@
+ #include <linux/delay.h>
+ #include <linux/mutex.h>
+ #include <asm/io.h>
++#include <asm/bug.h>
+ #include <asm/arch/hardware.h>
+ #include <asm/arch/smc.h>
+ #include <asm/sizes.h>
+@@ -30,10 +31,9 @@
+
+ // the testboards ran down to a value of 4
+ //#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f3f /* slow settings, 345 ns */
+-#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f0d /* fast settings, 70 ns; use this as default, because it works for hipox board NOR flash also */
++//#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f0d /* fast settings, 70 ns */
+ //#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f09 /* ultra fast settings, 50 ns */
+-//#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f04 /* warp settings, 27 ns */
+-#define STATIC_BUS_FLASH_CONFIG_RW 0x41030303 /* read and write warp settings */
++#define STATIC_BUS_FLASH_CONFIG 0x4f1f3f04 /* warp settings, 27 ns */
+
+ /*
+ * MTD structure for HydraIP board
+@@ -66,7 +66,6 @@
+ */
+ static void hipox_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+ {
+- static unsigned int bank0 = STATIC_BUS_FLASH_CONFIG;
+ struct nand_chip *this = mtd->priv;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+@@ -79,15 +78,12 @@
+ // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
+ mutex_lock(&hipox_flash_mutex);
+ writel(0x20000000, GPIO_A_OUTPUT_CLEAR); /* assert CS-NAND */
+- bank0 = readl(STATIC_CONTROL_BANK0);
+- writel(STATIC_BUS_FLASH_CONFIG_RW, STATIC_CONTROL_BANK0);
+ }
+ }
+ else
+ {
+ if (!(0x20000000 & readl(GPIO_A_OUTPUT_VALUE)))
+ {
+- writel(bank0, STATIC_CONTROL_BANK0);
+ writel(0x20000000, GPIO_A_OUTPUT_SET); /* deassert CS-NAND */
+ mutex_unlock(&hipox_flash_mutex);
+ // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
+@@ -104,9 +100,10 @@
+
+ if (cmd != NAND_CMD_NONE)
+ {
+- hipox_smc_request_pci_ad_31_0();
++ if ( ox810_flash_acquire_bus() )
++ BUG();
+ writeb(cmd, this->IO_ADDR_W);
+- hipox_smc_release_pci_ad_31_0();
++ ox810_flash_release_bus();
+ }
+ }
+
+@@ -120,9 +117,13 @@
+ {
+ struct nand_chip *chip = mtd->priv;
+ uint8_t res;
+- hipox_smc_request_pci_ad_31_0();
++
++ if ( ox810_flash_acquire_bus() )
++ BUG();
++
+ res = readb(chip->IO_ADDR_R);
+- hipox_smc_release_pci_ad_31_0();
++
++ ox810_flash_release_bus();
+ return res;
+ }
+
+@@ -137,9 +138,13 @@
+ {
+ struct nand_chip *chip = mtd->priv;
+ u16 res;
+- hipox_smc_request_pci_ad_31_0();
++
++ if ( ox810_flash_acquire_bus() )
++ BUG();
++
+ res = readw(chip->IO_ADDR_R);
+- hipox_smc_release_pci_ad_31_0();
++
++ ox810_flash_release_bus();
+ return res;
+ }
+
+@@ -156,10 +161,13 @@
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+- hipox_smc_request_pci_ad_31_0();
++ if ( ox810_flash_acquire_bus() )
++ BUG();
++
+ for (i = 0; i < len; i++)
+ buf[i] = readb(chip->IO_ADDR_R);
+- hipox_smc_release_pci_ad_31_0();
++
++ ox810_flash_release_bus();
+ }
+
+ /**
+@@ -175,10 +183,13 @@
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+- hipox_smc_request_pci_ad_31_0();
++ if ( ox810_flash_acquire_bus() )
++ BUG();
++
+ for (i = 0; i < len; i++)
+ writeb(buf[i], chip->IO_ADDR_W);
+- hipox_smc_release_pci_ad_31_0();
++
++ ox810_flash_release_bus();
+ }
+
+ /**
+@@ -195,7 +206,9 @@
+ int ret = 0;
+ struct nand_chip *chip = mtd->priv;
+
+- hipox_smc_request_pci_ad_31_0();
++ if ( ox810_flash_acquire_bus() )
++ BUG();
++
+ for (i = 0; i < len; i++)
+ {
+ if (buf[i] != readb(chip->IO_ADDR_R))
+@@ -204,7 +217,8 @@
+ break;
+ }
+ }
+- hipox_smc_release_pci_ad_31_0();
++
++ ox810_flash_release_bus();
+
+ return ret;
+ }
+@@ -239,9 +253,7 @@
+ return -ENOMEM;
+ }
+
+- mutex_lock(&hipox_flash_mutex);
+ writel(STATIC_BUS_FLASH_CONFIG, STATIC_CONTROL_BANK0);
+- mutex_unlock(&hipox_flash_mutex);
+
+ /* Initialize structures */
+ memset(hipox_nand_mtd, 0, sizeof(struct mtd_info));
+@@ -252,12 +264,12 @@
+ writel(0x20000000, GPIO_A_OUTPUT_ENABLE_SET);
+
+ // deselect alternate function
+- writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~0x20000000,
+- SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
+- writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~0x20000000,
+- SYS_CTRL_GPIO_SECSEL_CTRL_0);
+- writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~0x20000000,
+- SYS_CTRL_GPIO_TERTSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_PRIMSEL_CTRL_0) & ~0x20000000,
++ SYS_CTRL_GPIO_PRIMSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_SECSEL_CTRL_0) & ~0x20000000,
++ SYS_CTRL_GPIO_SECSEL_CTRL_0);
++ writel(readl(SYS_CTRL_GPIO_TERTSEL_CTRL_0) & ~0x20000000,
++ SYS_CTRL_GPIO_TERTSEL_CTRL_0);
+
+ // assert CS-NAND
+ writel(0x20000000, GPIO_A_OUTPUT_CLEAR);
+--- old/drivers/mtd/maps/physmap.c 2011-05-16 11:00:10.895565009 +0200
++++ new/drivers/mtd/maps/physmap.c 2011-05-19 15:45:07.765565002 +0200
+@@ -22,6 +22,7 @@
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/physmap.h>
+ #include <asm/io.h>
++#include <asm/bug.h>
+
+ #if defined (CONFIG_ARCH_HIPOX)
+ #include <asm/arch/smc.h>
+@@ -31,110 +32,115 @@
+ #endif /* CONFIG_ARCH_HIPOX */
+
+ struct physmap_flash_info {
+- struct mtd_info *mtd;
+- struct map_info map;
+- struct resource *res;
++ struct mtd_info *mtd;
++ struct map_info map;
++ struct resource *res;
+ #ifdef CONFIG_MTD_PARTITIONS
+- int nr_parts;
+- struct mtd_partition *parts;
++ int nr_parts;
++ struct mtd_partition *parts;
+ #endif
+ };
+
+
+ static int physmap_flash_remove(struct platform_device *dev)
+ {
+- struct physmap_flash_info *info;
+- struct physmap_flash_data *physmap_data;
++ struct physmap_flash_info *info;
++ struct physmap_flash_data *physmap_data;
+
+- info = platform_get_drvdata(dev);
+- if (info == NULL)
+- return 0;
+- platform_set_drvdata(dev, NULL);
++ info = platform_get_drvdata(dev);
++ if (info == NULL)
++ return 0;
++ platform_set_drvdata(dev, NULL);
+
+- physmap_data = dev->dev.platform_data;
++ physmap_data = dev->dev.platform_data;
+
+- if (info->mtd != NULL) {
++ if (info->mtd != NULL) {
+ #ifdef CONFIG_MTD_PARTITIONS
+- if (info->nr_parts) {
+- del_mtd_partitions(info->mtd);
+- kfree(info->parts);
+- } else if (physmap_data->nr_parts) {
+- del_mtd_partitions(info->mtd);
+- } else {
+- del_mtd_device(info->mtd);
+- }
++ if (info->nr_parts) {
++ del_mtd_partitions(info->mtd);
++ kfree(info->parts);
++ } else if (physmap_data->nr_parts) {
++ del_mtd_partitions(info->mtd);
++ } else {
++ del_mtd_device(info->mtd);
++ }
+ #else
+- del_mtd_device(info->mtd);
++ del_mtd_device(info->mtd);
+ #endif
+- map_destroy(info->mtd);
+- }
++ map_destroy(info->mtd);
++ }
+
+- if (info->map.virt != NULL)
+- iounmap(info->map.virt);
++ if (info->map.virt != NULL)
++ iounmap(info->map.virt);
+
+- if (info->res != NULL) {
+- release_resource(info->res);
+- kfree(info->res);
+- }
++ if (info->res != NULL) {
++ release_resource(info->res);
++ kfree(info->res);
++ }
+
+- return 0;
++ return 0;
+ }
+
+ #if defined (CONFIG_ARCH_HIPOX)
+ static map_word __xipram physmap_hipox_read(struct map_info *map, unsigned long ofs)
+ {
+- map_word ret;
++ map_word ret;
+
+- // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
+- mutex_lock(&hipox_flash_mutex);
+- hipox_smc_request_pci_ad_31_0();
++ // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
++ mutex_lock(&hipox_flash_mutex);
+
+- ret = inline_map_read(map, ofs);
++ if ( 0 != ox810_flash_acquire_bus() )
++ BUG();
+
+- hipox_smc_release_pci_ad_31_0();
+- mutex_unlock(&hipox_flash_mutex);
+- // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
++ ret = inline_map_read(map, ofs);
+
+- return ret;
++ ox810_flash_release_bus();
++ mutex_unlock(&hipox_flash_mutex);
++ // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
++
++ return ret;
+ }
+
+ static void __xipram physmap_hipox_write(struct map_info *map, const map_word datum, unsigned long ofs)
+ {
+- // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
+- mutex_lock(&hipox_flash_mutex);
+- hipox_smc_request_pci_ad_31_0();
+-
+- inline_map_write(map, datum, ofs);
+-
+- hipox_smc_release_pci_ad_31_0();
+- mutex_unlock(&hipox_flash_mutex);
+- // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
++ // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
++ mutex_lock(&hipox_flash_mutex);
++ if ( 0 != ox810_flash_acquire_bus() )
++ BUG();
++
++ inline_map_write(map, datum, ofs);
++
++ ox810_flash_release_bus();
++ mutex_unlock(&hipox_flash_mutex);
++ // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
+ }
+
+ static void __xipram physmap_hipox_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+ {
+- // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
+- mutex_lock(&hipox_flash_mutex);
+- hipox_smc_request_pci_ad_31_0();
+-
+- inline_map_copy_from(map, to, from, len);
+-
+- hipox_smc_release_pci_ad_31_0();
+- mutex_unlock(&hipox_flash_mutex);
+- // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
++ // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
++ mutex_lock(&hipox_flash_mutex);
++ if ( 0 != ox810_flash_acquire_bus() )
++ BUG();
++
++ inline_map_copy_from(map, to, from, len);
++
++ ox810_flash_release_bus();
++ mutex_unlock(&hipox_flash_mutex);
++ // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
+ }
+
+ static void __xipram physmap_hipox_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+ {
+- // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
+- mutex_lock(&hipox_flash_mutex);
+- hipox_smc_request_pci_ad_31_0();
+-
+- inline_map_copy_to(map, to, from, len);
+-
+- hipox_smc_release_pci_ad_31_0();
+- mutex_unlock(&hipox_flash_mutex);
+- // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
++ // printk("%s:%d would wait for hipox_flash_mutex\n", __func__, __LINE__);
++ mutex_lock(&hipox_flash_mutex);
++ if ( 0 != ox810_flash_acquire_bus() )
++ BUG();
++
++ inline_map_copy_to(map, to, from, len);
++
++ ox810_flash_release_bus();
++ mutex_unlock(&hipox_flash_mutex);
++ // printk("%s:%d hipox_flash_mutex unlocked\n", __func__, __LINE__);
+ }
+ #endif /* CONFIG_ARCH_HIPOX */
+
+@@ -145,136 +151,134 @@
+
+ static int physmap_flash_probe(struct platform_device *dev)
+ {
+- struct physmap_flash_data *physmap_data;
+- struct physmap_flash_info *info;
+- const char **probe_type;
+- int err;
+-
+- physmap_data = dev->dev.platform_data;
+- if (physmap_data == NULL)
+- return -ENODEV;
++ struct physmap_flash_data *physmap_data;
++ struct physmap_flash_info *info;
++ const char **probe_type;
++ int err;
++
++ physmap_data = dev->dev.platform_data;
++ if (physmap_data == NULL)
++ return -ENODEV;
+
+ #if defined (CONFIG_ARCH_HIPOX)
+- /* init timing for static memory controller */
+- mutex_lock(&hipox_flash_mutex);
+- writel(STATIC_BUS_FLASH_CONFIG, STATIC_CONTROL_BANK0);
+- mutex_unlock(&hipox_flash_mutex);
++ /* init timing for static memory controller */
++ writel(STATIC_BUS_FLASH_CONFIG, STATIC_CONTROL_BANK0);
+ #endif /* CONFIG_ARCH_HIPOX */
+
+- printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
+- (unsigned long long)(dev->resource->end - dev->resource->start + 1),
+- (unsigned long long)dev->resource->start);
+-
+- info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
+- if (info == NULL) {
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- platform_set_drvdata(dev, info);
+-
+- info->res = request_mem_region(dev->resource->start,
+- dev->resource->end - dev->resource->start + 1,
+- dev->dev.bus_id);
+- if (info->res == NULL) {
+- dev_err(&dev->dev, "Could not reserve memory region\n");
+- err = -ENOMEM;
+- goto err_out;
+- }
+-
+- info->map.name = dev->dev.bus_id;
+- info->map.phys = dev->resource->start;
+- info->map.size = dev->resource->end - dev->resource->start + 1;
+- info->map.bankwidth = physmap_data->width;
+- info->map.set_vpp = physmap_data->set_vpp;
+-
+- info->map.virt = ioremap(info->map.phys, info->map.size);
+- if (info->map.virt == NULL) {
+- dev_err(&dev->dev, "Failed to ioremap flash region\n");
+- err = EIO;
+- goto err_out;
+- }
++ printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n",
++ (unsigned long long)(dev->resource->end - dev->resource->start + 1),
++ (unsigned long long)dev->resource->start);
++
++ info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);
++ if (info == NULL) {
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ platform_set_drvdata(dev, info);
++
++ info->res = request_mem_region(dev->resource->start,
++ dev->resource->end - dev->resource->start + 1,
++ dev->dev.bus_id);
++ if (info->res == NULL) {
++ dev_err(&dev->dev, "Could not reserve memory region\n");
++ err = -ENOMEM;
++ goto err_out;
++ }
++
++ info->map.name = dev->dev.bus_id;
++ info->map.phys = dev->resource->start;
++ info->map.size = dev->resource->end - dev->resource->start + 1;
++ info->map.bankwidth = physmap_data->width;
++ info->map.set_vpp = physmap_data->set_vpp;
++
++ info->map.virt = ioremap(info->map.phys, info->map.size);
++ if (info->map.virt == NULL) {
++ dev_err(&dev->dev, "Failed to ioremap flash region\n");
++ err = EIO;
++ goto err_out;
++ }
+
+- simple_map_init(&info->map);
++ simple_map_init(&info->map);
+ #if defined (CONFIG_ARCH_HIPOX)
+- info->map.read = physmap_hipox_read;
+- info->map.write = physmap_hipox_write;
+- info->map.copy_from = physmap_hipox_copy_from;
+- info->map.copy_to = physmap_hipox_copy_to;
++ info->map.read = physmap_hipox_read;
++ info->map.write = physmap_hipox_write;
++ info->map.copy_from = physmap_hipox_copy_from;
++ info->map.copy_to = physmap_hipox_copy_to;
+ #endif /* CONFIG_ARCH_HIPOX */
+
+- probe_type = rom_probe_types;
+- for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
+- info->mtd = do_map_probe(*probe_type, &info->map);
+- if (info->mtd == NULL) {
+- dev_err(&dev->dev, "map_probe failed\n");
+- err = -ENXIO;
+- goto err_out;
+- }
+- info->mtd->owner = THIS_MODULE;
++ probe_type = rom_probe_types;
++ for (; info->mtd == NULL && *probe_type != NULL; probe_type++)
++ info->mtd = do_map_probe(*probe_type, &info->map);
++ if (info->mtd == NULL) {
++ dev_err(&dev->dev, "map_probe failed\n");
++ err = -ENXIO;
++ goto err_out;
++ }
++ info->mtd->owner = THIS_MODULE;
+
+ #ifdef CONFIG_MTD_PARTITIONS
+- err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
+- if (err > 0) {
+- add_mtd_partitions(info->mtd, info->parts, err);
+- return 0;
+- }
+-
+- if (physmap_data->nr_parts) {
+- printk(KERN_NOTICE "Using physmap partition information\n");
+- add_mtd_partitions(info->mtd, physmap_data->parts,
+- physmap_data->nr_parts);
+- return 0;
+- }
++ err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);
++ if (err > 0) {
++ add_mtd_partitions(info->mtd, info->parts, err);
++ return 0;
++ }
++
++ if (physmap_data->nr_parts) {
++ printk(KERN_NOTICE "Using physmap partition information\n");
++ add_mtd_partitions(info->mtd, physmap_data->parts,
++ physmap_data->nr_parts);
++ return 0;
++ }
+ #endif
+
+- add_mtd_device(info->mtd);
+- return 0;
++ add_mtd_device(info->mtd);
++ return 0;
+
+ err_out:
+- physmap_flash_remove(dev);
+- return err;
++ physmap_flash_remove(dev);
++ return err;
+ }
+
+ #ifdef CONFIG_PM
+ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state)
+ {
+- struct physmap_flash_info *info = platform_get_drvdata(dev);
+- int ret = 0;
++ struct physmap_flash_info *info = platform_get_drvdata(dev);
++ int ret = 0;
+
+- if (info)
+- ret = info->mtd->suspend(info->mtd);
++ if (info)
++ ret = info->mtd->suspend(info->mtd);
+
+- return ret;
++ return ret;
+ }
+
+ static int physmap_flash_resume(struct platform_device *dev)
+ {
+- struct physmap_flash_info *info = platform_get_drvdata(dev);
+- if (info)
+- info->mtd->resume(info->mtd);
+- return 0;
++ struct physmap_flash_info *info = platform_get_drvdata(dev);
++ if (info)
++ info->mtd->resume(info->mtd);
++ return 0;
+ }
+
+ static void physmap_flash_shutdown(struct platform_device *dev)
+ {
+- struct physmap_flash_info *info = platform_get_drvdata(dev);
+- if (info && info->mtd->suspend(info->mtd) == 0)
+- info->mtd->resume(info->mtd);
++ struct physmap_flash_info *info = platform_get_drvdata(dev);
++ if (info && info->mtd->suspend(info->mtd) == 0)
++ info->mtd->resume(info->mtd);
+ }
+ #endif
+
+ static struct platform_driver physmap_flash_driver = {
+- .probe = physmap_flash_probe,
+- .remove = physmap_flash_remove,
++ .probe = physmap_flash_probe,
++ .remove = physmap_flash_remove,
+ #ifdef CONFIG_PM
+- .suspend = physmap_flash_suspend,
+- .resume = physmap_flash_resume,
+- .shutdown = physmap_flash_shutdown,
+-#endif
+- .driver = {
+- .name = "physmap-flash",
+- },
++ .suspend = physmap_flash_suspend,
++ .resume = physmap_flash_resume,
++ .shutdown = physmap_flash_shutdown,
++#endif
++ .driver = {
++ .name = "physmap-flash",
++ },
+ };
+
+
+@@ -291,63 +295,63 @@
+ }
+
+ static struct physmap_flash_data physmap_flash_data = {
+- .width = CONFIG_MTD_PHYSMAP_BANKWIDTH,
++ .width = CONFIG_MTD_PHYSMAP_BANKWIDTH,
+ };
+
+ static struct resource physmap_flash_resource = {
+- .start = CONFIG_MTD_PHYSMAP_START,
+- .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
+- .flags = IORESOURCE_MEM,
++ .start = CONFIG_MTD_PHYSMAP_START,
++ .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1,
++ .flags = IORESOURCE_MEM,
+ };
+
+ static struct platform_device physmap_flash = {
+- .name = "physmap-flash",
+- .id = 0,
+- .dev = {
+- .platform_data = &physmap_flash_data,
+- .release = physmap_flash_release, /* needed for module build */
+- },
+- .num_resources = 1,
+- .resource = &physmap_flash_resource,
++ .name = "physmap-flash",
++ .id = 0,
++ .dev = {
++ .platform_data = &physmap_flash_data,
++ .release = physmap_flash_release, /* needed for module build */
++ },
++ .num_resources = 1,
++ .resource = &physmap_flash_resource,
+ };
+
+ void physmap_configure(unsigned long addr, unsigned long size,
+- int bankwidth, void (*set_vpp)(struct map_info *, int))
++ int bankwidth, void (*set_vpp)(struct map_info *, int))
+ {
+- physmap_flash_resource.start = addr;
+- physmap_flash_resource.end = addr + size - 1;
+- physmap_flash_data.width = bankwidth;
+- physmap_flash_data.set_vpp = set_vpp;
++ physmap_flash_resource.start = addr;
++ physmap_flash_resource.end = addr + size - 1;
++ physmap_flash_data.width = bankwidth;
++ physmap_flash_data.set_vpp = set_vpp;
+ }
+
+ #ifdef CONFIG_MTD_PARTITIONS
+ void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
+ {
+- physmap_flash_data.nr_parts = num_parts;
+- physmap_flash_data.parts = parts;
++ physmap_flash_data.nr_parts = num_parts;
++ physmap_flash_data.parts = parts;
+ }
+ #endif
+ #endif
+
+ static int __init physmap_init(void)
+ {
+- int err;
++ int err;
+
+- err = platform_driver_register(&physmap_flash_driver);
++ err = platform_driver_register(&physmap_flash_driver);
+ #ifdef PHYSMAP_COMPAT
+- if (err == 0)
+- platform_device_register(&physmap_flash);
++ if (err == 0)
++ platform_device_register(&physmap_flash);
+ #endif
+
+- return err;
++ return err;
+ }
+
+ static void __exit physmap_exit(void)
+ {
+ #ifdef PHYSMAP_COMPAT
+- platform_device_unregister(&physmap_flash);
++ platform_device_unregister(&physmap_flash);
+ #endif
+- platform_driver_unregister(&physmap_flash_driver);
++ platform_driver_unregister(&physmap_flash_driver);
+ }
+
+ module_init(physmap_init);
diff --git a/recipes/linux/linux_2.6.24.bb b/recipes/linux/linux_2.6.24.bb
index 97eef1b16e..121a8c3b89 100644
--- a/recipes/linux/linux_2.6.24.bb
+++ b/recipes/linux/linux_2.6.24.bb
@@ -11,7 +11,7 @@ DEFAULT_PREFERENCE_hipox = "1"
DEFAULT_PREFERENCE_cs-e9302 = "1"
DEFAULT_PREFERENCE_smartq5 = "1"
-PR = "r38"
+PR = "r39"
SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-2.6.24.tar.bz2;name=kernel \
${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/patch-${PV}.7.bz2;apply=yes;name=stablepatch \
@@ -108,6 +108,7 @@ SRC_URI_append_hipox = " \
file://hipox-phy.patch \
file://ox810-pci-read-config-fix.patch \
file://hipox-nand-timing.patch \
+ file://ox810-pci-abort-handler.patch \
"
EXTRA_OEMAKE_smartq5 = " OBJCOPY=${OBJCOPY}"