diff options
-rw-r--r-- | arch/x86/kernel/geode_32.c | 48 | ||||
-rw-r--r-- | include/asm-x86/geode.h | 12 |
2 files changed, 42 insertions, 18 deletions
diff --git a/arch/x86/kernel/geode_32.c b/arch/x86/kernel/geode_32.c index f12d8c5d9809..9c7f7d395968 100644 --- a/arch/x86/kernel/geode_32.c +++ b/arch/x86/kernel/geode_32.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * AMD Geode southbridge support code | 2 | * AMD Geode southbridge support code |
3 | * Copyright (C) 2006, Advanced Micro Devices, Inc. | 3 | * Copyright (C) 2006, Advanced Micro Devices, Inc. |
4 | * Copyright (C) 2007, Andres Salomon <dilinger@debian.org> | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of version 2 of the GNU General Public License | 7 | * modify it under the terms of version 2 of the GNU General Public License |
@@ -51,45 +52,62 @@ EXPORT_SYMBOL_GPL(geode_get_dev_base); | |||
51 | 52 | ||
52 | /* === GPIO API === */ | 53 | /* === GPIO API === */ |
53 | 54 | ||
54 | void geode_gpio_set(unsigned int gpio, unsigned int reg) | 55 | void geode_gpio_set(u32 gpio, unsigned int reg) |
55 | { | 56 | { |
56 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); | 57 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); |
57 | 58 | ||
58 | if (!base) | 59 | if (!base) |
59 | return; | 60 | return; |
60 | 61 | ||
61 | if (gpio < 16) | 62 | /* low bank register */ |
62 | outl(1 << gpio, base + reg); | 63 | if (gpio & 0xFFFF) |
63 | else | 64 | outl(gpio & 0xFFFF, base + reg); |
64 | outl(1 << (gpio - 16), base + 0x80 + reg); | 65 | /* high bank register */ |
66 | gpio >>= 16; | ||
67 | if (gpio) | ||
68 | outl(gpio, base + 0x80 + reg); | ||
65 | } | 69 | } |
66 | EXPORT_SYMBOL_GPL(geode_gpio_set); | 70 | EXPORT_SYMBOL_GPL(geode_gpio_set); |
67 | 71 | ||
68 | void geode_gpio_clear(unsigned int gpio, unsigned int reg) | 72 | void geode_gpio_clear(u32 gpio, unsigned int reg) |
69 | { | 73 | { |
70 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); | 74 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); |
71 | 75 | ||
72 | if (!base) | 76 | if (!base) |
73 | return; | 77 | return; |
74 | 78 | ||
75 | if (gpio < 16) | 79 | /* low bank register */ |
76 | outl(1 << (gpio + 16), base + reg); | 80 | if (gpio & 0xFFFF) |
77 | else | 81 | outl((gpio & 0xFFFF) << 16, base + reg); |
78 | outl(1 << gpio, base + 0x80 + reg); | 82 | /* high bank register */ |
83 | gpio &= (0xFFFF << 16); | ||
84 | if (gpio) | ||
85 | outl(gpio, base + 0x80 + reg); | ||
79 | } | 86 | } |
80 | EXPORT_SYMBOL_GPL(geode_gpio_clear); | 87 | EXPORT_SYMBOL_GPL(geode_gpio_clear); |
81 | 88 | ||
82 | int geode_gpio_isset(unsigned int gpio, unsigned int reg) | 89 | int geode_gpio_isset(u32 gpio, unsigned int reg) |
83 | { | 90 | { |
84 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); | 91 | u32 base = geode_get_dev_base(GEODE_DEV_GPIO); |
92 | u32 val; | ||
85 | 93 | ||
86 | if (!base) | 94 | if (!base) |
87 | return 0; | 95 | return 0; |
88 | 96 | ||
89 | if (gpio < 16) | 97 | /* low bank register */ |
90 | return (inl(base + reg) & (1 << gpio)) ? 1 : 0; | 98 | if (gpio & 0xFFFF) { |
91 | else | 99 | val = inl(base + reg) & (gpio & 0xFFFF); |
92 | return (inl(base + 0x80 + reg) & (1 << (gpio - 16))) ? 1 : 0; | 100 | if ((gpio & 0xFFFF) == val) |
101 | return 1; | ||
102 | } | ||
103 | /* high bank register */ | ||
104 | gpio >>= 16; | ||
105 | if (gpio) { | ||
106 | val = inl(base + 0x80 + reg) & gpio; | ||
107 | if (gpio == val) | ||
108 | return 1; | ||
109 | } | ||
110 | return 0; | ||
93 | } | 111 | } |
94 | EXPORT_SYMBOL_GPL(geode_gpio_isset); | 112 | EXPORT_SYMBOL_GPL(geode_gpio_isset); |
95 | 113 | ||
diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h index 771af336734f..811fe14f70b2 100644 --- a/include/asm-x86/geode.h +++ b/include/asm-x86/geode.h | |||
@@ -121,9 +121,15 @@ extern int geode_get_dev_base(unsigned int dev); | |||
121 | #define GPIO_MAP_Z 0xE8 | 121 | #define GPIO_MAP_Z 0xE8 |
122 | #define GPIO_MAP_W 0xEC | 122 | #define GPIO_MAP_W 0xEC |
123 | 123 | ||
124 | extern void geode_gpio_set(unsigned int, unsigned int); | 124 | static inline u32 geode_gpio(unsigned int nr) |
125 | extern void geode_gpio_clear(unsigned int, unsigned int); | 125 | { |
126 | extern int geode_gpio_isset(unsigned int, unsigned int); | 126 | BUG_ON(nr > 28); |
127 | return 1 << nr; | ||
128 | } | ||
129 | |||
130 | extern void geode_gpio_set(u32, unsigned int); | ||
131 | extern void geode_gpio_clear(u32, unsigned int); | ||
132 | extern int geode_gpio_isset(u32, unsigned int); | ||
127 | extern void geode_gpio_setup_event(unsigned int, int, int); | 133 | extern void geode_gpio_setup_event(unsigned int, int, int); |
128 | extern void geode_gpio_set_irq(unsigned int, unsigned int); | 134 | extern void geode_gpio_set_irq(unsigned int, unsigned int); |
129 | 135 | ||