diff options
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 287 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbmgr.c | 8 | ||||
-rw-r--r-- | arch/blackfin/kernel/ipipe.c | 38 | ||||
-rw-r--r-- | arch/blackfin/kernel/kgdb_test.c | 1 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 12 | ||||
-rw-r--r-- | arch/blackfin/kernel/sys_bfin.c | 15 | ||||
-rw-r--r-- | arch/blackfin/kernel/trace.c | 1 |
8 files changed, 226 insertions, 145 deletions
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index dc07ed08b37..170cf90735b 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -1,7 +1,7 @@ /* * GPIO Abstraction Layer * - * Copyright 2006-2009 Analog Devices Inc. + * Copyright 2006-2010 Analog Devices Inc. * * Licensed under the GPL-2 or later */ @@ -215,82 +215,91 @@ static void port_setup(unsigned gpio, unsigned short usage) } #ifdef BF537_FAMILY -static struct { - unsigned short res; - unsigned short offset; -} port_mux_lut[] = { - {.res = P_PPI0_D13, .offset = 11}, - {.res = P_PPI0_D14, .offset = 11}, - {.res = P_PPI0_D15, .offset = 11}, - {.res = P_SPORT1_TFS, .offset = 11}, - {.res = P_SPORT1_TSCLK, .offset = 11}, - {.res = P_SPORT1_DTPRI, .offset = 11}, - {.res = P_PPI0_D10, .offset = 10}, - {.res = P_PPI0_D11, .offset = 10}, - {.res = P_PPI0_D12, .offset = 10}, - {.res = P_SPORT1_RSCLK, .offset = 10}, - {.res = P_SPORT1_RFS, .offset = 10}, - {.res = P_SPORT1_DRPRI, .offset = 10}, - {.res = P_PPI0_D8, .offset = 9}, - {.res = P_PPI0_D9, .offset = 9}, - {.res = P_SPORT1_DRSEC, .offset = 9}, - {.res = P_SPORT1_DTSEC, .offset = 9}, - {.res = P_TMR2, .offset = 8}, - {.res = P_PPI0_FS3, .offset = 8}, - {.res = P_TMR3, .offset = 7}, - {.res = P_SPI0_SSEL4, .offset = 7}, - {.res = P_TMR4, .offset = 6}, - {.res = P_SPI0_SSEL5, .offset = 6}, - {.res = P_TMR5, .offset = 5}, - {.res = P_SPI0_SSEL6, .offset = 5}, - {.res = P_UART1_RX, .offset = 4}, - {.res = P_UART1_TX, .offset = 4}, - {.res = P_TMR6, .offset = 4}, - {.res = P_TMR7, .offset = 4}, - {.res = P_UART0_RX, .offset = 3}, - {.res = P_UART0_TX, .offset = 3}, - {.res = P_DMAR0, .offset = 3}, - {.res = P_DMAR1, .offset = 3}, - {.res = P_SPORT0_DTSEC, .offset = 1}, - {.res = P_SPORT0_DRSEC, .offset = 1}, - {.res = P_CAN0_RX, .offset = 1}, - {.res = P_CAN0_TX, .offset = 1}, - {.res = P_SPI0_SSEL7, .offset = 1}, - {.res = P_SPORT0_TFS, .offset = 0}, - {.res = P_SPORT0_DTPRI, .offset = 0}, - {.res = P_SPI0_SSEL2, .offset = 0}, - {.res = P_SPI0_SSEL3, .offset = 0}, +static const s8 port_mux[] = { + [GPIO_PF0] = 3, + [GPIO_PF1] = 3, + [GPIO_PF2] = 4, + [GPIO_PF3] = 4, + [GPIO_PF4] = 5, + [GPIO_PF5] = 6, + [GPIO_PF6] = 7, + [GPIO_PF7] = 8, + [GPIO_PF8 ... GPIO_PF15] = -1, + [GPIO_PG0 ... GPIO_PG7] = -1, + [GPIO_PG8] = 9, + [GPIO_PG9] = 9, + [GPIO_PG10] = 10, + [GPIO_PG11] = 10, + [GPIO_PG12] = 10, + [GPIO_PG13] = 11, + [GPIO_PG14] = 11, + [GPIO_PG15] = 11, + [GPIO_PH0 ... GPIO_PH15] = -1, + [PORT_PJ0 ... PORT_PJ3] = -1, + [PORT_PJ4] = 1, + [PORT_PJ5] = 1, + [PORT_PJ6 ... PORT_PJ9] = -1, + [PORT_PJ10] = 0, + [PORT_PJ11] = 0, }; -static void portmux_setup(unsigned short per) +static int portmux_group_check(unsigned short per) { - u16 y, offset, muxreg; + u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); + s8 offset = port_mux[ident]; + u16 m, pmux, pfunc; - for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { - if (port_mux_lut[y].res == per) { - - /* SET PORTMUX REG */ - - offset = port_mux_lut[y].offset; - muxreg = bfin_read_PORT_MUX(); + if (offset < 0) + return 0; - if (offset != 1) - muxreg &= ~(1 << offset); - else - muxreg &= ~(3 << 1); + pmux = bfin_read_PORT_MUX(); + for (m = 0; m < ARRAY_SIZE(port_mux); ++m) { + if (m == ident) + continue; + if (port_mux[m] != offset) + continue; + if (!is_reserved(peri, m, 1)) + continue; - muxreg |= (function << offset); - bfin_write_PORT_MUX(muxreg); + if (offset == 1) + pfunc = (pmux >> offset) & 3; + else + pfunc = (pmux >> offset) & 1; + if (pfunc != function) { + pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n", + ident, function, m, pfunc); + return -EINVAL; } } + + return 0; +} + +static void portmux_setup(unsigned short per) +{ + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); + s8 offset = port_mux[ident]; + u16 pmux; + + if (offset == -1) + return; + + pmux = bfin_read_PORT_MUX(); + if (offset != 1) + pmux &= ~(1 << offset); + else + pmux &= ~(3 << 1); + pmux |= (function << offset); + bfin_write_PORT_MUX(pmux); } #elif defined(CONFIG_BF54x) inline void portmux_setup(unsigned short per) { - u32 pmux; u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); + u32 pmux; pmux = gpio_array[gpio_bank(ident)]->port_mux; @@ -302,20 +311,54 @@ inline void portmux_setup(unsigned short per) inline u16 get_portmux(unsigned short per) { - u32 pmux; u16 ident = P_IDENT(per); - - pmux = gpio_array[gpio_bank(ident)]->port_mux; - + u32 pmux = gpio_array[gpio_bank(ident)]->port_mux; return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); } +static int portmux_group_check(unsigned short per) +{ + return 0; +} #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x) +static int portmux_group_check(unsigned short per) +{ + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); + u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; + u16 pin, gpiopin, pfunc; + + for (pin = 0; pin < GPIO_BANKSIZE; ++pin) { + if (offset != pmux_offset[gpio_bank(ident)][pin]) + continue; + + gpiopin = gpio_bank(ident) * GPIO_BANKSIZE + pin; + if (gpiopin == ident) + continue; + if (!is_reserved(peri, gpiopin, 1)) + continue; + + pfunc = *port_mux[gpio_bank(ident)]; + pfunc = (pfunc >> offset) & 3; + if (pfunc != function) { + pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n", + ident, function, gpiopin, pfunc); + return -EINVAL; + } + } + + return 0; +} + inline void portmux_setup(unsigned short per) { - u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; + u16 pmux; pmux = *port_mux[gpio_bank(ident)]; + if (((pmux >> offset) & 3) == function) + return; pmux &= ~(3 << offset); pmux |= (function & 3) << offset; *port_mux[gpio_bank(ident)] = pmux; @@ -323,6 +366,10 @@ inline void portmux_setup(unsigned short per) } #else # define portmux_setup(...) do { } while (0) +static int portmux_group_check(unsigned short per) +{ + return 0; +} #endif #ifndef CONFIG_BF54x @@ -349,13 +396,13 @@ inline void portmux_setup(unsigned short per) void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ - local_irq_save_hw(flags); \ + flags = hard_local_irq_save(); \ if (arg) \ gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ else \ gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + hard_local_irq_restore(flags); \ } \ EXPORT_SYMBOL(set_gpio_ ## name); @@ -371,14 +418,14 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ + flags = hard_local_irq_save(); \ if (arg) \ gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ else \ gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ if (ANOMALY_05000311 || ANOMALY_05000323) { \ AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + hard_local_irq_restore(flags); \ } \ } \ EXPORT_SYMBOL(set_gpio_ ## name); @@ -391,11 +438,11 @@ void set_gpio_toggle(unsigned gpio) { unsigned long flags; if (ANOMALY_05000311 || ANOMALY_05000323) - local_irq_save_hw(flags); + flags = hard_local_irq_save(); gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); if (ANOMALY_05000311 || ANOMALY_05000323) { AWA_DUMMY_READ(toggle); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } } EXPORT_SYMBOL(set_gpio_toggle); @@ -408,11 +455,11 @@ void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ + flags = hard_local_irq_save(); \ gpio_array[gpio_bank(gpio)]->name = arg; \ if (ANOMALY_05000311 || ANOMALY_05000323) { \ AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + hard_local_irq_restore(flags); \ } \ } \ EXPORT_SYMBOL(set_gpiop_ ## name); @@ -433,11 +480,11 @@ unsigned short get_gpio_ ## name(unsigned gpio) \ unsigned long flags; \ unsigned short ret; \ if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ + flags = hard_local_irq_save(); \ ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ if (ANOMALY_05000311 || ANOMALY_05000323) { \ AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + hard_local_irq_restore(flags); \ } \ return ret; \ } \ @@ -460,11 +507,11 @@ unsigned short get_gpiop_ ## name(unsigned gpio) \ unsigned long flags; \ unsigned short ret; \ if (ANOMALY_05000311 || ANOMALY_05000323) \ - local_irq_save_hw(flags); \ + flags = hard_local_irq_save(); \ ret = (gpio_array[gpio_bank(gpio)]->name); \ if (ANOMALY_05000311 || ANOMALY_05000323) { \ AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + hard_local_irq_restore(flags); \ } \ return ret; \ } \ @@ -525,14 +572,14 @@ int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) if (check_gpio(gpio) < 0) return -EINVAL; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (ctrl) reserve(wakeup, gpio); else unreserve(wakeup, gpio); set_gpio_maskb(gpio, ctrl); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 0; } @@ -690,7 +737,7 @@ int peripheral_request(unsigned short per, const char *label) BUG_ON(ident >= MAX_RESOURCES); - local_irq_save_hw(flags); + flags = hard_local_irq_save(); /* If a pin can be muxed as either GPIO or peripheral, make * sure it is not already a GPIO pin when we request it. @@ -701,7 +748,7 @@ int peripheral_request(unsigned short per, const char *label) printk(KERN_ERR "%s: Peripheral %d is already reserved as GPIO by %s !\n", __func__, ident, get_label(ident)); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -EBUSY; } @@ -730,18 +777,22 @@ int peripheral_request(unsigned short per, const char *label) printk(KERN_ERR "%s: Peripheral %d function %d is already reserved by %s !\n", __func__, ident, P_FUNCT2MUX(per), get_label(ident)); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -EBUSY; } } + if (unlikely(portmux_group_check(per))) { + hard_local_irq_restore(flags); + return -EBUSY; + } anyway: reserve(peri, ident); portmux_setup(per); port_setup(ident, PERIPHERAL_USAGE); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); set_label(ident, label); return 0; @@ -780,10 +831,10 @@ void peripheral_free(unsigned short per) if (!(per & P_DEFINED)) return; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (unlikely(!is_reserved(peri, ident, 0))) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return; } @@ -794,7 +845,7 @@ void peripheral_free(unsigned short per) set_label(ident, "free"); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(peripheral_free); @@ -828,7 +879,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) if (check_gpio(gpio) < 0) return -EINVAL; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); /* * Allow that the identical GPIO can @@ -837,7 +888,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) */ if (cmp_label(gpio, label) == 0) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 0; } @@ -846,7 +897,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) dump_stack(); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", gpio, get_label(gpio)); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -EBUSY; } if (unlikely(is_reserved(peri, gpio, 1))) { @@ -855,7 +906,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", gpio, get_label(gpio)); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -EBUSY; } if (unlikely(is_reserved(gpio_irq, gpio, 1))) { @@ -871,7 +922,7 @@ int bfin_gpio_request(unsigned gpio, const char *label) reserve(gpio, gpio); set_label(gpio, label); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); port_setup(gpio, GPIO_USAGE); @@ -888,13 +939,13 @@ void bfin_gpio_free(unsigned gpio) might_sleep(); - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (unlikely(!is_reserved(gpio, gpio, 0))) { if (system_state == SYSTEM_BOOTING) dump_stack(); gpio_error(gpio); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return; } @@ -902,7 +953,7 @@ void bfin_gpio_free(unsigned gpio) set_label(gpio, "free"); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(bfin_gpio_free); @@ -913,7 +964,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) { unsigned long flags; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); /* * Allow that the identical GPIO can @@ -922,19 +973,19 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) */ if (cmp_label(gpio, label) == 0) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 0; } if (unlikely(is_reserved(special_gpio, gpio, 1))) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n", gpio, get_label(gpio)); return -EBUSY; } if (unlikely(is_reserved(peri, gpio, 1))) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", gpio, get_label(gpio)); @@ -946,7 +997,7 @@ int bfin_special_gpio_request(unsigned gpio, const char *label) reserve(peri, gpio); set_label(gpio, label); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); port_setup(gpio, GPIO_USAGE); return 0; @@ -959,18 +1010,18 @@ void bfin_special_gpio_free(unsigned gpio) might_sleep(); - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (unlikely(!is_reserved(special_gpio, gpio, 0))) { gpio_error(gpio); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return; } unreserve(special_gpio, gpio); unreserve(peri, gpio); set_label(gpio, "free"); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(bfin_special_gpio_free); #endif @@ -983,7 +1034,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) if (check_gpio(gpio) < 0) return -EINVAL; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (unlikely(is_reserved(peri, gpio, 1))) { if (system_state == SYSTEM_BOOTING) @@ -991,7 +1042,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n", gpio, get_label(gpio)); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -EBUSY; } if (unlikely(is_reserved(gpio, gpio, 1))) @@ -1002,7 +1053,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) reserve(gpio_irq, gpio); set_label(gpio, label); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); port_setup(gpio, GPIO_USAGE); @@ -1016,13 +1067,13 @@ void bfin_gpio_irq_free(unsigned gpio) if (check_gpio(gpio) < 0) return; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (unlikely(!is_reserved(gpio_irq, gpio, 0))) { if (system_state == SYSTEM_BOOTING) dump_stack(); gpio_error(gpio); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return; } @@ -1030,7 +1081,7 @@ void bfin_gpio_irq_free(unsigned gpio) set_label(gpio, "free"); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } static inline void __bfin_gpio_direction_input(unsigned gpio) @@ -1052,10 +1103,10 @@ int bfin_gpio_direction_input(unsigned gpio) return -EINVAL; } - local_irq_save_hw(flags); + flags = hard_local_irq_save(); __bfin_gpio_direction_input(gpio); AWA_DUMMY_READ(inen); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 0; } @@ -1070,9 +1121,9 @@ void bfin_gpio_irq_prepare(unsigned gpio) port_setup(gpio, GPIO_USAGE); #ifdef CONFIG_BF54x - local_irq_save_hw(flags); + flags = hard_local_irq_save(); __bfin_gpio_direction_input(gpio); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); #endif } @@ -1094,7 +1145,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) return -EINVAL; } - local_irq_save_hw(flags); + flags = hard_local_irq_save(); gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); @@ -1105,7 +1156,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value) #endif AWA_DUMMY_READ(dir); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 0; } @@ -1120,11 +1171,11 @@ int bfin_gpio_get_value(unsigned gpio) if (unlikely(get_gpio_edge(gpio))) { int ret; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); set_gpio_edge(gpio, 0); ret = get_gpio_data(gpio); set_gpio_edge(gpio, 1); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return ret; } else return get_gpio_data(gpio); diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c index 87b25b1b30e..8de92299b3e 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c @@ -318,7 +318,7 @@ void flush_switched_cplbs(unsigned int cpu) nr_cplb_flush[cpu]++; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); _disable_icplb(); for (i = first_switched_icplb; i < MAX_CPLBS; i++) { icplb_tbl[cpu][i].data = 0; @@ -332,7 +332,7 @@ void flush_switched_cplbs(unsigned int cpu) bfin_write32(DCPLB_DATA0 + i * 4, 0); } _enable_dcplb(); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } @@ -348,7 +348,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu) return; } - local_irq_save_hw(flags); + flags = hard_local_irq_save(); current_rwx_mask[cpu] = masks; if (L2_LENGTH && addr >= L2_START && addr < L2_START + L2_LENGTH) { @@ -373,5 +373,5 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu) addr += PAGE_SIZE; } _enable_dcplb(); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index 1a496cd71ba..3b1da4aff2a 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c @@ -219,10 +219,10 @@ int __ipipe_syscall_root(struct pt_regs *regs) ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs); - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (!__ipipe_root_domain_p) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 1; } @@ -230,7 +230,7 @@ int __ipipe_syscall_root(struct pt_regs *regs) if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0) __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return -ret; } @@ -239,14 +239,14 @@ unsigned long ipipe_critical_enter(void (*syncfn) (void)) { unsigned long flags; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); return flags; } void ipipe_critical_exit(unsigned long flags) { - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } static void __ipipe_no_irqtail(void) @@ -279,9 +279,9 @@ int ipipe_trigger_irq(unsigned irq) return -EINVAL; #endif - local_irq_save_hw(flags); + flags = hard_local_irq_save(); __ipipe_handle_irq(irq, NULL); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return 1; } @@ -293,7 +293,7 @@ asmlinkage void __ipipe_sync_root(void) BUG_ON(irqs_disabled()); - local_irq_save_hw(flags); + flags = hard_local_irq_save(); if (irq_tail_hook) irq_tail_hook(); @@ -303,7 +303,7 @@ asmlinkage void __ipipe_sync_root(void) if (ipipe_root_cpudom_var(irqpend_himask) != 0) __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } void ___ipipe_sync_pipeline(unsigned long syncmask) @@ -344,10 +344,10 @@ void __ipipe_stall_root(void) { unsigned long *p, flags; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); p = &__ipipe_root_status; __set_bit(IPIPE_STALL_FLAG, p); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(__ipipe_stall_root); @@ -356,10 +356,10 @@ unsigned long __ipipe_test_and_stall_root(void) unsigned long *p, flags; int x; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); p = &__ipipe_root_status; x = __test_and_set_bit(IPIPE_STALL_FLAG, p); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); return x; } @@ -371,10 +371,10 @@ unsigned long __ipipe_test_root(void) unsigned long flags; int x; - local_irq_save_hw_smp(flags); + flags = hard_local_irq_save_smp(); p = &__ipipe_root_status; x = test_bit(IPIPE_STALL_FLAG, p); - local_irq_restore_hw_smp(flags); + hard_local_irq_restore_smp(flags); return x; } @@ -384,10 +384,10 @@ void __ipipe_lock_root(void) { unsigned long *p, flags; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); p = &__ipipe_root_status; __set_bit(IPIPE_SYNCDEFER_FLAG, p); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(__ipipe_lock_root); @@ -395,9 +395,9 @@ void __ipipe_unlock_root(void) { unsigned long *p, flags; - local_irq_save_hw(flags); + flags = hard_local_irq_save(); p = &__ipipe_root_status; __clear_bit(IPIPE_SYNCDEFER_FLAG, p); - local_irq_restore_hw(flags); + hard_local_irq_restore(flags); } EXPORT_SYMBOL(__ipipe_unlock_root); diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c index 9a4b0759438..08c0236acf3 100644 --- a/arch/blackfin/kernel/kgdb_test.c +++ b/arch/blackfin/kernel/kgdb_test.c @@ -88,6 +88,7 @@ static const struct file_operations kgdb_test_proc_fops = { .owner = THIS_MODULE, .read = kgdb_test_proc_read, .write = kgdb_test_proc_write, + .llseek = noop_llseek, }; static int __init kgdbtest_init(void) diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 01f98cb964d..cd0c090ebc5 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c @@ -65,11 +65,11 @@ static void default_idle(void) #ifdef CONFIG_IPIPE ipipe_suspend_domain(); #endif - local_irq_disable_hw(); + hard_local_irq_disable(); if (!need_resched()) idle_with_irq_disabled(); - local_irq_enable_hw(); + hard_local_irq_enable(); } /* @@ -493,6 +493,11 @@ int _access_ok(unsigned long addr, unsigned long size) return 1; #endif +#ifndef CONFIG_EXCEPTION_L1_SCRATCH + if (in_mem_const(addr, size, (unsigned long)l1_stack_base, l1_stack_len)) + return 1; +#endif + aret = in_async(addr, size); if (aret < 2) return aret; diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 6ec77685df5..b3583935413 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c @@ -27,6 +27,7 @@ #include <asm/fixed_code.h> #include <asm/cacheflush.h> #include <asm/mem_map.h> +#include <asm/mmu_context.h> /* * does not yet catch signals sent when the child dies. @@ -113,8 +114,8 @@ put_reg(struct task_struct *task, long regno, unsigned long data) /* * check that an address falls within the bounds of the target process's memory mappings */ -static inline int is_user_addr_valid(struct task_struct *child, - unsigned long start, unsigned long len) +int +is_user_addr_valid(struct task_struct *child, unsigned long start, unsigned long len) { struct vm_area_struct *vma; struct sram_list_struct *sraml; @@ -135,6 +136,13 @@ static inline int is_user_addr_valid(struct task_struct *child, if (start >= FIXED_CODE_START && start + len < FIXED_CODE_END) return 0; +#ifdef CONFIG_APP_STACK_L1 + if (child->mm->context.l1_stack_save) + if (start >= (unsigned long)l1_stack_base && + start + len < (unsigned long)l1_stack_base + l1_stack_len) + return 0; +#endif + return -EIO; } diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index bdc1e2f0da3..89448ed7065 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c @@ -21,6 +21,8 @@ #include <asm/cacheflush.h> #include <asm/dma.h> +#include <asm/cachectl.h> +#include <asm/ptrace.h> asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) { @@ -70,3 +72,16 @@ asmlinkage int sys_bfin_spinlock(int *p) return ret; } + +SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, len, int, op) +{ + if (is_user_addr_valid(current, addr, len) != 0) + return -EINVAL; + + if (op & DCACHE) + blackfin_dcache_flush_range(addr, addr + len); + if (op & ICACHE) + blackfin_icache_flush_range(addr, addr + len); + + return 0; +} diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c index 59fcdf6b013..05b550891ce 100644 --- a/arch/blackfin/kernel/trace.c +++ b/arch/blackfin/kernel/trace.c @@ -15,6 +15,7 @@ #include <linux/kallsyms.h> #include <linux/err.h> #include <linux/fs.h> +#include <linux/irq.h> #include <asm/dma.h> #include <asm/trace.h> #include <asm/fixed_code.h> |