Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: orion: Refactor the MPP code common in the orion platform

mv78xx0 and kirkwood use identical mpp code.

It should also be possible to rewrite the orion5x mpp to use this
platform code.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>

authored by

Andrew Lunn and committed by
Nicolas Pitre
b2f427a1 44350061

+122 -123
+3 -55
arch/arm/mach-kirkwood/mpp.c
··· 14 14 #include <linux/io.h> 15 15 #include <asm/gpio.h> 16 16 #include <mach/hardware.h> 17 + #include <plat/mpp.h> 17 18 #include "common.h" 18 19 #include "mpp.h" 19 20 ··· 37 36 return 0; 38 37 } 39 38 40 - #define MPP_CTRL(i) (DEV_BUS_VIRT_BASE + (i) * 4) 41 - #define MPP_NR_REGS (1 + MPP_MAX/8) 42 - 43 39 void __init kirkwood_mpp_conf(unsigned int *mpp_list) 44 40 { 45 - u32 mpp_ctrl[MPP_NR_REGS]; 46 - unsigned int variant_mask; 47 - int i; 48 - 49 - variant_mask = kirkwood_variant(); 50 - if (!variant_mask) 51 - return; 52 - 53 - printk(KERN_DEBUG "initial MPP regs:"); 54 - for (i = 0; i < MPP_NR_REGS; i++) { 55 - mpp_ctrl[i] = readl(MPP_CTRL(i)); 56 - printk(" %08x", mpp_ctrl[i]); 57 - } 58 - printk("\n"); 59 - 60 - for ( ; *mpp_list; mpp_list++) { 61 - unsigned int num = MPP_NUM(*mpp_list); 62 - unsigned int sel = MPP_SEL(*mpp_list); 63 - int shift, gpio_mode; 64 - 65 - if (num > MPP_MAX) { 66 - printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP " 67 - "number (%u)\n", num); 68 - continue; 69 - } 70 - if (!(*mpp_list & variant_mask)) { 71 - printk(KERN_WARNING 72 - "kirkwood_mpp_conf: requested MPP%u config " 73 - "unavailable on this hardware\n", num); 74 - continue; 75 - } 76 - 77 - shift = (num & 7) << 2; 78 - mpp_ctrl[num / 8] &= ~(0xf << shift); 79 - mpp_ctrl[num / 8] |= sel << shift; 80 - 81 - gpio_mode = 0; 82 - if (*mpp_list & MPP_INPUT_MASK) 83 - gpio_mode |= GPIO_INPUT_OK; 84 - if (*mpp_list & MPP_OUTPUT_MASK) 85 - gpio_mode |= GPIO_OUTPUT_OK; 86 - if (sel != 0) 87 - gpio_mode = 0; 88 - orion_gpio_set_valid(num, gpio_mode); 89 - } 90 - 91 - printk(KERN_DEBUG " final MPP regs:"); 92 - for (i = 0; i < MPP_NR_REGS; i++) { 93 - writel(mpp_ctrl[i], MPP_CTRL(i)); 94 - printk(" %08x", mpp_ctrl[i]); 95 - } 96 - printk("\n"); 41 + orion_mpp_conf(mpp_list, kirkwood_variant(), 42 + MPP_MAX, DEV_BUS_VIRT_BASE); 97 43 }
-6
arch/arm/mach-kirkwood/mpp.h
··· 22 22 /* available on F6281 */ ((!!(_F6281)) << 17) | \ 23 23 /* available on F6282 */ ((!!(_F6282)) << 18)) 24 24 25 - #define MPP_NUM(x) ((x) & 0xff) 26 - #define MPP_SEL(x) (((x) >> 8) & 0xf) 27 - 28 25 /* num sel i o 6180 6190 6192 6281 6282 */ 29 - 30 - #define MPP_INPUT_MASK MPP( 0, 0x0, 1, 0, 0, 0, 0, 0, 0 ) 31 - #define MPP_OUTPUT_MASK MPP( 0, 0x0, 0, 1, 0, 0, 0, 0, 0 ) 32 26 33 27 #define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0, 0 ) 34 28 #define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0, 0 )
+3 -55
arch/arm/mach-mv78xx0/mpp.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/mbus.h> 14 14 #include <linux/io.h> 15 + #include <plat/mpp.h> 15 16 #include <asm/gpio.h> 16 17 #include <mach/hardware.h> 17 18 #include "common.h" ··· 32 31 return 0; 33 32 } 34 33 35 - #define MPP_CTRL(i) (DEV_BUS_VIRT_BASE + (i) * 4) 36 - #define MPP_NR_REGS (1 + MPP_MAX/8) 37 - 38 34 void __init mv78xx0_mpp_conf(unsigned int *mpp_list) 39 35 { 40 - u32 mpp_ctrl[MPP_NR_REGS]; 41 - unsigned int variant_mask; 42 - int i; 43 - 44 - variant_mask = mv78xx0_variant(); 45 - if (!variant_mask) 46 - return; 47 - 48 - printk(KERN_DEBUG "initial MPP regs:"); 49 - for (i = 0; i < MPP_NR_REGS; i++) { 50 - mpp_ctrl[i] = readl(MPP_CTRL(i)); 51 - printk(" %08x", mpp_ctrl[i]); 52 - } 53 - printk("\n"); 54 - 55 - for ( ; *mpp_list; mpp_list++) { 56 - unsigned int num = MPP_NUM(*mpp_list); 57 - unsigned int sel = MPP_SEL(*mpp_list); 58 - int shift, gpio_mode; 59 - 60 - if (num > MPP_MAX) { 61 - printk(KERN_ERR "mv78xx0_mpp_conf: invalid MPP " 62 - "number (%u)\n", num); 63 - continue; 64 - } 65 - if (!(*mpp_list & variant_mask)) { 66 - printk(KERN_WARNING 67 - "mv78xx0_mpp_conf: requested MPP%u config " 68 - "unavailable on this hardware\n", num); 69 - continue; 70 - } 71 - 72 - shift = (num & 7) << 2; 73 - mpp_ctrl[num / 8] &= ~(0xf << shift); 74 - mpp_ctrl[num / 8] |= sel << shift; 75 - 76 - gpio_mode = 0; 77 - if (*mpp_list & MPP_INPUT_MASK) 78 - gpio_mode |= GPIO_INPUT_OK; 79 - if (*mpp_list & MPP_OUTPUT_MASK) 80 - gpio_mode |= GPIO_OUTPUT_OK; 81 - if (sel != 0) 82 - gpio_mode = 0; 83 - orion_gpio_set_valid(num, gpio_mode); 84 - } 85 - 86 - printk(KERN_DEBUG " final MPP regs:"); 87 - for (i = 0; i < MPP_NR_REGS; i++) { 88 - writel(mpp_ctrl[i], MPP_CTRL(i)); 89 - printk(" %08x", mpp_ctrl[i]); 90 - } 91 - printk("\n"); 36 + orion_mpp_conf(mpp_list, mv78xx0_variant(), 37 + MPP_MAX, DEV_BUS_VIRT_BASE); 92 38 }
-6
arch/arm/mach-mv78xx0/mpp.h
··· 19 19 /* may be output signal */ ((!!(_out)) << 13) | \ 20 20 /* available on A0 */ ((!!(_78100_A0)) << 14)) 21 21 22 - #define MPP_NUM(x) ((x) & 0xff) 23 - #define MPP_SEL(x) (((x) >> 8) & 0xf) 24 - 25 22 /* num sel i o 78100_A0 */ 26 - 27 - #define MPP_INPUT_MASK MPP(0, 0x0, 1, 0, 0) 28 - #define MPP_OUTPUT_MASK MPP(0, 0x0, 0, 1, 0) 29 23 30 24 #define MPP_78100_A0_MASK MPP(0, 0x0, 0, 0, 1) 31 25
+1 -1
arch/arm/plat-orion/Makefile
··· 2 2 # Makefile for the linux kernel. 3 3 # 4 4 5 - obj-y := irq.o pcie.o time.o common.o 5 + obj-y := irq.o pcie.o time.o common.o mpp.o 6 6 obj-m := 7 7 obj-n := 8 8 obj- :=
+34
arch/arm/plat-orion/include/plat/mpp.h
··· 1 + /* 2 + * arch/arm/plat-orion/include/plat/mpp.h 3 + * 4 + * Marvell Orion SoC MPP handling. 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + #ifndef __PLAT_MPP_H 12 + #define __PLAT_MPP_H 13 + 14 + #define MPP_NUM(x) ((x) & 0xff) 15 + #define MPP_SEL(x) (((x) >> 8) & 0xf) 16 + 17 + /* This is the generic MPP macro, without any variant information. 18 + Each machine architecture is expected to extend this with further 19 + bit fields indicating which MPP configurations are valid for a 20 + specific variant. */ 21 + 22 + #define GENERIC_MPP(_num, _sel, _in, _out) ( \ 23 + /* MPP number */ ((_num) & 0xff) | \ 24 + /* MPP select value */ (((_sel) & 0xf) << 8) | \ 25 + /* may be input signal */ ((!!(_in)) << 12) | \ 26 + /* may be output signal */ ((!!(_out)) << 13)) 27 + 28 + #define MPP_INPUT_MASK GENERIC_MPP(0, 0x0, 1, 0) 29 + #define MPP_OUTPUT_MASK GENERIC_MPP(0, 0x0, 0, 1) 30 + 31 + void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask, 32 + unsigned int mpp_max, unsigned int dev_bus); 33 + 34 + #endif
+81
arch/arm/plat-orion/mpp.c
··· 1 + /* 2 + * arch/arm/plat-orion/mpp.c 3 + * 4 + * MPP functions for Marvell orion SoCs 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/init.h> 13 + #include <linux/mbus.h> 14 + #include <linux/io.h> 15 + #include <linux/gpio.h> 16 + #include <mach/hardware.h> 17 + #include <plat/mpp.h> 18 + 19 + /* Address of the ith MPP control register */ 20 + static __init unsigned long mpp_ctrl_addr(unsigned int i, 21 + unsigned long dev_bus) 22 + { 23 + return dev_bus + (i) * 4; 24 + } 25 + 26 + 27 + void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask, 28 + unsigned int mpp_max, unsigned int dev_bus) 29 + { 30 + unsigned int mpp_nr_regs = (1 + mpp_max/8); 31 + u32 mpp_ctrl[mpp_nr_regs]; 32 + int i; 33 + 34 + if (!variant_mask) 35 + return; 36 + 37 + printk(KERN_DEBUG "initial MPP regs:"); 38 + for (i = 0; i < mpp_nr_regs; i++) { 39 + mpp_ctrl[i] = readl(mpp_ctrl_addr(i, dev_bus)); 40 + printk(" %08x", mpp_ctrl[i]); 41 + } 42 + printk("\n"); 43 + 44 + for ( ; *mpp_list; mpp_list++) { 45 + unsigned int num = MPP_NUM(*mpp_list); 46 + unsigned int sel = MPP_SEL(*mpp_list); 47 + int shift, gpio_mode; 48 + 49 + if (num > mpp_max) { 50 + printk(KERN_ERR "orion_mpp_conf: invalid MPP " 51 + "number (%u)\n", num); 52 + continue; 53 + } 54 + if (!(*mpp_list & variant_mask)) { 55 + printk(KERN_WARNING 56 + "orion_mpp_conf: requested MPP%u config " 57 + "unavailable on this hardware\n", num); 58 + continue; 59 + } 60 + 61 + shift = (num & 7) << 2; 62 + mpp_ctrl[num / 8] &= ~(0xf << shift); 63 + mpp_ctrl[num / 8] |= sel << shift; 64 + 65 + gpio_mode = 0; 66 + if (*mpp_list & MPP_INPUT_MASK) 67 + gpio_mode |= GPIO_INPUT_OK; 68 + if (*mpp_list & MPP_OUTPUT_MASK) 69 + gpio_mode |= GPIO_OUTPUT_OK; 70 + if (sel != 0) 71 + gpio_mode = 0; 72 + orion_gpio_set_valid(num, gpio_mode); 73 + } 74 + 75 + printk(KERN_DEBUG " final MPP regs:"); 76 + for (i = 0; i < mpp_nr_regs; i++) { 77 + writel(mpp_ctrl[i], mpp_ctrl_addr(i, dev_bus)); 78 + printk(" %08x", mpp_ctrl[i]); 79 + } 80 + printk("\n"); 81 + }