From f04f5a81aca703bb507d0051332527db3a3c903a Mon Sep 17 00:00:00 2001 From: Thilo Fromm Date: Fri, 20 May 2011 10:36:37 +0000 Subject: linux-2.6.24: add PCI abort handler (hipox machine only) Signed-off-by: Thilo Fromm --- .../hipox/ox810-pci-abort-handler.patch | 1009 ++++++++++++++++++++ recipes/linux/linux_2.6.24.bb | 3 +- 2 files changed, 1011 insertions(+), 1 deletion(-) create mode 100644 recipes/linux/linux-2.6.24/hipox/ox810-pci-abort-handler.patch (limited to 'recipes/linux') 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 + #include ++#include + #include + #include + #include + #include +-#include + +-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 + #include + #include ++#include + #include + #include + #include +@@ -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 + #include + #include ++#include + + #if defined (CONFIG_ARCH_HIPOX) + #include +@@ -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}" -- cgit 1.2.3-korg