diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 20:20:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-30 20:20:32 -0500 |
commit | cdfc83075fb76369a31e6c187d0cebcab9f8b9c8 (patch) | |
tree | 33d1cdca3e2cb610451ed30943189f55652bac4c /drivers | |
parent | 04a24ae45d018e177db7e4ae2d03a70f79149782 (diff) | |
parent | b26a21c1eacdb7daf22a304fa857413df2650cfe (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"The most notable new addition inside this pull request is the support
for MIPS's latest and greatest core called "inter/proAptiv". The
patch series describes this core as follows.
"The interAptiv is a power-efficient multi-core microprocessor
for use in system-on-chip (SoC) applications. The interAptiv combines
a multi-threading pipeline with a coherence manager to deliver improved
computational throughput and power efficiency. The interAptiv can
contain one to four MIPS32R3 interAptiv cores, system level
coherence manager with L2 cache, optional coherent I/O port,
and optional floating point unit."
The platform specific patches touch all 3 Broadcom families. It adds
support for the new Broadcom/Netlogix XLP9xx Soc, building a common
BCM63XX SMP kernel for all BCM63XX SoCs regardless of core type/count
and full gpio button/led descriptions for BCM47xx.
The rest of the series are cleanups and bug fixes that are MIPS
generic and consist largely of changes that Imgtec/MIPS had published
in their linux-mti-3.10.git stable tree. Random other cleanups and
patches preparing code to be merged in 3.15"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
mips: select ARCH_MIGHT_HAVE_PC_SERIO
mips: delete non-required instances of include <linux/init.h>
MIPS: KVM: remove shadow_tlb code
MIPS: KVM: use common EHINV aware UNIQUE_ENTRYHI
mips/ide: flush dcache also if icache does not snoop dcache
MIPS: BCM47XX: fix position of cpu_wait disabling
MIPS: BCM63XX: select correct MIPS_L1_CACHE_SHIFT value
MIPS: update MIPS_L1_CACHE_SHIFT based on MIPS_L1_CACHE_SHIFT_<N>
MIPS: introduce MIPS_L1_CACHE_SHIFT_<N>
MIPS: ZBOOT: gather string functions into string.c
arch/mips/pci: don't check resource with devm_ioremap_resource
arch/mips/lantiq/xway: don't check resource with devm_ioremap_resource
bcma: gpio: don't cast u32 to unsigned long
ssb: gpio: add own IRQ domain
MIPS: BCM47XX: fix sparse warnings in board.c
MIPS: BCM47XX: add board detection for Linksys WRT54GS V1
MIPS: BCM47XX: fix detection for some boards
MIPS: BCM47XX: Enable buttons support on SSB
MIPS: BCM47XX: Convert WNDR4500 to new syntax
MIPS: BCM47XX: Use "timer" trigger for status LEDs
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bcma/Kconfig | 1 | ||||
-rw-r--r-- | drivers/bcma/driver_gpio.c | 137 | ||||
-rw-r--r-- | drivers/ssb/Kconfig | 1 | ||||
-rw-r--r-- | drivers/ssb/driver_gpio.c | 306 | ||||
-rw-r--r-- | drivers/ssb/main.c | 12 | ||||
-rw-r--r-- | drivers/tty/serial/bcm63xx_uart.c | 9 |
6 files changed, 437 insertions, 29 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 7c081b38ef3e..0ee48be23837 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
@@ -75,6 +75,7 @@ config BCMA_DRIVER_GMAC_CMN | |||
75 | config BCMA_DRIVER_GPIO | 75 | config BCMA_DRIVER_GPIO |
76 | bool "BCMA GPIO driver" | 76 | bool "BCMA GPIO driver" |
77 | depends on BCMA && GPIOLIB | 77 | depends on BCMA && GPIOLIB |
78 | select IRQ_DOMAIN if BCMA_HOST_SOC | ||
78 | help | 79 | help |
79 | Driver to provide access to the GPIO pins of the bcma bus. | 80 | Driver to provide access to the GPIO pins of the bcma bus. |
80 | 81 | ||
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 45f0996a3752..25f9887a35d0 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c | |||
@@ -9,6 +9,9 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/gpio.h> | 11 | #include <linux/gpio.h> |
12 | #include <linux/irq.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irqdomain.h> | ||
12 | #include <linux/export.h> | 15 | #include <linux/export.h> |
13 | #include <linux/bcma/bcma.h> | 16 | #include <linux/bcma/bcma.h> |
14 | 17 | ||
@@ -73,19 +76,136 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio) | |||
73 | bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); | 76 | bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); |
74 | } | 77 | } |
75 | 78 | ||
79 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) | ||
76 | static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | 80 | static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) |
77 | { | 81 | { |
78 | struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); | 82 | struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); |
79 | 83 | ||
80 | if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) | 84 | if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC) |
81 | return bcma_core_irq(cc->core); | 85 | return irq_find_mapping(cc->irq_domain, gpio); |
82 | else | 86 | else |
83 | return -EINVAL; | 87 | return -EINVAL; |
84 | } | 88 | } |
85 | 89 | ||
90 | static void bcma_gpio_irq_unmask(struct irq_data *d) | ||
91 | { | ||
92 | struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); | ||
93 | int gpio = irqd_to_hwirq(d); | ||
94 | u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); | ||
95 | |||
96 | bcma_chipco_gpio_polarity(cc, BIT(gpio), val); | ||
97 | bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio)); | ||
98 | } | ||
99 | |||
100 | static void bcma_gpio_irq_mask(struct irq_data *d) | ||
101 | { | ||
102 | struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); | ||
103 | int gpio = irqd_to_hwirq(d); | ||
104 | |||
105 | bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); | ||
106 | } | ||
107 | |||
108 | static struct irq_chip bcma_gpio_irq_chip = { | ||
109 | .name = "BCMA-GPIO", | ||
110 | .irq_mask = bcma_gpio_irq_mask, | ||
111 | .irq_unmask = bcma_gpio_irq_unmask, | ||
112 | }; | ||
113 | |||
114 | static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) | ||
115 | { | ||
116 | struct bcma_drv_cc *cc = dev_id; | ||
117 | u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN); | ||
118 | u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ); | ||
119 | u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL); | ||
120 | unsigned long irqs = (val ^ pol) & mask; | ||
121 | int gpio; | ||
122 | |||
123 | if (!irqs) | ||
124 | return IRQ_NONE; | ||
125 | |||
126 | for_each_set_bit(gpio, &irqs, cc->gpio.ngpio) | ||
127 | generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio)); | ||
128 | bcma_chipco_gpio_polarity(cc, irqs, val & irqs); | ||
129 | |||
130 | return IRQ_HANDLED; | ||
131 | } | ||
132 | |||
133 | static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) | ||
134 | { | ||
135 | struct gpio_chip *chip = &cc->gpio; | ||
136 | int gpio, hwirq, err; | ||
137 | |||
138 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) | ||
139 | return 0; | ||
140 | |||
141 | cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, | ||
142 | &irq_domain_simple_ops, cc); | ||
143 | if (!cc->irq_domain) { | ||
144 | err = -ENODEV; | ||
145 | goto err_irq_domain; | ||
146 | } | ||
147 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
148 | int irq = irq_create_mapping(cc->irq_domain, gpio); | ||
149 | |||
150 | irq_set_chip_data(irq, cc); | ||
151 | irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, | ||
152 | handle_simple_irq); | ||
153 | } | ||
154 | |||
155 | hwirq = bcma_core_irq(cc->core); | ||
156 | err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", | ||
157 | cc); | ||
158 | if (err) | ||
159 | goto err_req_irq; | ||
160 | |||
161 | bcma_chipco_gpio_intmask(cc, ~0, 0); | ||
162 | bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); | ||
163 | |||
164 | return 0; | ||
165 | |||
166 | err_req_irq: | ||
167 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
168 | int irq = irq_find_mapping(cc->irq_domain, gpio); | ||
169 | |||
170 | irq_dispose_mapping(irq); | ||
171 | } | ||
172 | irq_domain_remove(cc->irq_domain); | ||
173 | err_irq_domain: | ||
174 | return err; | ||
175 | } | ||
176 | |||
177 | static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) | ||
178 | { | ||
179 | struct gpio_chip *chip = &cc->gpio; | ||
180 | int gpio; | ||
181 | |||
182 | if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) | ||
183 | return; | ||
184 | |||
185 | bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO); | ||
186 | free_irq(bcma_core_irq(cc->core), cc); | ||
187 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
188 | int irq = irq_find_mapping(cc->irq_domain, gpio); | ||
189 | |||
190 | irq_dispose_mapping(irq); | ||
191 | } | ||
192 | irq_domain_remove(cc->irq_domain); | ||
193 | } | ||
194 | #else | ||
195 | static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) | ||
196 | { | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc) | ||
201 | { | ||
202 | } | ||
203 | #endif | ||
204 | |||
86 | int bcma_gpio_init(struct bcma_drv_cc *cc) | 205 | int bcma_gpio_init(struct bcma_drv_cc *cc) |
87 | { | 206 | { |
88 | struct gpio_chip *chip = &cc->gpio; | 207 | struct gpio_chip *chip = &cc->gpio; |
208 | int err; | ||
89 | 209 | ||
90 | chip->label = "bcma_gpio"; | 210 | chip->label = "bcma_gpio"; |
91 | chip->owner = THIS_MODULE; | 211 | chip->owner = THIS_MODULE; |
@@ -95,7 +215,9 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
95 | chip->set = bcma_gpio_set_value; | 215 | chip->set = bcma_gpio_set_value; |
96 | chip->direction_input = bcma_gpio_direction_input; | 216 | chip->direction_input = bcma_gpio_direction_input; |
97 | chip->direction_output = bcma_gpio_direction_output; | 217 | chip->direction_output = bcma_gpio_direction_output; |
218 | #if IS_BUILTIN(CONFIG_BCMA_HOST_SOC) | ||
98 | chip->to_irq = bcma_gpio_to_irq; | 219 | chip->to_irq = bcma_gpio_to_irq; |
220 | #endif | ||
99 | chip->ngpio = 16; | 221 | chip->ngpio = 16; |
100 | /* There is just one SoC in one device and its GPIO addresses should be | 222 | /* There is just one SoC in one device and its GPIO addresses should be |
101 | * deterministic to address them more easily. The other buses could get | 223 | * deterministic to address them more easily. The other buses could get |
@@ -105,10 +227,21 @@ int bcma_gpio_init(struct bcma_drv_cc *cc) | |||
105 | else | 227 | else |
106 | chip->base = -1; | 228 | chip->base = -1; |
107 | 229 | ||
108 | return gpiochip_add(chip); | 230 | err = bcma_gpio_irq_domain_init(cc); |
231 | if (err) | ||
232 | return err; | ||
233 | |||
234 | err = gpiochip_add(chip); | ||
235 | if (err) { | ||
236 | bcma_gpio_irq_domain_exit(cc); | ||
237 | return err; | ||
238 | } | ||
239 | |||
240 | return 0; | ||
109 | } | 241 | } |
110 | 242 | ||
111 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) | 243 | int bcma_gpio_unregister(struct bcma_drv_cc *cc) |
112 | { | 244 | { |
245 | bcma_gpio_irq_domain_exit(cc); | ||
113 | return gpiochip_remove(&cc->gpio); | 246 | return gpiochip_remove(&cc->gpio); |
114 | } | 247 | } |
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index 2cd9b0e44a41..75b3603906c1 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig | |||
@@ -168,6 +168,7 @@ config SSB_DRIVER_GIGE | |||
168 | config SSB_DRIVER_GPIO | 168 | config SSB_DRIVER_GPIO |
169 | bool "SSB GPIO driver" | 169 | bool "SSB GPIO driver" |
170 | depends on SSB && GPIOLIB | 170 | depends on SSB && GPIOLIB |
171 | select IRQ_DOMAIN if SSB_EMBEDDED | ||
171 | help | 172 | help |
172 | Driver to provide access to the GPIO pins on the bus. | 173 | Driver to provide access to the GPIO pins on the bus. |
173 | 174 | ||
diff --git a/drivers/ssb/driver_gpio.c b/drivers/ssb/driver_gpio.c index dc109de228c6..ba350d2035c0 100644 --- a/drivers/ssb/driver_gpio.c +++ b/drivers/ssb/driver_gpio.c | |||
@@ -9,16 +9,40 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/gpio.h> | 11 | #include <linux/gpio.h> |
12 | #include <linux/irq.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/irqdomain.h> | ||
12 | #include <linux/export.h> | 15 | #include <linux/export.h> |
13 | #include <linux/ssb/ssb.h> | 16 | #include <linux/ssb/ssb.h> |
14 | 17 | ||
15 | #include "ssb_private.h" | 18 | #include "ssb_private.h" |
16 | 19 | ||
20 | |||
21 | /************************************************** | ||
22 | * Shared | ||
23 | **************************************************/ | ||
24 | |||
17 | static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip) | 25 | static struct ssb_bus *ssb_gpio_get_bus(struct gpio_chip *chip) |
18 | { | 26 | { |
19 | return container_of(chip, struct ssb_bus, gpio); | 27 | return container_of(chip, struct ssb_bus, gpio); |
20 | } | 28 | } |
21 | 29 | ||
30 | #if IS_ENABLED(CONFIG_SSB_EMBEDDED) | ||
31 | static int ssb_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) | ||
32 | { | ||
33 | struct ssb_bus *bus = ssb_gpio_get_bus(chip); | ||
34 | |||
35 | if (bus->bustype == SSB_BUSTYPE_SSB) | ||
36 | return irq_find_mapping(bus->irq_domain, gpio); | ||
37 | else | ||
38 | return -EINVAL; | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | /************************************************** | ||
43 | * ChipCommon | ||
44 | **************************************************/ | ||
45 | |||
22 | static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) | 46 | static int ssb_gpio_chipco_get_value(struct gpio_chip *chip, unsigned gpio) |
23 | { | 47 | { |
24 | struct ssb_bus *bus = ssb_gpio_get_bus(chip); | 48 | struct ssb_bus *bus = ssb_gpio_get_bus(chip); |
@@ -74,19 +98,129 @@ static void ssb_gpio_chipco_free(struct gpio_chip *chip, unsigned gpio) | |||
74 | ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); | 98 | ssb_chipco_gpio_pullup(&bus->chipco, 1 << gpio, 0); |
75 | } | 99 | } |
76 | 100 | ||
77 | static int ssb_gpio_chipco_to_irq(struct gpio_chip *chip, unsigned gpio) | 101 | #if IS_ENABLED(CONFIG_SSB_EMBEDDED) |
102 | static void ssb_gpio_irq_chipco_mask(struct irq_data *d) | ||
78 | { | 103 | { |
79 | struct ssb_bus *bus = ssb_gpio_get_bus(chip); | 104 | struct ssb_bus *bus = irq_data_get_irq_chip_data(d); |
105 | int gpio = irqd_to_hwirq(d); | ||
80 | 106 | ||
81 | if (bus->bustype == SSB_BUSTYPE_SSB) | 107 | ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), 0); |
82 | return ssb_mips_irq(bus->chipco.dev) + 2; | 108 | } |
83 | else | 109 | |
84 | return -EINVAL; | 110 | static void ssb_gpio_irq_chipco_unmask(struct irq_data *d) |
111 | { | ||
112 | struct ssb_bus *bus = irq_data_get_irq_chip_data(d); | ||
113 | int gpio = irqd_to_hwirq(d); | ||
114 | u32 val = ssb_chipco_gpio_in(&bus->chipco, BIT(gpio)); | ||
115 | |||
116 | ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val); | ||
117 | ssb_chipco_gpio_intmask(&bus->chipco, BIT(gpio), BIT(gpio)); | ||
118 | } | ||
119 | |||
120 | static struct irq_chip ssb_gpio_irq_chipco_chip = { | ||
121 | .name = "SSB-GPIO-CC", | ||
122 | .irq_mask = ssb_gpio_irq_chipco_mask, | ||
123 | .irq_unmask = ssb_gpio_irq_chipco_unmask, | ||
124 | }; | ||
125 | |||
126 | static irqreturn_t ssb_gpio_irq_chipco_handler(int irq, void *dev_id) | ||
127 | { | ||
128 | struct ssb_bus *bus = dev_id; | ||
129 | struct ssb_chipcommon *chipco = &bus->chipco; | ||
130 | u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN); | ||
131 | u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ); | ||
132 | u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL); | ||
133 | unsigned long irqs = (val ^ pol) & mask; | ||
134 | int gpio; | ||
135 | |||
136 | if (!irqs) | ||
137 | return IRQ_NONE; | ||
138 | |||
139 | for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) | ||
140 | generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); | ||
141 | ssb_chipco_gpio_polarity(chipco, irqs, val & irqs); | ||
142 | |||
143 | return IRQ_HANDLED; | ||
144 | } | ||
145 | |||
146 | static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus) | ||
147 | { | ||
148 | struct ssb_chipcommon *chipco = &bus->chipco; | ||
149 | struct gpio_chip *chip = &bus->gpio; | ||
150 | int gpio, hwirq, err; | ||
151 | |||
152 | if (bus->bustype != SSB_BUSTYPE_SSB) | ||
153 | return 0; | ||
154 | |||
155 | bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, | ||
156 | &irq_domain_simple_ops, chipco); | ||
157 | if (!bus->irq_domain) { | ||
158 | err = -ENODEV; | ||
159 | goto err_irq_domain; | ||
160 | } | ||
161 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
162 | int irq = irq_create_mapping(bus->irq_domain, gpio); | ||
163 | |||
164 | irq_set_chip_data(irq, bus); | ||
165 | irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip, | ||
166 | handle_simple_irq); | ||
167 | } | ||
168 | |||
169 | hwirq = ssb_mips_irq(bus->chipco.dev) + 2; | ||
170 | err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED, | ||
171 | "gpio", bus); | ||
172 | if (err) | ||
173 | goto err_req_irq; | ||
174 | |||
175 | ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0); | ||
176 | chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO); | ||
177 | |||
178 | return 0; | ||
179 | |||
180 | err_req_irq: | ||
181 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
182 | int irq = irq_find_mapping(bus->irq_domain, gpio); | ||
183 | |||
184 | irq_dispose_mapping(irq); | ||
185 | } | ||
186 | irq_domain_remove(bus->irq_domain); | ||
187 | err_irq_domain: | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus) | ||
192 | { | ||
193 | struct ssb_chipcommon *chipco = &bus->chipco; | ||
194 | struct gpio_chip *chip = &bus->gpio; | ||
195 | int gpio; | ||
196 | |||
197 | if (bus->bustype != SSB_BUSTYPE_SSB) | ||
198 | return; | ||
199 | |||
200 | chipco_mask32(chipco, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO); | ||
201 | free_irq(ssb_mips_irq(bus->chipco.dev) + 2, chipco); | ||
202 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
203 | int irq = irq_find_mapping(bus->irq_domain, gpio); | ||
204 | |||
205 | irq_dispose_mapping(irq); | ||
206 | } | ||
207 | irq_domain_remove(bus->irq_domain); | ||
208 | } | ||
209 | #else | ||
210 | static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus) | ||
211 | { | ||
212 | return 0; | ||
85 | } | 213 | } |
86 | 214 | ||
215 | static void ssb_gpio_irq_chipco_domain_exit(struct ssb_bus *bus) | ||
216 | { | ||
217 | } | ||
218 | #endif | ||
219 | |||
87 | static int ssb_gpio_chipco_init(struct ssb_bus *bus) | 220 | static int ssb_gpio_chipco_init(struct ssb_bus *bus) |
88 | { | 221 | { |
89 | struct gpio_chip *chip = &bus->gpio; | 222 | struct gpio_chip *chip = &bus->gpio; |
223 | int err; | ||
90 | 224 | ||
91 | chip->label = "ssb_chipco_gpio"; | 225 | chip->label = "ssb_chipco_gpio"; |
92 | chip->owner = THIS_MODULE; | 226 | chip->owner = THIS_MODULE; |
@@ -96,7 +230,9 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) | |||
96 | chip->set = ssb_gpio_chipco_set_value; | 230 | chip->set = ssb_gpio_chipco_set_value; |
97 | chip->direction_input = ssb_gpio_chipco_direction_input; | 231 | chip->direction_input = ssb_gpio_chipco_direction_input; |
98 | chip->direction_output = ssb_gpio_chipco_direction_output; | 232 | chip->direction_output = ssb_gpio_chipco_direction_output; |
99 | chip->to_irq = ssb_gpio_chipco_to_irq; | 233 | #if IS_ENABLED(CONFIG_SSB_EMBEDDED) |
234 | chip->to_irq = ssb_gpio_to_irq; | ||
235 | #endif | ||
100 | chip->ngpio = 16; | 236 | chip->ngpio = 16; |
101 | /* There is just one SoC in one device and its GPIO addresses should be | 237 | /* There is just one SoC in one device and its GPIO addresses should be |
102 | * deterministic to address them more easily. The other buses could get | 238 | * deterministic to address them more easily. The other buses could get |
@@ -106,9 +242,23 @@ static int ssb_gpio_chipco_init(struct ssb_bus *bus) | |||
106 | else | 242 | else |
107 | chip->base = -1; | 243 | chip->base = -1; |
108 | 244 | ||
109 | return gpiochip_add(chip); | 245 | err = ssb_gpio_irq_chipco_domain_init(bus); |
246 | if (err) | ||
247 | return err; | ||
248 | |||
249 | err = gpiochip_add(chip); | ||
250 | if (err) { | ||
251 | ssb_gpio_irq_chipco_domain_exit(bus); | ||
252 | return err; | ||
253 | } | ||
254 | |||
255 | return 0; | ||
110 | } | 256 | } |
111 | 257 | ||
258 | /************************************************** | ||
259 | * EXTIF | ||
260 | **************************************************/ | ||
261 | |||
112 | #ifdef CONFIG_SSB_DRIVER_EXTIF | 262 | #ifdef CONFIG_SSB_DRIVER_EXTIF |
113 | 263 | ||
114 | static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) | 264 | static int ssb_gpio_extif_get_value(struct gpio_chip *chip, unsigned gpio) |
@@ -145,19 +295,127 @@ static int ssb_gpio_extif_direction_output(struct gpio_chip *chip, | |||
145 | return 0; | 295 | return 0; |
146 | } | 296 | } |
147 | 297 | ||
148 | static int ssb_gpio_extif_to_irq(struct gpio_chip *chip, unsigned gpio) | 298 | #if IS_ENABLED(CONFIG_SSB_EMBEDDED) |
299 | static void ssb_gpio_irq_extif_mask(struct irq_data *d) | ||
149 | { | 300 | { |
150 | struct ssb_bus *bus = ssb_gpio_get_bus(chip); | 301 | struct ssb_bus *bus = irq_data_get_irq_chip_data(d); |
302 | int gpio = irqd_to_hwirq(d); | ||
151 | 303 | ||
152 | if (bus->bustype == SSB_BUSTYPE_SSB) | 304 | ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), 0); |
153 | return ssb_mips_irq(bus->extif.dev) + 2; | 305 | } |
154 | else | 306 | |
155 | return -EINVAL; | 307 | static void ssb_gpio_irq_extif_unmask(struct irq_data *d) |
308 | { | ||
309 | struct ssb_bus *bus = irq_data_get_irq_chip_data(d); | ||
310 | int gpio = irqd_to_hwirq(d); | ||
311 | u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio)); | ||
312 | |||
313 | ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val); | ||
314 | ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio)); | ||
315 | } | ||
316 | |||
317 | static struct irq_chip ssb_gpio_irq_extif_chip = { | ||
318 | .name = "SSB-GPIO-EXTIF", | ||
319 | .irq_mask = ssb_gpio_irq_extif_mask, | ||
320 | .irq_unmask = ssb_gpio_irq_extif_unmask, | ||
321 | }; | ||
322 | |||
323 | static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id) | ||
324 | { | ||
325 | struct ssb_bus *bus = dev_id; | ||
326 | struct ssb_extif *extif = &bus->extif; | ||
327 | u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN); | ||
328 | u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK); | ||
329 | u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL); | ||
330 | unsigned long irqs = (val ^ pol) & mask; | ||
331 | int gpio; | ||
332 | |||
333 | if (!irqs) | ||
334 | return IRQ_NONE; | ||
335 | |||
336 | for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) | ||
337 | generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); | ||
338 | ssb_extif_gpio_polarity(extif, irqs, val & irqs); | ||
339 | |||
340 | return IRQ_HANDLED; | ||
341 | } | ||
342 | |||
343 | static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus) | ||
344 | { | ||
345 | struct ssb_extif *extif = &bus->extif; | ||
346 | struct gpio_chip *chip = &bus->gpio; | ||
347 | int gpio, hwirq, err; | ||
348 | |||
349 | if (bus->bustype != SSB_BUSTYPE_SSB) | ||
350 | return 0; | ||
351 | |||
352 | bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, | ||
353 | &irq_domain_simple_ops, extif); | ||
354 | if (!bus->irq_domain) { | ||
355 | err = -ENODEV; | ||
356 | goto err_irq_domain; | ||
357 | } | ||
358 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
359 | int irq = irq_create_mapping(bus->irq_domain, gpio); | ||
360 | |||
361 | irq_set_chip_data(irq, bus); | ||
362 | irq_set_chip_and_handler(irq, &ssb_gpio_irq_extif_chip, | ||
363 | handle_simple_irq); | ||
364 | } | ||
365 | |||
366 | hwirq = ssb_mips_irq(bus->extif.dev) + 2; | ||
367 | err = request_irq(hwirq, ssb_gpio_irq_extif_handler, IRQF_SHARED, | ||
368 | "gpio", bus); | ||
369 | if (err) | ||
370 | goto err_req_irq; | ||
371 | |||
372 | ssb_extif_gpio_intmask(&bus->extif, ~0, 0); | ||
373 | |||
374 | return 0; | ||
375 | |||
376 | err_req_irq: | ||
377 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
378 | int irq = irq_find_mapping(bus->irq_domain, gpio); | ||
379 | |||
380 | irq_dispose_mapping(irq); | ||
381 | } | ||
382 | irq_domain_remove(bus->irq_domain); | ||
383 | err_irq_domain: | ||
384 | return err; | ||
385 | } | ||
386 | |||
387 | static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus) | ||
388 | { | ||
389 | struct ssb_extif *extif = &bus->extif; | ||
390 | struct gpio_chip *chip = &bus->gpio; | ||
391 | int gpio; | ||
392 | |||
393 | if (bus->bustype != SSB_BUSTYPE_SSB) | ||
394 | return; | ||
395 | |||
396 | free_irq(ssb_mips_irq(bus->extif.dev) + 2, extif); | ||
397 | for (gpio = 0; gpio < chip->ngpio; gpio++) { | ||
398 | int irq = irq_find_mapping(bus->irq_domain, gpio); | ||
399 | |||
400 | irq_dispose_mapping(irq); | ||
401 | } | ||
402 | irq_domain_remove(bus->irq_domain); | ||
156 | } | 403 | } |
404 | #else | ||
405 | static int ssb_gpio_irq_extif_domain_init(struct ssb_bus *bus) | ||
406 | { | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static void ssb_gpio_irq_extif_domain_exit(struct ssb_bus *bus) | ||
411 | { | ||
412 | } | ||
413 | #endif | ||
157 | 414 | ||
158 | static int ssb_gpio_extif_init(struct ssb_bus *bus) | 415 | static int ssb_gpio_extif_init(struct ssb_bus *bus) |
159 | { | 416 | { |
160 | struct gpio_chip *chip = &bus->gpio; | 417 | struct gpio_chip *chip = &bus->gpio; |
418 | int err; | ||
161 | 419 | ||
162 | chip->label = "ssb_extif_gpio"; | 420 | chip->label = "ssb_extif_gpio"; |
163 | chip->owner = THIS_MODULE; | 421 | chip->owner = THIS_MODULE; |
@@ -165,7 +423,9 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus) | |||
165 | chip->set = ssb_gpio_extif_set_value; | 423 | chip->set = ssb_gpio_extif_set_value; |
166 | chip->direction_input = ssb_gpio_extif_direction_input; | 424 | chip->direction_input = ssb_gpio_extif_direction_input; |
167 | chip->direction_output = ssb_gpio_extif_direction_output; | 425 | chip->direction_output = ssb_gpio_extif_direction_output; |
168 | chip->to_irq = ssb_gpio_extif_to_irq; | 426 | #if IS_ENABLED(CONFIG_SSB_EMBEDDED) |
427 | chip->to_irq = ssb_gpio_to_irq; | ||
428 | #endif | ||
169 | chip->ngpio = 5; | 429 | chip->ngpio = 5; |
170 | /* There is just one SoC in one device and its GPIO addresses should be | 430 | /* There is just one SoC in one device and its GPIO addresses should be |
171 | * deterministic to address them more easily. The other buses could get | 431 | * deterministic to address them more easily. The other buses could get |
@@ -175,7 +435,17 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus) | |||
175 | else | 435 | else |
176 | chip->base = -1; | 436 | chip->base = -1; |
177 | 437 | ||
178 | return gpiochip_add(chip); | 438 | err = ssb_gpio_irq_extif_domain_init(bus); |
439 | if (err) | ||
440 | return err; | ||
441 | |||
442 | err = gpiochip_add(chip); | ||
443 | if (err) { | ||
444 | ssb_gpio_irq_extif_domain_exit(bus); | ||
445 | return err; | ||
446 | } | ||
447 | |||
448 | return 0; | ||
179 | } | 449 | } |
180 | 450 | ||
181 | #else | 451 | #else |
@@ -185,6 +455,10 @@ static int ssb_gpio_extif_init(struct ssb_bus *bus) | |||
185 | } | 455 | } |
186 | #endif | 456 | #endif |
187 | 457 | ||
458 | /************************************************** | ||
459 | * Init | ||
460 | **************************************************/ | ||
461 | |||
188 | int ssb_gpio_init(struct ssb_bus *bus) | 462 | int ssb_gpio_init(struct ssb_bus *bus) |
189 | { | 463 | { |
190 | if (ssb_chipco_available(&bus->chipco)) | 464 | if (ssb_chipco_available(&bus->chipco)) |
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 32a811d11c25..2fead3820849 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -593,6 +593,13 @@ static int ssb_attach_queued_buses(void) | |||
593 | ssb_pcicore_init(&bus->pcicore); | 593 | ssb_pcicore_init(&bus->pcicore); |
594 | if (bus->bustype == SSB_BUSTYPE_SSB) | 594 | if (bus->bustype == SSB_BUSTYPE_SSB) |
595 | ssb_watchdog_register(bus); | 595 | ssb_watchdog_register(bus); |
596 | |||
597 | err = ssb_gpio_init(bus); | ||
598 | if (err == -ENOTSUPP) | ||
599 | ssb_dbg("GPIO driver not activated\n"); | ||
600 | else if (err) | ||
601 | ssb_dbg("Error registering GPIO driver: %i\n", err); | ||
602 | |||
596 | ssb_bus_may_powerdown(bus); | 603 | ssb_bus_may_powerdown(bus); |
597 | 604 | ||
598 | err = ssb_devices_register(bus); | 605 | err = ssb_devices_register(bus); |
@@ -830,11 +837,6 @@ static int ssb_bus_register(struct ssb_bus *bus, | |||
830 | ssb_chipcommon_init(&bus->chipco); | 837 | ssb_chipcommon_init(&bus->chipco); |
831 | ssb_extif_init(&bus->extif); | 838 | ssb_extif_init(&bus->extif); |
832 | ssb_mipscore_init(&bus->mipscore); | 839 | ssb_mipscore_init(&bus->mipscore); |
833 | err = ssb_gpio_init(bus); | ||
834 | if (err == -ENOTSUPP) | ||
835 | ssb_dbg("GPIO driver not activated\n"); | ||
836 | else if (err) | ||
837 | ssb_dbg("Error registering GPIO driver: %i\n", err); | ||
838 | err = ssb_fetch_invariants(bus, get_invariants); | 840 | err = ssb_fetch_invariants(bus, get_invariants); |
839 | if (err) { | 841 | if (err) { |
840 | ssb_bus_may_powerdown(bus); | 842 | ssb_bus_may_powerdown(bus); |
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 649d5129c4b4..78e82b017b92 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c | |||
@@ -29,10 +29,7 @@ | |||
29 | #include <linux/sysrq.h> | 29 | #include <linux/sysrq.h> |
30 | #include <linux/serial.h> | 30 | #include <linux/serial.h> |
31 | #include <linux/serial_core.h> | 31 | #include <linux/serial_core.h> |
32 | 32 | #include <linux/serial_bcm63xx.h> | |
33 | #include <bcm63xx_irq.h> | ||
34 | #include <bcm63xx_regs.h> | ||
35 | #include <bcm63xx_io.h> | ||
36 | 33 | ||
37 | #define BCM63XX_NR_UARTS 2 | 34 | #define BCM63XX_NR_UARTS 2 |
38 | 35 | ||
@@ -81,13 +78,13 @@ static struct uart_port ports[BCM63XX_NR_UARTS]; | |||
81 | static inline unsigned int bcm_uart_readl(struct uart_port *port, | 78 | static inline unsigned int bcm_uart_readl(struct uart_port *port, |
82 | unsigned int offset) | 79 | unsigned int offset) |
83 | { | 80 | { |
84 | return bcm_readl(port->membase + offset); | 81 | return __raw_readl(port->membase + offset); |
85 | } | 82 | } |
86 | 83 | ||
87 | static inline void bcm_uart_writel(struct uart_port *port, | 84 | static inline void bcm_uart_writel(struct uart_port *port, |
88 | unsigned int value, unsigned int offset) | 85 | unsigned int value, unsigned int offset) |
89 | { | 86 | { |
90 | bcm_writel(value, port->membase + offset); | 87 | __raw_writel(value, port->membase + offset); |
91 | } | 88 | } |
92 | 89 | ||
93 | /* | 90 | /* |