diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /arch/blackfin/kernel | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 159 |
2 files changed, 143 insertions, 19 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 703dc7c..735f24e 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -7,7 +7,7 @@ extra-y := vmlinux.lds obj-y := \ entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ - fixed_code.o reboot.o bfin_dma.o \ + fixed_code.o reboot.o bfin_gpio.o bfin_dma.o \ exception.o dumpstack.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) @@ -16,7 +16,6 @@ else obj-y += time.o endif -obj-$(CONFIG_GPIO_ADI) += bfin_gpio.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index a017359..ed978f1 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -11,8 +11,11 @@ #include <linux/err.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> -#include <linux/gpio.h> +#include <asm/blackfin.h> +#include <asm/gpio.h> +#include <asm/portmux.h> #include <linux/irq.h> +#include <asm/irq_handler.h> #if ANOMALY_05000311 || ANOMALY_05000323 enum { @@ -55,6 +58,19 @@ static struct gpio_port_t * const gpio_array[] = { (struct gpio_port_t *) FIO0_FLAG_D, (struct gpio_port_t *) FIO1_FLAG_D, (struct gpio_port_t *) FIO2_FLAG_D, +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + (struct gpio_port_t *)PORTA_FER, + (struct gpio_port_t *)PORTB_FER, + (struct gpio_port_t *)PORTC_FER, + (struct gpio_port_t *)PORTD_FER, + (struct gpio_port_t *)PORTE_FER, + (struct gpio_port_t *)PORTF_FER, + (struct gpio_port_t *)PORTG_FER, +# if defined(CONFIG_BF54x) + (struct gpio_port_t *)PORTH_FER, + (struct gpio_port_t *)PORTI_FER, + (struct gpio_port_t *)PORTJ_FER, +# endif #else # error no gpio arrays defined #endif @@ -153,6 +169,12 @@ DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM); inline int check_gpio(unsigned gpio) { +#if defined(CONFIG_BF54x) + if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15 + || gpio == GPIO_PH14 || gpio == GPIO_PH15 + || gpio == GPIO_PJ14 || gpio == GPIO_PJ15) + return -EINVAL; +#endif if (gpio >= MAX_BLACKFIN_GPIOS) return -EINVAL; return 0; @@ -190,6 +212,12 @@ static void port_setup(unsigned gpio, unsigned short usage) else *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); SSYNC(); +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + if (usage == GPIO_USAGE) + gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); + else + gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio); + SSYNC(); #endif } @@ -227,7 +255,7 @@ static int portmux_group_check(unsigned short per) u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); s8 offset = port_mux[ident]; - u16 m, pmux, pfunc, mask; + u16 m, pmux, pfunc; if (offset < 0) return 0; @@ -242,12 +270,10 @@ static int portmux_group_check(unsigned short per) continue; if (offset == 1) - mask = 3; + pfunc = (pmux >> offset) & 3; else - mask = 1; - - pfunc = (pmux >> offset) & mask; - if (pfunc != (function & mask)) { + 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; @@ -262,21 +288,43 @@ static void portmux_setup(unsigned short per) u16 ident = P_IDENT(per); u16 function = P_FUNCT2MUX(per); s8 offset = port_mux[ident]; - u16 pmux, mask; + u16 pmux; if (offset == -1) return; pmux = bfin_read_PORT_MUX(); - if (offset == 1) - mask = 3; + if (offset != 1) + pmux &= ~(1 << offset); else - mask = 1; + pmux &= ~(3 << 1); + pmux |= (function << offset); + bfin_write_PORT_MUX(pmux); +} +#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) +inline void portmux_setup(unsigned short per) +{ + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); + u32 pmux; - pmux &= ~(mask << offset); - pmux |= ((function & mask) << offset); + pmux = gpio_array[gpio_bank(ident)]->port_mux; - bfin_write_PORT_MUX(pmux); + pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); + pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); + + gpio_array[gpio_bank(ident)]->port_mux = pmux; +} + +inline u16 get_portmux(unsigned short per) +{ + u16 ident = P_IDENT(per); + 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) @@ -331,6 +379,7 @@ static int portmux_group_check(unsigned short per) } #endif +#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) /*********************************************************** * * FUNCTIONS: Blackfin General Purpose Ports Access Functions @@ -523,7 +572,7 @@ static const unsigned int sic_iwr_irqs[] = { ************************************************************* * MODIFICATION HISTORY : **************************************************************/ -int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) +int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) { unsigned long flags; @@ -542,7 +591,7 @@ int bfin_gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl) return 0; } -int bfin_gpio_pm_standby_ctrl(unsigned ctrl) +int bfin_pm_standby_ctrl(unsigned ctrl) { u16 bank, mask, i; @@ -633,6 +682,53 @@ void bfin_gpio_pm_hibernate_restore(void) #endif +#else /* CONFIG_BF54x || CONFIG_BF60x */ +#ifdef CONFIG_PM + +int bfin_pm_standby_ctrl(unsigned ctrl) +{ + return 0; +} + +void bfin_gpio_pm_hibernate_suspend(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + + gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; + gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; + gpio_bank_saved[bank].data = gpio_array[bank]->data; + gpio_bank_saved[bank].inen = gpio_array[bank]->inen; + gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; + } +} + +void bfin_gpio_pm_hibernate_restore(void) +{ + int i, bank; + + for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { + bank = gpio_bank(i); + + gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; + gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; + gpio_array[bank]->inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->data_set = gpio_bank_saved[bank].data + & gpio_bank_saved[bank].dir; + gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; + } +} +#endif + +unsigned short get_gpio_dir(unsigned gpio) +{ + return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); +} +EXPORT_SYMBOL(get_gpio_dir); + +#endif /* CONFIG_BF54x || CONFIG_BF60x */ /*********************************************************** * @@ -689,7 +785,11 @@ int peripheral_request(unsigned short per, const char *label) * be requested and used by several drivers */ +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { +#else if (!(per & P_MAYSHARE)) { +#endif /* * Allow that the identical pin function can * be requested from the same driver twice @@ -838,9 +938,12 @@ int bfin_gpio_request(unsigned gpio, const char *label) if (unlikely(is_reserved(gpio_irq, gpio, 1))) { printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); - } else { /* Reset POLAR setting when acquiring a gpio for the first time */ + } +#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) + else { /* Reset POLAR setting when acquiring a gpio for the first time */ set_gpio_polar(gpio, 0); } +#endif reserve(gpio, gpio); set_label(gpio, label); @@ -1009,7 +1112,11 @@ void bfin_gpio_irq_free(unsigned gpio) static inline void __bfin_gpio_direction_input(unsigned gpio) { +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); +#else gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); +#endif gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); } @@ -1033,7 +1140,17 @@ EXPORT_SYMBOL(bfin_gpio_direction_input); void bfin_gpio_irq_prepare(unsigned gpio) { +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + unsigned long flags; +#endif + port_setup(gpio, GPIO_USAGE); + +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + flags = hard_local_irq_save(); + __bfin_gpio_direction_input(gpio); + hard_local_irq_restore(flags); +#endif } void bfin_gpio_set_value(unsigned gpio, int arg) @@ -1058,7 +1175,11 @@ int bfin_gpio_direction_output(unsigned gpio, int value) gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); gpio_set_value(gpio, value); +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); +#else gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); +#endif AWA_DUMMY_READ(dir); hard_local_irq_restore(flags); @@ -1069,6 +1190,9 @@ EXPORT_SYMBOL(bfin_gpio_direction_output); int bfin_gpio_get_value(unsigned gpio) { +#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) + return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); +#else unsigned long flags; if (unlikely(get_gpio_edge(gpio))) { @@ -1081,6 +1205,7 @@ int bfin_gpio_get_value(unsigned gpio) return ret; } else return get_gpio_data(gpio); +#endif } EXPORT_SYMBOL(bfin_gpio_get_value); |