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 | /* |
