diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2012-11-26 06:57:58 -0500 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2012-11-26 06:57:58 -0500 |
| commit | eabc5fa51c1fae4b66cf883e3a3c2b3ca794494c (patch) | |
| tree | 7e17333920f4ab9986f3f40e881b4bc890a91724 | |
| parent | 9489e9dcae718d5fde988e4a684a0f55b5f94d17 (diff) | |
| parent | df1590d9ae5e37e07e7cf91107e4c2c946ce8bf4 (diff) | |
Merge branch 'spear-for-3.8' of git://git.linaro.org/people/vireshk/linux into next/dt2
From Viresh Kumar <viresh.kumar@linaro.org>:
These are DT updates for SPEAr SoCs. There aren't any fixes that we want
to get into 3.7-rc* and we are happy with 3.8.
Some of the dtbs which use gpiopinctrl have dependency on Linus's
pinctrl tree, where an earlier update for adding gpiopinctrl node is present.
* 'spear-for-3.8' of git://git.linaro.org/people/vireshk/linux:
ARM: SPEAr3xx: Shirq: Move shirq controller out of plat/
ARM: SPEAr320: DT: Add SPEAr 320 HMI board support
ARM: SPEAr3xx: DT: add shirq node for interrupt multiplexor
ARM: SPEAr3xx: shirq: simplify and move the shared irq multiplexor to DT
ARM: SPEAr1310: Fix AUXDATA for compact flash controller
ARM: SPEAr13xx: Remove fields not required for ssp controller
ARM: SPEAr1310: Move 1310 specific misc register into machine specific files
ARM: SPEAr: DT: Update device nodes
ARM: SPEAr: DT: add uart state to fix warning
ARM: SPEAr: DT: Modify DT bindings for STMMAC
ARM: SPEAr: DT: Fix existing DT support
ARM: SPEAr: DT: Update partition info for MTD devices
ARM: SPEAr: DT: Update pinctrl list
ARM: SPEAr13xx: DT: Add spics gpio controller nodes
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
89 files changed, 4179 insertions, 1225 deletions
diff --git a/Documentation/devicetree/bindings/arm/spear/shirq.txt b/Documentation/devicetree/bindings/arm/spear/shirq.txt new file mode 100644 index 000000000000..13fbb8866bd6 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/spear/shirq.txt | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | * SPEAr Shared IRQ layer (shirq) | ||
| 2 | |||
| 3 | SPEAr3xx architecture includes shared/multiplexed irqs for certain set | ||
| 4 | of devices. The multiplexor provides a single interrupt to parent | ||
| 5 | interrupt controller (VIC) on behalf of a group of devices. | ||
| 6 | |||
| 7 | There can be multiple groups available on SPEAr3xx variants but not | ||
| 8 | exceeding 4. The number of devices in a group can differ, further they | ||
| 9 | may share same set of status/mask registers spanning across different | ||
| 10 | bit masks. Also in some cases the group may not have enable or other | ||
| 11 | registers. This makes software little complex. | ||
| 12 | |||
| 13 | A single node in the device tree is used to describe the shared | ||
| 14 | interrupt multiplexor (one node for all groups). A group in the | ||
| 15 | interrupt controller shares config/control registers with other groups. | ||
| 16 | For example, a 32-bit interrupt enable/disable config register can | ||
| 17 | accommodate upto 4 interrupt groups. | ||
| 18 | |||
| 19 | Required properties: | ||
| 20 | - compatible: should be, either of | ||
| 21 | - "st,spear300-shirq" | ||
| 22 | - "st,spear310-shirq" | ||
| 23 | - "st,spear320-shirq" | ||
| 24 | - interrupt-controller: Identifies the node as an interrupt controller. | ||
| 25 | - #interrupt-cells: should be <1> which basically contains the offset | ||
| 26 | (starting from 0) of interrupts for all the groups. | ||
| 27 | - reg: Base address and size of shirq registers. | ||
| 28 | - interrupts: The list of interrupts generated by the groups which are | ||
| 29 | then connected to a parent interrupt controller. Each group is | ||
| 30 | associated with one of the interrupts, hence number of interrupts (to | ||
| 31 | parent) is equal to number of groups. The format of the interrupt | ||
| 32 | specifier depends in the interrupt parent controller. | ||
| 33 | |||
| 34 | Optional properties: | ||
| 35 | - interrupt-parent: pHandle of the parent interrupt controller, if not | ||
| 36 | inherited from the parent node. | ||
| 37 | |||
| 38 | Example: | ||
| 39 | |||
| 40 | The following is an example from the SPEAr320 SoC dtsi file. | ||
| 41 | |||
| 42 | shirq: interrupt-controller@0xb3000000 { | ||
| 43 | compatible = "st,spear320-shirq"; | ||
| 44 | reg = <0xb3000000 0x1000>; | ||
| 45 | interrupts = <28 29 30 1>; | ||
| 46 | #interrupt-cells = <1>; | ||
| 47 | interrupt-controller; | ||
| 48 | }; | ||
diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt index 4e16ba4feab0..a33628759d36 100644 --- a/Documentation/devicetree/bindings/gpio/gpio.txt +++ b/Documentation/devicetree/bindings/gpio/gpio.txt | |||
| @@ -75,4 +75,40 @@ Example of two SOC GPIO banks defined as gpio-controller nodes: | |||
| 75 | gpio-controller; | 75 | gpio-controller; |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| 78 | 2.1) gpio-controller and pinctrl subsystem | ||
| 79 | ------------------------------------------ | ||
| 78 | 80 | ||
| 81 | gpio-controller on a SOC might be tightly coupled with the pinctrl | ||
| 82 | subsystem, in the sense that the pins can be used by other functions | ||
| 83 | together with optional gpio feature. | ||
| 84 | |||
| 85 | While the pin allocation is totally managed by the pin ctrl subsystem, | ||
| 86 | gpio (under gpiolib) is still maintained by gpio drivers. It may happen | ||
| 87 | that different pin ranges in a SoC is managed by different gpio drivers. | ||
| 88 | |||
| 89 | This makes it logical to let gpio drivers announce their pin ranges to | ||
| 90 | the pin ctrl subsystem and call 'pinctrl_request_gpio' in order to | ||
| 91 | request the corresponding pin before any gpio usage. | ||
| 92 | |||
| 93 | For this, the gpio controller can use a pinctrl phandle and pins to | ||
| 94 | announce the pinrange to the pin ctrl subsystem. For example, | ||
| 95 | |||
| 96 | qe_pio_e: gpio-controller@1460 { | ||
| 97 | #gpio-cells = <2>; | ||
| 98 | compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; | ||
| 99 | reg = <0x1460 0x18>; | ||
| 100 | gpio-controller; | ||
| 101 | gpio-ranges = <&pinctrl1 20 10>, <&pinctrl2 50 20>; | ||
| 102 | |||
| 103 | } | ||
| 104 | |||
| 105 | where, | ||
| 106 | &pinctrl1 and &pinctrl2 is the phandle to the pinctrl DT node. | ||
| 107 | |||
| 108 | Next values specify the base pin and number of pins for the range | ||
| 109 | handled by 'qe_pio_e' gpio. In the given example from base pin 20 to | ||
| 110 | pin 29 under pinctrl1 and pin 50 to pin 69 under pinctrl2 is handled | ||
| 111 | by this gpio controller. | ||
| 112 | |||
| 113 | The pinctrl node must have "#gpio-range-cells" property to show number of | ||
| 114 | arguments to pass with phandle from gpio controllers node. | ||
diff --git a/Documentation/devicetree/bindings/gpio/spear_spics.txt b/Documentation/devicetree/bindings/gpio/spear_spics.txt new file mode 100644 index 000000000000..96c37eb15075 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/spear_spics.txt | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | === ST Microelectronics SPEAr SPI CS Driver === | ||
| 2 | |||
| 3 | SPEAr platform provides a provision to control chipselects of ARM PL022 Prime | ||
| 4 | Cell spi controller through its system registers, which otherwise remains under | ||
| 5 | PL022 control. If chipselect remain under PL022 control then they would be | ||
| 6 | released as soon as transfer is over and TxFIFO becomes empty. This is not | ||
| 7 | desired by some of the device protocols above spi which expect (multiple) | ||
| 8 | transfers without releasing their chipselects. | ||
| 9 | |||
| 10 | Chipselects can be controlled by software by turning them as GPIOs. SPEAr | ||
| 11 | provides another interface through system registers through which software can | ||
| 12 | directly control each PL022 chipselect. Hence, it is natural for SPEAr to export | ||
| 13 | the control of this interface as gpio. | ||
| 14 | |||
| 15 | Required properties: | ||
| 16 | |||
| 17 | * compatible: should be defined as "st,spear-spics-gpio" | ||
| 18 | * reg: mentioning address range of spics controller | ||
| 19 | * st-spics,peripcfg-reg: peripheral configuration register offset | ||
| 20 | * st-spics,sw-enable-bit: bit offset to enable sw control | ||
| 21 | * st-spics,cs-value-bit: bit offset to drive chipselect low or high | ||
| 22 | * st-spics,cs-enable-mask: chip select number bit mask | ||
| 23 | * st-spics,cs-enable-shift: chip select number program offset | ||
| 24 | * gpio-controller: Marks the device node as gpio controller | ||
| 25 | * #gpio-cells: should be 1 and will mention chip select number | ||
| 26 | |||
| 27 | All the above bit offsets are within peripcfg register. | ||
| 28 | |||
| 29 | Example: | ||
| 30 | ------- | ||
| 31 | spics: spics@e0700000{ | ||
| 32 | compatible = "st,spear-spics-gpio"; | ||
| 33 | reg = <0xe0700000 0x1000>; | ||
| 34 | st-spics,peripcfg-reg = <0x3b0>; | ||
| 35 | st-spics,sw-enable-bit = <12>; | ||
| 36 | st-spics,cs-value-bit = <11>; | ||
| 37 | st-spics,cs-enable-mask = <3>; | ||
| 38 | st-spics,cs-enable-shift = <8>; | ||
| 39 | gpio-controller; | ||
| 40 | #gpio-cells = <2>; | ||
| 41 | }; | ||
| 42 | |||
| 43 | |||
| 44 | spi0: spi@e0100000 { | ||
| 45 | status = "okay"; | ||
| 46 | num-cs = <3>; | ||
| 47 | cs-gpios = <&gpio1 7 0>, <&spics 0>, | ||
| 48 | <&spics 1>; | ||
| 49 | ... | ||
| 50 | } | ||
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index e08a883de36e..77a1d11af723 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt | |||
| @@ -439,6 +439,48 @@ slower clock delays the rising edge of SCK, and the I2C master adjusts its | |||
| 439 | signaling rate accordingly. | 439 | signaling rate accordingly. |
| 440 | 440 | ||
| 441 | 441 | ||
| 442 | GPIO controllers and the pinctrl subsystem | ||
| 443 | ------------------------------------------ | ||
| 444 | |||
| 445 | A GPIO controller on a SOC might be tightly coupled with the pinctrl | ||
| 446 | subsystem, in the sense that the pins can be used by other functions | ||
| 447 | together with an optional gpio feature. We have already covered the | ||
| 448 | case where e.g. a GPIO controller need to reserve a pin or set the | ||
| 449 | direction of a pin by calling any of: | ||
| 450 | |||
| 451 | pinctrl_request_gpio() | ||
| 452 | pinctrl_free_gpio() | ||
| 453 | pinctrl_gpio_direction_input() | ||
| 454 | pinctrl_gpio_direction_output() | ||
| 455 | |||
| 456 | But how does the pin control subsystem cross-correlate the GPIO | ||
| 457 | numbers (which are a global business) to a certain pin on a certain | ||
| 458 | pin controller? | ||
| 459 | |||
| 460 | This is done by registering "ranges" of pins, which are essentially | ||
| 461 | cross-reference tables. These are described in | ||
| 462 | Documentation/pinctrl.txt | ||
| 463 | |||
| 464 | While the pin allocation is totally managed by the pinctrl subsystem, | ||
| 465 | gpio (under gpiolib) is still maintained by gpio drivers. It may happen | ||
| 466 | that different pin ranges in a SoC is managed by different gpio drivers. | ||
| 467 | |||
| 468 | This makes it logical to let gpio drivers announce their pin ranges to | ||
| 469 | the pin ctrl subsystem before it will call 'pinctrl_request_gpio' in order | ||
| 470 | to request the corresponding pin to be prepared by the pinctrl subsystem | ||
| 471 | before any gpio usage. | ||
| 472 | |||
| 473 | For this, the gpio controller can register its pin range with pinctrl | ||
| 474 | subsystem. There are two ways of doing it currently: with or without DT. | ||
| 475 | |||
| 476 | For with DT support refer to Documentation/devicetree/bindings/gpio/gpio.txt. | ||
| 477 | |||
| 478 | For non-DT support, user can call gpiochip_add_pin_range() with appropriate | ||
| 479 | parameters to register a range of gpio pins with a pinctrl driver. For this | ||
| 480 | exact name string of pinctrl device has to be passed as one of the | ||
| 481 | argument to this routine. | ||
| 482 | |||
| 483 | |||
| 442 | What do these conventions omit? | 484 | What do these conventions omit? |
| 443 | =============================== | 485 | =============================== |
| 444 | One of the biggest things these conventions omit is pin multiplexing, since | 486 | One of the biggest things these conventions omit is pin multiplexing, since |
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 3b4ee5328868..da40efbef6ec 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt | |||
| @@ -364,6 +364,9 @@ will get an pin number into its handled number range. Further it is also passed | |||
| 364 | the range ID value, so that the pin controller knows which range it should | 364 | the range ID value, so that the pin controller knows which range it should |
| 365 | deal with. | 365 | deal with. |
| 366 | 366 | ||
| 367 | Calling pinctrl_add_gpio_range from pinctrl driver is DEPRECATED. Please see | ||
| 368 | section 2.1 of Documentation/devicetree/bindings/gpio/gpio.txt on how to bind | ||
| 369 | pinctrl and gpio drivers. | ||
| 367 | 370 | ||
| 368 | PINMUX interfaces | 371 | PINMUX interfaces |
| 369 | ================= | 372 | ================= |
| @@ -1193,4 +1196,6 @@ foo_switch() | |||
| 1193 | ... | 1196 | ... |
| 1194 | } | 1197 | } |
| 1195 | 1198 | ||
| 1196 | The above has to be done from process context. | 1199 | The above has to be done from process context. The reservation of the pins |
| 1200 | will be done when the state is activated, so in effect one specific pin | ||
| 1201 | can be used by different functions at different times on a running system. | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ade7e924bef5..b673d65449f8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -364,6 +364,7 @@ config ARCH_CNS3XXX | |||
| 364 | 364 | ||
| 365 | config ARCH_CLPS711X | 365 | config ARCH_CLPS711X |
| 366 | bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" | 366 | bool "Cirrus Logic CLPS711x/EP721x/EP731x-based" |
| 367 | select ARCH_REQUIRE_GPIOLIB | ||
| 367 | select ARCH_USES_GETTIMEOFFSET | 368 | select ARCH_USES_GETTIMEOFFSET |
| 368 | select CLKDEV_LOOKUP | 369 | select CLKDEV_LOOKUP |
| 369 | select COMMON_CLK | 370 | select COMMON_CLK |
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index f37cf9fa5fa0..07e6cfaaa319 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile | |||
| @@ -82,7 +82,8 @@ dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ | |||
| 82 | spear1340-evb.dtb | 82 | spear1340-evb.dtb |
| 83 | dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ | 83 | dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \ |
| 84 | spear310-evb.dtb \ | 84 | spear310-evb.dtb \ |
| 85 | spear320-evb.dtb | 85 | spear320-evb.dtb \ |
| 86 | spear320-hmi.dtb | ||
| 86 | dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb | 87 | dtb-$(CONFIG_ARCH_SPEAR6XX)+= spear600-evb.dtb |
| 87 | dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ | 88 | dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ |
| 88 | tegra20-medcom-wide.dtb \ | 89 | tegra20-medcom-wide.dtb \ |
diff --git a/arch/arm/boot/dts/spear1310-evb.dts b/arch/arm/boot/dts/spear1310-evb.dts index dd4358bc26e2..b56a801e42a2 100644 --- a/arch/arm/boot/dts/spear1310-evb.dts +++ b/arch/arm/boot/dts/spear1310-evb.dts | |||
| @@ -30,10 +30,14 @@ | |||
| 30 | pinctrl-0 = <&state_default>; | 30 | pinctrl-0 = <&state_default>; |
| 31 | 31 | ||
| 32 | state_default: pinmux { | 32 | state_default: pinmux { |
| 33 | i2c0-pmx { | 33 | i2c0 { |
| 34 | st,pins = "i2c0_grp"; | 34 | st,pins = "i2c0_grp"; |
| 35 | st,function = "i2c0"; | 35 | st,function = "i2c0"; |
| 36 | }; | 36 | }; |
| 37 | i2s0 { | ||
| 38 | st,pins = "i2s0_grp"; | ||
| 39 | st,function = "i2s0"; | ||
| 40 | }; | ||
| 37 | i2s1 { | 41 | i2s1 { |
| 38 | st,pins = "i2s1_grp"; | 42 | st,pins = "i2s1_grp"; |
| 39 | st,function = "i2s1"; | 43 | st,function = "i2s1"; |
| @@ -42,6 +46,10 @@ | |||
| 42 | st,pins = "arm_gpio_grp"; | 46 | st,pins = "arm_gpio_grp"; |
| 43 | st,function = "arm_gpio"; | 47 | st,function = "arm_gpio"; |
| 44 | }; | 48 | }; |
| 49 | clcd { | ||
| 50 | st,pins = "clcd_grp" , "clcd_high_res"; | ||
| 51 | st,function = "clcd"; | ||
| 52 | }; | ||
| 45 | eth { | 53 | eth { |
| 46 | st,pins = "gmii_grp"; | 54 | st,pins = "gmii_grp"; |
| 47 | st,function = "gmii"; | 55 | st,function = "gmii"; |
| @@ -74,11 +82,6 @@ | |||
| 74 | st,pins = "i2c_1_2_grp"; | 82 | st,pins = "i2c_1_2_grp"; |
| 75 | st,function = "i2c_1_2"; | 83 | st,function = "i2c_1_2"; |
| 76 | }; | 84 | }; |
| 77 | pci { | ||
| 78 | st,pins = "pcie0_grp","pcie1_grp", | ||
| 79 | "pcie2_grp"; | ||
| 80 | st,function = "pci"; | ||
| 81 | }; | ||
| 82 | smii { | 85 | smii { |
| 83 | st,pins = "smii_0_1_2_grp"; | 86 | st,pins = "smii_0_1_2_grp"; |
| 84 | st,function = "smii_0_1_2"; | 87 | st,function = "smii_0_1_2"; |
| @@ -88,6 +91,14 @@ | |||
| 88 | "nand_16bit_grp"; | 91 | "nand_16bit_grp"; |
| 89 | st,function = "nand"; | 92 | st,function = "nand"; |
| 90 | }; | 93 | }; |
| 94 | sata { | ||
| 95 | st,pins = "sata0_grp"; | ||
| 96 | st,function = "sata"; | ||
| 97 | }; | ||
| 98 | pcie { | ||
| 99 | st,pins = "pcie1_grp", "pcie2_grp"; | ||
| 100 | st,function = "pci_express"; | ||
| 101 | }; | ||
| 91 | }; | 102 | }; |
| 92 | }; | 103 | }; |
| 93 | 104 | ||
| @@ -109,9 +120,49 @@ | |||
| 109 | 120 | ||
| 110 | fsmc: flash@b0000000 { | 121 | fsmc: flash@b0000000 { |
| 111 | status = "okay"; | 122 | status = "okay"; |
| 123 | |||
| 124 | partition@0 { | ||
| 125 | label = "xloader"; | ||
| 126 | reg = <0x0 0x80000>; | ||
| 127 | }; | ||
| 128 | partition@80000 { | ||
| 129 | label = "u-boot"; | ||
| 130 | reg = <0x80000 0x140000>; | ||
| 131 | }; | ||
| 132 | partition@1C0000 { | ||
| 133 | label = "environment"; | ||
| 134 | reg = <0x1C0000 0x40000>; | ||
| 135 | }; | ||
| 136 | partition@200000 { | ||
| 137 | label = "dtb"; | ||
| 138 | reg = <0x200000 0x40000>; | ||
| 139 | }; | ||
| 140 | partition@240000 { | ||
| 141 | label = "linux"; | ||
| 142 | reg = <0x240000 0xC00000>; | ||
| 143 | }; | ||
| 144 | partition@E40000 { | ||
| 145 | label = "rootfs"; | ||
| 146 | reg = <0xE40000 0x0>; | ||
| 147 | }; | ||
| 148 | }; | ||
| 149 | |||
| 150 | gpio_keys { | ||
| 151 | compatible = "gpio-keys"; | ||
| 152 | #address-cells = <1>; | ||
| 153 | #size-cells = <0>; | ||
| 154 | |||
| 155 | button@1 { | ||
| 156 | label = "wakeup"; | ||
| 157 | linux,code = <0x100>; | ||
| 158 | gpios = <&gpio0 7 0x4>; | ||
| 159 | debounce-interval = <20>; | ||
| 160 | gpio-key,wakeup = <1>; | ||
| 161 | }; | ||
| 112 | }; | 162 | }; |
| 113 | 163 | ||
| 114 | gmac0: eth@e2000000 { | 164 | gmac0: eth@e2000000 { |
| 165 | phy-mode = "gmii"; | ||
| 115 | status = "okay"; | 166 | status = "okay"; |
| 116 | }; | 167 | }; |
| 117 | 168 | ||
| @@ -135,23 +186,27 @@ | |||
| 135 | }; | 186 | }; |
| 136 | partition@10000 { | 187 | partition@10000 { |
| 137 | label = "u-boot"; | 188 | label = "u-boot"; |
| 138 | reg = <0x10000 0x40000>; | 189 | reg = <0x10000 0x50000>; |
| 190 | }; | ||
| 191 | partition@60000 { | ||
| 192 | label = "environment"; | ||
| 193 | reg = <0x60000 0x10000>; | ||
| 139 | }; | 194 | }; |
| 140 | partition@50000 { | 195 | partition@70000 { |
| 196 | label = "dtb"; | ||
| 197 | reg = <0x70000 0x10000>; | ||
| 198 | }; | ||
| 199 | partition@80000 { | ||
| 141 | label = "linux"; | 200 | label = "linux"; |
| 142 | reg = <0x50000 0x2c0000>; | 201 | reg = <0x80000 0x310000>; |
| 143 | }; | 202 | }; |
| 144 | partition@310000 { | 203 | partition@390000 { |
| 145 | label = "rootfs"; | 204 | label = "rootfs"; |
| 146 | reg = <0x310000 0x4f0000>; | 205 | reg = <0x390000 0x0>; |
| 147 | }; | 206 | }; |
| 148 | }; | 207 | }; |
| 149 | }; | 208 | }; |
| 150 | 209 | ||
| 151 | spi0: spi@e0100000 { | ||
| 152 | status = "okay"; | ||
| 153 | }; | ||
| 154 | |||
| 155 | ehci@e4800000 { | 210 | ehci@e4800000 { |
| 156 | status = "okay"; | 211 | status = "okay"; |
| 157 | }; | 212 | }; |
| @@ -181,11 +236,11 @@ | |||
| 181 | status = "okay"; | 236 | status = "okay"; |
| 182 | }; | 237 | }; |
| 183 | 238 | ||
| 184 | i2c0: i2c@e0280000 { | 239 | gpio@d8400000 { |
| 185 | status = "okay"; | 240 | status = "okay"; |
| 186 | }; | 241 | }; |
| 187 | 242 | ||
| 188 | i2c1: i2c@5cd00000 { | 243 | i2c0: i2c@e0280000 { |
| 189 | status = "okay"; | 244 | status = "okay"; |
| 190 | }; | 245 | }; |
| 191 | 246 | ||
| @@ -273,6 +328,7 @@ | |||
| 273 | 0x08080052 >; | 328 | 0x08080052 >; |
| 274 | autorepeat; | 329 | autorepeat; |
| 275 | st,mode = <0>; | 330 | st,mode = <0>; |
| 331 | suspended_rate = <2000000>; | ||
| 276 | status = "okay"; | 332 | status = "okay"; |
| 277 | }; | 333 | }; |
| 278 | 334 | ||
| @@ -282,6 +338,81 @@ | |||
| 282 | 338 | ||
| 283 | serial@e0000000 { | 339 | serial@e0000000 { |
| 284 | status = "okay"; | 340 | status = "okay"; |
| 341 | pinctrl-names = "default"; | ||
| 342 | pinctrl-0 = <>; | ||
| 343 | }; | ||
| 344 | |||
| 345 | spi0: spi@e0100000 { | ||
| 346 | status = "okay"; | ||
| 347 | num-cs = <3>; | ||
| 348 | cs-gpios = <&gpio1 7 0>, <&spics 0>, <&spics 1>; | ||
| 349 | |||
| 350 | stmpe610@0 { | ||
| 351 | compatible = "st,stmpe610"; | ||
| 352 | reg = <0>; | ||
| 353 | #address-cells = <1>; | ||
| 354 | #size-cells = <0>; | ||
| 355 | spi-max-frequency = <1000000>; | ||
| 356 | spi-cpha; | ||
| 357 | pl022,hierarchy = <0>; | ||
| 358 | pl022,interface = <0>; | ||
| 359 | pl022,slave-tx-disable; | ||
| 360 | pl022,com-mode = <0>; | ||
| 361 | pl022,rx-level-trig = <0>; | ||
| 362 | pl022,tx-level-trig = <0>; | ||
| 363 | pl022,ctrl-len = <0x7>; | ||
| 364 | pl022,wait-state = <0>; | ||
| 365 | pl022,duplex = <0>; | ||
| 366 | interrupts = <6 0x4>; | ||
| 367 | interrupt-parent = <&gpio1>; | ||
| 368 | irq-trigger = <0x2>; | ||
| 369 | |||
| 370 | stmpe_touchscreen { | ||
| 371 | compatible = "st,stmpe-ts"; | ||
| 372 | ts,sample-time = <4>; | ||
| 373 | ts,mod-12b = <1>; | ||
| 374 | ts,ref-sel = <0>; | ||
| 375 | ts,adc-freq = <1>; | ||
| 376 | ts,ave-ctrl = <1>; | ||
| 377 | ts,touch-det-delay = <2>; | ||
| 378 | ts,settling = <2>; | ||
| 379 | ts,fraction-z = <7>; | ||
| 380 | ts,i-drive = <1>; | ||
| 381 | }; | ||
| 382 | }; | ||
| 383 | |||
| 384 | m25p80@1 { | ||
| 385 | compatible = "st,m25p80"; | ||
| 386 | reg = <1>; | ||
| 387 | spi-max-frequency = <12000000>; | ||
| 388 | spi-cpol; | ||
| 389 | spi-cpha; | ||
| 390 | pl022,hierarchy = <0>; | ||
| 391 | pl022,interface = <0>; | ||
| 392 | pl022,slave-tx-disable; | ||
| 393 | pl022,com-mode = <0x2>; | ||
| 394 | pl022,rx-level-trig = <0>; | ||
| 395 | pl022,tx-level-trig = <0>; | ||
| 396 | pl022,ctrl-len = <0x11>; | ||
| 397 | pl022,wait-state = <0>; | ||
| 398 | pl022,duplex = <0>; | ||
| 399 | }; | ||
| 400 | |||
| 401 | spidev@2 { | ||
| 402 | compatible = "spidev"; | ||
| 403 | reg = <2>; | ||
| 404 | spi-max-frequency = <25000000>; | ||
| 405 | spi-cpha; | ||
| 406 | pl022,hierarchy = <0>; | ||
| 407 | pl022,interface = <0>; | ||
| 408 | pl022,slave-tx-disable; | ||
| 409 | pl022,com-mode = <0x2>; | ||
| 410 | pl022,rx-level-trig = <0>; | ||
| 411 | pl022,tx-level-trig = <0>; | ||
| 412 | pl022,ctrl-len = <0x11>; | ||
| 413 | pl022,wait-state = <0>; | ||
| 414 | pl022,duplex = <0>; | ||
| 415 | }; | ||
| 285 | }; | 416 | }; |
| 286 | 417 | ||
| 287 | wdt@ec800620 { | 418 | wdt@ec800620 { |
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 419ea7413d23..1513c1927cc8 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi | |||
| @@ -17,6 +17,18 @@ | |||
| 17 | compatible = "st,spear1310"; | 17 | compatible = "st,spear1310"; |
| 18 | 18 | ||
| 19 | ahb { | 19 | ahb { |
| 20 | spics: spics@e0700000{ | ||
| 21 | compatible = "st,spear-spics-gpio"; | ||
| 22 | reg = <0xe0700000 0x1000>; | ||
| 23 | st-spics,peripcfg-reg = <0x3b0>; | ||
| 24 | st-spics,sw-enable-bit = <12>; | ||
| 25 | st-spics,cs-value-bit = <11>; | ||
| 26 | st-spics,cs-enable-mask = <3>; | ||
| 27 | st-spics,cs-enable-shift = <8>; | ||
| 28 | gpio-controller; | ||
| 29 | #gpio-cells = <2>; | ||
| 30 | }; | ||
| 31 | |||
| 20 | ahci@b1000000 { | 32 | ahci@b1000000 { |
| 21 | compatible = "snps,spear-ahci"; | 33 | compatible = "snps,spear-ahci"; |
| 22 | reg = <0xb1000000 0x10000>; | 34 | reg = <0xb1000000 0x10000>; |
| @@ -43,6 +55,7 @@ | |||
| 43 | reg = <0x5c400000 0x8000>; | 55 | reg = <0x5c400000 0x8000>; |
| 44 | interrupts = <0 95 0x4>; | 56 | interrupts = <0 95 0x4>; |
| 45 | interrupt-names = "macirq"; | 57 | interrupt-names = "macirq"; |
| 58 | phy-mode = "mii"; | ||
| 46 | status = "disabled"; | 59 | status = "disabled"; |
| 47 | }; | 60 | }; |
| 48 | 61 | ||
| @@ -51,6 +64,7 @@ | |||
| 51 | reg = <0x5c500000 0x8000>; | 64 | reg = <0x5c500000 0x8000>; |
| 52 | interrupts = <0 96 0x4>; | 65 | interrupts = <0 96 0x4>; |
| 53 | interrupt-names = "macirq"; | 66 | interrupt-names = "macirq"; |
| 67 | phy-mode = "mii"; | ||
| 54 | status = "disabled"; | 68 | status = "disabled"; |
| 55 | }; | 69 | }; |
| 56 | 70 | ||
| @@ -59,6 +73,7 @@ | |||
| 59 | reg = <0x5c600000 0x8000>; | 73 | reg = <0x5c600000 0x8000>; |
| 60 | interrupts = <0 97 0x4>; | 74 | interrupts = <0 97 0x4>; |
| 61 | interrupt-names = "macirq"; | 75 | interrupt-names = "macirq"; |
| 76 | phy-mode = "rmii"; | ||
| 62 | status = "disabled"; | 77 | status = "disabled"; |
| 63 | }; | 78 | }; |
| 64 | 79 | ||
| @@ -67,14 +82,14 @@ | |||
| 67 | reg = <0x5c700000 0x8000>; | 82 | reg = <0x5c700000 0x8000>; |
| 68 | interrupts = <0 98 0x4>; | 83 | interrupts = <0 98 0x4>; |
| 69 | interrupt-names = "macirq"; | 84 | interrupt-names = "macirq"; |
| 85 | phy-mode = "rgmii"; | ||
| 70 | status = "disabled"; | 86 | status = "disabled"; |
| 71 | }; | 87 | }; |
| 72 | 88 | ||
| 73 | spi1: spi@5d400000 { | 89 | pinmux: pinmux@e0700000 { |
| 74 | compatible = "arm,pl022", "arm,primecell"; | 90 | compatible = "st,spear1310-pinmux"; |
| 75 | reg = <0x5d400000 0x1000>; | 91 | reg = <0xe0700000 0x1000>; |
| 76 | interrupts = <0 99 0x4>; | 92 | #gpio-range-cells = <2>; |
| 77 | status = "disabled"; | ||
| 78 | }; | 93 | }; |
| 79 | 94 | ||
| 80 | apb { | 95 | apb { |
| @@ -141,6 +156,15 @@ | |||
| 141 | status = "disabled"; | 156 | status = "disabled"; |
| 142 | }; | 157 | }; |
| 143 | 158 | ||
| 159 | spi1: spi@5d400000 { | ||
| 160 | compatible = "arm,pl022", "arm,primecell"; | ||
| 161 | reg = <0x5d400000 0x1000>; | ||
| 162 | interrupts = <0 99 0x4>; | ||
| 163 | #address-cells = <1>; | ||
| 164 | #size-cells = <0>; | ||
| 165 | status = "disabled"; | ||
| 166 | }; | ||
| 167 | |||
| 144 | serial@5c800000 { | 168 | serial@5c800000 { |
| 145 | compatible = "arm,pl011", "arm,primecell"; | 169 | compatible = "arm,pl011", "arm,primecell"; |
| 146 | reg = <0x5c800000 0x1000>; | 170 | reg = <0x5c800000 0x1000>; |
| @@ -179,6 +203,27 @@ | |||
| 179 | thermal@e07008c4 { | 203 | thermal@e07008c4 { |
| 180 | st,thermal-flags = <0x7000>; | 204 | st,thermal-flags = <0x7000>; |
| 181 | }; | 205 | }; |
| 206 | |||
| 207 | gpiopinctrl: gpio@d8400000 { | ||
| 208 | compatible = "st,spear-plgpio"; | ||
| 209 | reg = <0xd8400000 0x1000>; | ||
| 210 | interrupts = <0 100 0x4>; | ||
| 211 | #interrupt-cells = <1>; | ||
| 212 | interrupt-controller; | ||
| 213 | gpio-controller; | ||
| 214 | #gpio-cells = <2>; | ||
| 215 | gpio-ranges = <&pinmux 0 246>; | ||
| 216 | status = "disabled"; | ||
| 217 | |||
| 218 | st-plgpio,ngpio = <246>; | ||
| 219 | st-plgpio,enb-reg = <0xd0>; | ||
| 220 | st-plgpio,wdata-reg = <0x90>; | ||
| 221 | st-plgpio,dir-reg = <0xb0>; | ||
| 222 | st-plgpio,ie-reg = <0x30>; | ||
| 223 | st-plgpio,rdata-reg = <0x70>; | ||
| 224 | st-plgpio,mis-reg = <0x10>; | ||
| 225 | st-plgpio,eit-reg = <0x50>; | ||
| 226 | }; | ||
| 182 | }; | 227 | }; |
| 183 | }; | 228 | }; |
| 184 | }; | 229 | }; |
diff --git a/arch/arm/boot/dts/spear1340-evb.dts b/arch/arm/boot/dts/spear1340-evb.dts index c9a54e06fb68..d6c30ae0a8d7 100644 --- a/arch/arm/boot/dts/spear1340-evb.dts +++ b/arch/arm/boot/dts/spear1340-evb.dts | |||
| @@ -38,20 +38,15 @@ | |||
| 38 | st,pins = "fsmc_8bit_grp"; | 38 | st,pins = "fsmc_8bit_grp"; |
| 39 | st,function = "fsmc"; | 39 | st,function = "fsmc"; |
| 40 | }; | 40 | }; |
| 41 | kbd { | ||
| 42 | st,pins = "keyboard_row_col_grp", | ||
| 43 | "keyboard_col5_grp"; | ||
| 44 | st,function = "keyboard"; | ||
| 45 | }; | ||
| 46 | uart0 { | 41 | uart0 { |
| 47 | st,pins = "uart0_grp", "uart0_enh_grp"; | 42 | st,pins = "uart0_grp"; |
| 48 | st,function = "uart0"; | 43 | st,function = "uart0"; |
| 49 | }; | 44 | }; |
| 50 | i2c0-pmx { | 45 | i2c0 { |
| 51 | st,pins = "i2c0_grp"; | 46 | st,pins = "i2c0_grp"; |
| 52 | st,function = "i2c0"; | 47 | st,function = "i2c0"; |
| 53 | }; | 48 | }; |
| 54 | i2c1-pmx { | 49 | i2c1 { |
| 55 | st,pins = "i2c1_grp"; | 50 | st,pins = "i2c1_grp"; |
| 56 | st,function = "i2c1"; | 51 | st,function = "i2c1"; |
| 57 | }; | 52 | }; |
| @@ -64,14 +59,9 @@ | |||
| 64 | st,function = "spdif_out"; | 59 | st,function = "spdif_out"; |
| 65 | }; | 60 | }; |
| 66 | ssp0 { | 61 | ssp0 { |
| 67 | st,pins = "ssp0_grp", "ssp0_cs1_grp", | 62 | st,pins = "ssp0_grp", "ssp0_cs1_grp", "ssp0_cs2_grp", "ssp0_cs3_grp"; |
| 68 | "ssp0_cs3_grp"; | ||
| 69 | st,function = "ssp0"; | 63 | st,function = "ssp0"; |
| 70 | }; | 64 | }; |
| 71 | pwm { | ||
| 72 | st,pins = "pwm2_grp", "pwm3_grp"; | ||
| 73 | st,function = "pwm"; | ||
| 74 | }; | ||
| 75 | smi-pmx { | 65 | smi-pmx { |
| 76 | st,pins = "smi_grp"; | 66 | st,pins = "smi_grp"; |
| 77 | st,function = "smi"; | 67 | st,function = "smi"; |
| @@ -84,6 +74,18 @@ | |||
| 84 | st,pins = "gmii_grp", "rgmii_grp"; | 74 | st,pins = "gmii_grp", "rgmii_grp"; |
| 85 | st,function = "gmac"; | 75 | st,function = "gmac"; |
| 86 | }; | 76 | }; |
| 77 | cam0 { | ||
| 78 | st,pins = "cam0_grp"; | ||
| 79 | st,function = "cam0"; | ||
| 80 | }; | ||
| 81 | cam1 { | ||
| 82 | st,pins = "cam1_grp"; | ||
| 83 | st,function = "cam1"; | ||
| 84 | }; | ||
| 85 | cam2 { | ||
| 86 | st,pins = "cam2_grp"; | ||
| 87 | st,function = "cam2"; | ||
| 88 | }; | ||
| 87 | cam3 { | 89 | cam3 { |
| 88 | st,pins = "cam3_grp"; | 90 | st,pins = "cam3_grp"; |
| 89 | st,function = "cam3"; | 91 | st,function = "cam3"; |
| @@ -108,9 +110,18 @@ | |||
| 108 | st,pins = "sata_grp"; | 110 | st,pins = "sata_grp"; |
| 109 | st,function = "sata"; | 111 | st,function = "sata"; |
| 110 | }; | 112 | }; |
| 113 | pcie { | ||
| 114 | st,pins = "pcie_grp"; | ||
| 115 | st,function = "pcie"; | ||
| 116 | }; | ||
| 117 | |||
| 111 | }; | 118 | }; |
| 112 | }; | 119 | }; |
| 113 | 120 | ||
| 121 | ahci@b1000000 { | ||
| 122 | status = "okay"; | ||
| 123 | }; | ||
| 124 | |||
| 114 | dma@ea800000 { | 125 | dma@ea800000 { |
| 115 | status = "okay"; | 126 | status = "okay"; |
| 116 | }; | 127 | }; |
| @@ -121,9 +132,35 @@ | |||
| 121 | 132 | ||
| 122 | fsmc: flash@b0000000 { | 133 | fsmc: flash@b0000000 { |
| 123 | status = "okay"; | 134 | status = "okay"; |
| 135 | |||
| 136 | partition@0 { | ||
| 137 | label = "xloader"; | ||
| 138 | reg = <0x0 0x200000>; | ||
| 139 | }; | ||
| 140 | partition@200000 { | ||
| 141 | label = "u-boot"; | ||
| 142 | reg = <0x200000 0x200000>; | ||
| 143 | }; | ||
| 144 | partition@400000 { | ||
| 145 | label = "environment"; | ||
| 146 | reg = <0x400000 0x100000>; | ||
| 147 | }; | ||
| 148 | partition@500000 { | ||
| 149 | label = "dtb"; | ||
| 150 | reg = <0x500000 0x100000>; | ||
| 151 | }; | ||
| 152 | partition@600000 { | ||
| 153 | label = "linux"; | ||
| 154 | reg = <0x600000 0xC00000>; | ||
| 155 | }; | ||
| 156 | partition@1200000 { | ||
| 157 | label = "rootfs"; | ||
| 158 | reg = <0x1200000 0x0>; | ||
| 159 | }; | ||
| 124 | }; | 160 | }; |
| 125 | 161 | ||
| 126 | gmac0: eth@e2000000 { | 162 | gmac0: eth@e2000000 { |
| 163 | phy-mode = "rgmii"; | ||
| 127 | status = "okay"; | 164 | status = "okay"; |
| 128 | }; | 165 | }; |
| 129 | 166 | ||
| @@ -147,31 +184,62 @@ | |||
| 147 | }; | 184 | }; |
| 148 | partition@10000 { | 185 | partition@10000 { |
| 149 | label = "u-boot"; | 186 | label = "u-boot"; |
| 150 | reg = <0x10000 0x40000>; | 187 | reg = <0x10000 0x50000>; |
| 188 | }; | ||
| 189 | partition@60000 { | ||
| 190 | label = "environment"; | ||
| 191 | reg = <0x60000 0x10000>; | ||
| 192 | }; | ||
| 193 | partition@70000 { | ||
| 194 | label = "dtb"; | ||
| 195 | reg = <0x70000 0x10000>; | ||
| 151 | }; | 196 | }; |
| 152 | partition@50000 { | 197 | partition@80000 { |
| 153 | label = "linux"; | 198 | label = "linux"; |
| 154 | reg = <0x50000 0x2c0000>; | 199 | reg = <0x80000 0x310000>; |
| 155 | }; | 200 | }; |
| 156 | partition@310000 { | 201 | partition@390000 { |
| 157 | label = "rootfs"; | 202 | label = "rootfs"; |
| 158 | reg = <0x310000 0x4f0000>; | 203 | reg = <0x390000 0x0>; |
| 159 | }; | 204 | }; |
| 160 | }; | 205 | }; |
| 161 | }; | 206 | }; |
| 162 | 207 | ||
| 163 | spi0: spi@e0100000 { | 208 | ehci@e4800000 { |
| 164 | status = "okay"; | 209 | status = "okay"; |
| 165 | }; | 210 | }; |
| 166 | 211 | ||
| 167 | ehci@e4800000 { | 212 | gpio_keys { |
| 168 | status = "okay"; | 213 | compatible = "gpio-keys"; |
| 214 | #address-cells = <1>; | ||
| 215 | #size-cells = <0>; | ||
| 216 | |||
| 217 | button@1 { | ||
| 218 | label = "wakeup"; | ||
| 219 | linux,code = <0x100>; | ||
| 220 | gpios = <&gpio1 1 0x4>; | ||
| 221 | debounce-interval = <20>; | ||
| 222 | gpio-key,wakeup = <1>; | ||
| 223 | }; | ||
| 169 | }; | 224 | }; |
| 170 | 225 | ||
| 171 | ehci@e5800000 { | 226 | ehci@e5800000 { |
| 172 | status = "okay"; | 227 | status = "okay"; |
| 173 | }; | 228 | }; |
| 174 | 229 | ||
| 230 | i2s0: i2s-play@b2400000 { | ||
| 231 | status = "okay"; | ||
| 232 | }; | ||
| 233 | |||
| 234 | i2s1: i2s-rec@b2000000 { | ||
| 235 | status = "okay"; | ||
| 236 | }; | ||
| 237 | |||
| 238 | incodec: dir-hifi { | ||
| 239 | compatible = "dummy,dir-hifi"; | ||
| 240 | status = "okay"; | ||
| 241 | }; | ||
| 242 | |||
| 175 | ohci@e4000000 { | 243 | ohci@e4000000 { |
| 176 | status = "okay"; | 244 | status = "okay"; |
| 177 | }; | 245 | }; |
| @@ -180,11 +248,43 @@ | |||
| 180 | status = "okay"; | 248 | status = "okay"; |
| 181 | }; | 249 | }; |
| 182 | 250 | ||
| 251 | outcodec: dit-hifi { | ||
| 252 | compatible = "dummy,dit-hifi"; | ||
| 253 | status = "okay"; | ||
| 254 | }; | ||
| 255 | |||
| 256 | sound { | ||
| 257 | compatible = "spear,spear-evb"; | ||
| 258 | audio-controllers = <&spdif0 &spdif1 &i2s0 &i2s1>; | ||
| 259 | audio-codecs = <&incodec &outcodec &sta529 &sta529>; | ||
| 260 | codec_dai_name = "dir-hifi", "dit-hifi", "sta529-audio", "sta529-audio"; | ||
| 261 | stream_name = "spdif-cap", "spdif-play", "i2s-play", "i2s-cap"; | ||
| 262 | dai_name = "spdifin-pcm", "spdifout-pcm", "i2s0-pcm", "i2s1-pcm"; | ||
| 263 | nr_controllers = <4>; | ||
| 264 | status = "okay"; | ||
| 265 | }; | ||
| 266 | |||
| 267 | spdif0: spdif-in@d0100000 { | ||
| 268 | status = "okay"; | ||
| 269 | }; | ||
| 270 | |||
| 271 | spdif1: spdif-out@d0000000 { | ||
| 272 | status = "okay"; | ||
| 273 | }; | ||
| 274 | |||
| 183 | apb { | 275 | apb { |
| 184 | adc@e0080000 { | 276 | adc@e0080000 { |
| 185 | status = "okay"; | 277 | status = "okay"; |
| 186 | }; | 278 | }; |
| 187 | 279 | ||
| 280 | i2s-play@b2400000 { | ||
| 281 | status = "okay"; | ||
| 282 | }; | ||
| 283 | |||
| 284 | i2s-rec@b2000000 { | ||
| 285 | status = "okay"; | ||
| 286 | }; | ||
| 287 | |||
| 188 | gpio0: gpio@e0600000 { | 288 | gpio0: gpio@e0600000 { |
| 189 | status = "okay"; | 289 | status = "okay"; |
| 190 | }; | 290 | }; |
| @@ -193,12 +293,42 @@ | |||
| 193 | status = "okay"; | 293 | status = "okay"; |
| 194 | }; | 294 | }; |
| 195 | 295 | ||
| 296 | gpio@e2800000 { | ||
| 297 | status = "okay"; | ||
| 298 | }; | ||
| 299 | |||
| 196 | i2c0: i2c@e0280000 { | 300 | i2c0: i2c@e0280000 { |
| 197 | status = "okay"; | 301 | status = "okay"; |
| 302 | |||
| 303 | sta529: sta529@1a { | ||
| 304 | compatible = "st,sta529"; | ||
| 305 | reg = <0x1a>; | ||
| 306 | }; | ||
| 198 | }; | 307 | }; |
| 199 | 308 | ||
| 200 | i2c1: i2c@b4000000 { | 309 | i2c1: i2c@b4000000 { |
| 201 | status = "okay"; | 310 | status = "okay"; |
| 311 | |||
| 312 | eeprom0@56 { | ||
| 313 | compatible = "st,eeprom"; | ||
| 314 | reg = <0x56>; | ||
| 315 | }; | ||
| 316 | |||
| 317 | stmpe801@41 { | ||
| 318 | compatible = "st,stmpe801"; | ||
| 319 | #address-cells = <1>; | ||
| 320 | #size-cells = <0>; | ||
| 321 | reg = <0x41>; | ||
| 322 | interrupts = <4 0x4>; | ||
| 323 | interrupt-parent = <&gpio0>; | ||
| 324 | irq-trigger = <0x2>; | ||
| 325 | |||
| 326 | stmpegpio: stmpe_gpio { | ||
| 327 | compatible = "st,stmpe-gpio"; | ||
| 328 | gpio-controller; | ||
| 329 | #gpio-cells = <2>; | ||
| 330 | }; | ||
| 331 | }; | ||
| 202 | }; | 332 | }; |
| 203 | 333 | ||
| 204 | kbd@e0300000 { | 334 | kbd@e0300000 { |
| @@ -285,6 +415,7 @@ | |||
| 285 | 0x08080052 >; | 415 | 0x08080052 >; |
| 286 | autorepeat; | 416 | autorepeat; |
| 287 | st,mode = <0>; | 417 | st,mode = <0>; |
| 418 | suspended_rate = <2000000>; | ||
| 288 | status = "okay"; | 419 | status = "okay"; |
| 289 | }; | 420 | }; |
| 290 | 421 | ||
| @@ -294,10 +425,92 @@ | |||
| 294 | 425 | ||
| 295 | serial@e0000000 { | 426 | serial@e0000000 { |
| 296 | status = "okay"; | 427 | status = "okay"; |
| 428 | pinctrl-names = "default"; | ||
| 429 | pinctrl-0 = <>; | ||
| 297 | }; | 430 | }; |
| 298 | 431 | ||
| 299 | serial@b4100000 { | 432 | serial@b4100000 { |
| 300 | status = "okay"; | 433 | status = "okay"; |
| 434 | pinctrl-names = "default"; | ||
| 435 | pinctrl-0 = <>; | ||
| 436 | }; | ||
| 437 | |||
| 438 | spi0: spi@e0100000 { | ||
| 439 | status = "okay"; | ||
| 440 | num-cs = <3>; | ||
| 441 | cs-gpios = <&gpiopinctrl 80 0>, <&gpiopinctrl 24 0>, | ||
| 442 | <&gpiopinctrl 85 0>; | ||
| 443 | |||
| 444 | m25p80@0 { | ||
| 445 | compatible = "m25p80"; | ||
| 446 | reg = <0>; | ||
| 447 | spi-max-frequency = <12000000>; | ||
| 448 | spi-cpol; | ||
| 449 | spi-cpha; | ||
| 450 | pl022,hierarchy = <0>; | ||
| 451 | pl022,interface = <0>; | ||
| 452 | pl022,slave-tx-disable; | ||
| 453 | pl022,com-mode = <0x2>; | ||
| 454 | pl022,rx-level-trig = <0>; | ||
| 455 | pl022,tx-level-trig = <0>; | ||
| 456 | pl022,ctrl-len = <0x11>; | ||
| 457 | pl022,wait-state = <0>; | ||
| 458 | pl022,duplex = <0>; | ||
| 459 | }; | ||
| 460 | |||
| 461 | stmpe610@1 { | ||
| 462 | compatible = "st,stmpe610"; | ||
| 463 | spi-max-frequency = <1000000>; | ||
| 464 | spi-cpha; | ||
| 465 | reg = <1>; | ||
| 466 | pl022,hierarchy = <0>; | ||
| 467 | pl022,interface = <0>; | ||
| 468 | pl022,slave-tx-disable; | ||
| 469 | pl022,com-mode = <0>; | ||
| 470 | pl022,rx-level-trig = <0>; | ||
| 471 | pl022,tx-level-trig = <0>; | ||
| 472 | pl022,ctrl-len = <0x7>; | ||
| 473 | pl022,wait-state = <0>; | ||
| 474 | pl022,duplex = <0>; | ||
| 475 | interrupts = <100 0>; | ||
| 476 | interrupt-parent = <&gpiopinctrl>; | ||
| 477 | irq-trigger = <0x2>; | ||
| 478 | #address-cells = <1>; | ||
| 479 | #size-cells = <0>; | ||
| 480 | |||
| 481 | stmpe_touchscreen { | ||
| 482 | compatible = "st,stmpe-ts"; | ||
| 483 | ts,sample-time = <4>; | ||
| 484 | ts,mod-12b = <1>; | ||
| 485 | ts,ref-sel = <0>; | ||
| 486 | ts,adc-freq = <1>; | ||
| 487 | ts,ave-ctrl = <1>; | ||
| 488 | ts,touch-det-delay = <2>; | ||
| 489 | ts,settling = <2>; | ||
| 490 | ts,fraction-z = <7>; | ||
| 491 | ts,i-drive = <1>; | ||
| 492 | }; | ||
| 493 | }; | ||
| 494 | |||
| 495 | spidev@2 { | ||
| 496 | compatible = "spidev"; | ||
| 497 | reg = <2>; | ||
| 498 | spi-max-frequency = <25000000>; | ||
| 499 | spi-cpha; | ||
| 500 | pl022,hierarchy = <0>; | ||
| 501 | pl022,interface = <0>; | ||
| 502 | pl022,slave-tx-disable; | ||
| 503 | pl022,com-mode = <0x2>; | ||
| 504 | pl022,rx-level-trig = <0>; | ||
| 505 | pl022,tx-level-trig = <0>; | ||
| 506 | pl022,ctrl-len = <0x11>; | ||
| 507 | pl022,wait-state = <0>; | ||
| 508 | pl022,duplex = <0>; | ||
| 509 | }; | ||
| 510 | }; | ||
| 511 | |||
| 512 | timer@ec800600 { | ||
| 513 | status = "okay"; | ||
| 301 | }; | 514 | }; |
| 302 | 515 | ||
| 303 | wdt@ec800620 { | 516 | wdt@ec800620 { |
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index d71fe2a68f09..34da11aa6795 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi | |||
| @@ -17,6 +17,20 @@ | |||
| 17 | compatible = "st,spear1340"; | 17 | compatible = "st,spear1340"; |
| 18 | 18 | ||
| 19 | ahb { | 19 | ahb { |
| 20 | |||
| 21 | spics: spics@e0700000{ | ||
| 22 | compatible = "st,spear-spics-gpio"; | ||
| 23 | reg = <0xe0700000 0x1000>; | ||
| 24 | st-spics,peripcfg-reg = <0x42c>; | ||
| 25 | st-spics,sw-enable-bit = <21>; | ||
| 26 | st-spics,cs-value-bit = <20>; | ||
| 27 | st-spics,cs-enable-mask = <3>; | ||
| 28 | st-spics,cs-enable-shift = <18>; | ||
| 29 | gpio-controller; | ||
| 30 | #gpio-cells = <2>; | ||
| 31 | status = "disabled"; | ||
| 32 | }; | ||
| 33 | |||
| 20 | ahci@b1000000 { | 34 | ahci@b1000000 { |
| 21 | compatible = "snps,spear-ahci"; | 35 | compatible = "snps,spear-ahci"; |
| 22 | reg = <0xb1000000 0x10000>; | 36 | reg = <0xb1000000 0x10000>; |
| @@ -24,9 +38,61 @@ | |||
| 24 | status = "disabled"; | 38 | status = "disabled"; |
| 25 | }; | 39 | }; |
| 26 | 40 | ||
| 41 | i2s-play@b2400000 { | ||
| 42 | compatible = "snps,designware-i2s"; | ||
| 43 | reg = <0xb2400000 0x10000>; | ||
| 44 | interrupt-names = "play_irq"; | ||
| 45 | interrupts = <0 98 0x4 | ||
| 46 | 0 99 0x4>; | ||
| 47 | play; | ||
| 48 | channel = <8>; | ||
| 49 | status = "disabled"; | ||
| 50 | }; | ||
| 51 | |||
| 52 | i2s-rec@b2000000 { | ||
| 53 | compatible = "snps,designware-i2s"; | ||
| 54 | reg = <0xb2000000 0x10000>; | ||
| 55 | interrupt-names = "record_irq"; | ||
| 56 | interrupts = <0 100 0x4 | ||
| 57 | 0 101 0x4>; | ||
| 58 | record; | ||
| 59 | channel = <8>; | ||
| 60 | status = "disabled"; | ||
| 61 | }; | ||
| 62 | |||
| 63 | pinmux: pinmux@e0700000 { | ||
| 64 | compatible = "st,spear1340-pinmux"; | ||
| 65 | reg = <0xe0700000 0x1000>; | ||
| 66 | #gpio-range-cells = <2>; | ||
| 67 | }; | ||
| 68 | |||
| 69 | pwm: pwm@e0180000 { | ||
| 70 | compatible ="st,spear13xx-pwm"; | ||
| 71 | reg = <0xe0180000 0x1000>; | ||
| 72 | #pwm-cells = <2>; | ||
| 73 | status = "disabled"; | ||
| 74 | }; | ||
| 75 | |||
| 76 | spdif-in@d0100000 { | ||
| 77 | compatible = "st,spdif-in"; | ||
| 78 | reg = < 0xd0100000 0x20000 | ||
| 79 | 0xd0110000 0x10000 >; | ||
| 80 | interrupts = <0 84 0x4>; | ||
| 81 | status = "disabled"; | ||
| 82 | }; | ||
| 83 | |||
| 84 | spdif-out@d0000000 { | ||
| 85 | compatible = "st,spdif-out"; | ||
| 86 | reg = <0xd0000000 0x20000>; | ||
| 87 | interrupts = <0 85 0x4>; | ||
| 88 | status = "disabled"; | ||
| 89 | }; | ||
| 90 | |||
| 27 | spi1: spi@5d400000 { | 91 | spi1: spi@5d400000 { |
| 28 | compatible = "arm,pl022", "arm,primecell"; | 92 | compatible = "arm,pl022", "arm,primecell"; |
| 29 | reg = <0x5d400000 0x1000>; | 93 | reg = <0x5d400000 0x1000>; |
| 94 | #address-cells = <1>; | ||
| 95 | #size-cells = <0>; | ||
| 30 | interrupts = <0 99 0x4>; | 96 | interrupts = <0 99 0x4>; |
| 31 | status = "disabled"; | 97 | status = "disabled"; |
| 32 | }; | 98 | }; |
| @@ -38,6 +104,7 @@ | |||
| 38 | compatible = "snps,designware-i2c"; | 104 | compatible = "snps,designware-i2c"; |
| 39 | reg = <0xb4000000 0x1000>; | 105 | reg = <0xb4000000 0x1000>; |
| 40 | interrupts = <0 104 0x4>; | 106 | interrupts = <0 104 0x4>; |
| 107 | write-16bit; | ||
| 41 | status = "disabled"; | 108 | status = "disabled"; |
| 42 | }; | 109 | }; |
| 43 | 110 | ||
| @@ -51,6 +118,26 @@ | |||
| 51 | thermal@e07008c4 { | 118 | thermal@e07008c4 { |
| 52 | st,thermal-flags = <0x2a00>; | 119 | st,thermal-flags = <0x2a00>; |
| 53 | }; | 120 | }; |
| 121 | |||
| 122 | gpiopinctrl: gpio@e2800000 { | ||
| 123 | compatible = "st,spear-plgpio"; | ||
| 124 | reg = <0xe2800000 0x1000>; | ||
| 125 | interrupts = <0 107 0x4>; | ||
| 126 | #interrupt-cells = <1>; | ||
| 127 | interrupt-controller; | ||
| 128 | gpio-controller; | ||
| 129 | #gpio-cells = <2>; | ||
| 130 | gpio-ranges = <&pinmux 0 252>; | ||
| 131 | status = "disabled"; | ||
| 132 | |||
| 133 | st-plgpio,ngpio = <250>; | ||
| 134 | st-plgpio,wdata-reg = <0x40>; | ||
| 135 | st-plgpio,dir-reg = <0x00>; | ||
| 136 | st-plgpio,ie-reg = <0x80>; | ||
| 137 | st-plgpio,rdata-reg = <0x20>; | ||
| 138 | st-plgpio,mis-reg = <0xa0>; | ||
| 139 | st-plgpio,eit-reg = <0x60>; | ||
| 140 | }; | ||
| 54 | }; | 141 | }; |
| 55 | }; | 142 | }; |
| 56 | }; | 143 | }; |
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index f7b84aced654..009096d1d2c3 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi | |||
| @@ -64,12 +64,26 @@ | |||
| 64 | bootargs = "console=ttyAMA0,115200"; | 64 | bootargs = "console=ttyAMA0,115200"; |
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | cpufreq { | ||
| 68 | compatible = "st,cpufreq-spear"; | ||
| 69 | cpufreq_tbl = < 166000 | ||
| 70 | 200000 | ||
| 71 | 250000 | ||
| 72 | 300000 | ||
| 73 | 400000 | ||
| 74 | 500000 | ||
| 75 | 600000 >; | ||
| 76 | status = "disable"; | ||
| 77 | }; | ||
| 78 | |||
| 67 | ahb { | 79 | ahb { |
| 68 | #address-cells = <1>; | 80 | #address-cells = <1>; |
| 69 | #size-cells = <1>; | 81 | #size-cells = <1>; |
| 70 | compatible = "simple-bus"; | 82 | compatible = "simple-bus"; |
| 71 | ranges = <0x50000000 0x50000000 0x10000000 | 83 | ranges = <0x50000000 0x50000000 0x10000000 |
| 72 | 0xb0000000 0xb0000000 0x10000000 | 84 | 0xb0000000 0xb0000000 0x10000000 |
| 85 | 0xd0000000 0xd0000000 0x02000000 | ||
| 86 | 0xd8000000 0xd8000000 0x01000000 | ||
| 73 | 0xe0000000 0xe0000000 0x10000000>; | 87 | 0xe0000000 0xe0000000 0x10000000>; |
| 74 | 88 | ||
| 75 | sdhci@b3000000 { | 89 | sdhci@b3000000 { |
| @@ -81,7 +95,7 @@ | |||
| 81 | 95 | ||
| 82 | cf@b2800000 { | 96 | cf@b2800000 { |
| 83 | compatible = "arasan,cf-spear1340"; | 97 | compatible = "arasan,cf-spear1340"; |
| 84 | reg = <0xb2800000 0x100>; | 98 | reg = <0xb2800000 0x1000>; |
| 85 | interrupts = <0 29 0x4>; | 99 | interrupts = <0 29 0x4>; |
| 86 | status = "disabled"; | 100 | status = "disabled"; |
| 87 | }; | 101 | }; |
| @@ -113,6 +127,7 @@ | |||
| 113 | 0 23 0x4>; | 127 | 0 23 0x4>; |
| 114 | st,ale-off = <0x20000>; | 128 | st,ale-off = <0x20000>; |
| 115 | st,cle-off = <0x10000>; | 129 | st,cle-off = <0x10000>; |
| 130 | st,mode = <2>; | ||
| 116 | status = "disabled"; | 131 | status = "disabled"; |
| 117 | }; | 132 | }; |
| 118 | 133 | ||
| @@ -125,6 +140,13 @@ | |||
| 125 | status = "disabled"; | 140 | status = "disabled"; |
| 126 | }; | 141 | }; |
| 127 | 142 | ||
| 143 | pcm { | ||
| 144 | compatible = "st,pcm-audio"; | ||
| 145 | #address-cells = <0>; | ||
| 146 | #size-cells = <0>; | ||
| 147 | status = "disable"; | ||
| 148 | }; | ||
| 149 | |||
| 128 | smi: flash@ea000000 { | 150 | smi: flash@ea000000 { |
| 129 | compatible = "st,spear600-smi"; | 151 | compatible = "st,spear600-smi"; |
| 130 | #address-cells = <1>; | 152 | #address-cells = <1>; |
| @@ -134,17 +156,11 @@ | |||
| 134 | status = "disabled"; | 156 | status = "disabled"; |
| 135 | }; | 157 | }; |
| 136 | 158 | ||
| 137 | spi0: spi@e0100000 { | ||
| 138 | compatible = "arm,pl022", "arm,primecell"; | ||
| 139 | reg = <0xe0100000 0x1000>; | ||
| 140 | interrupts = <0 31 0x4>; | ||
| 141 | status = "disabled"; | ||
| 142 | }; | ||
| 143 | |||
| 144 | ehci@e4800000 { | 159 | ehci@e4800000 { |
| 145 | compatible = "st,spear600-ehci", "usb-ehci"; | 160 | compatible = "st,spear600-ehci", "usb-ehci"; |
| 146 | reg = <0xe4800000 0x1000>; | 161 | reg = <0xe4800000 0x1000>; |
| 147 | interrupts = <0 64 0x4>; | 162 | interrupts = <0 64 0x4>; |
| 163 | usbh0_id = <0>; | ||
| 148 | status = "disabled"; | 164 | status = "disabled"; |
| 149 | }; | 165 | }; |
| 150 | 166 | ||
| @@ -152,6 +168,7 @@ | |||
| 152 | compatible = "st,spear600-ehci", "usb-ehci"; | 168 | compatible = "st,spear600-ehci", "usb-ehci"; |
| 153 | reg = <0xe5800000 0x1000>; | 169 | reg = <0xe5800000 0x1000>; |
| 154 | interrupts = <0 66 0x4>; | 170 | interrupts = <0 66 0x4>; |
| 171 | usbh1_id = <1>; | ||
| 155 | status = "disabled"; | 172 | status = "disabled"; |
| 156 | }; | 173 | }; |
| 157 | 174 | ||
| @@ -159,6 +176,7 @@ | |||
| 159 | compatible = "st,spear600-ohci", "usb-ohci"; | 176 | compatible = "st,spear600-ohci", "usb-ohci"; |
| 160 | reg = <0xe4000000 0x1000>; | 177 | reg = <0xe4000000 0x1000>; |
| 161 | interrupts = <0 65 0x4>; | 178 | interrupts = <0 65 0x4>; |
| 179 | usbh0_id = <0>; | ||
| 162 | status = "disabled"; | 180 | status = "disabled"; |
| 163 | }; | 181 | }; |
| 164 | 182 | ||
| @@ -166,6 +184,7 @@ | |||
| 166 | compatible = "st,spear600-ohci", "usb-ohci"; | 184 | compatible = "st,spear600-ohci", "usb-ohci"; |
| 167 | reg = <0xe5000000 0x1000>; | 185 | reg = <0xe5000000 0x1000>; |
| 168 | interrupts = <0 67 0x4>; | 186 | interrupts = <0 67 0x4>; |
| 187 | usbh1_id = <1>; | ||
| 169 | status = "disabled"; | 188 | status = "disabled"; |
| 170 | }; | 189 | }; |
| 171 | 190 | ||
| @@ -175,6 +194,8 @@ | |||
| 175 | compatible = "simple-bus"; | 194 | compatible = "simple-bus"; |
| 176 | ranges = <0x50000000 0x50000000 0x10000000 | 195 | ranges = <0x50000000 0x50000000 0x10000000 |
| 177 | 0xb0000000 0xb0000000 0x10000000 | 196 | 0xb0000000 0xb0000000 0x10000000 |
| 197 | 0xd0000000 0xd0000000 0x02000000 | ||
| 198 | 0xd8000000 0xd8000000 0x01000000 | ||
| 178 | 0xe0000000 0xe0000000 0x10000000>; | 199 | 0xe0000000 0xe0000000 0x10000000>; |
| 179 | 200 | ||
| 180 | gpio0: gpio@e0600000 { | 201 | gpio0: gpio@e0600000 { |
| @@ -215,8 +236,35 @@ | |||
| 215 | status = "disabled"; | 236 | status = "disabled"; |
| 216 | }; | 237 | }; |
| 217 | 238 | ||
| 239 | i2s@e0180000 { | ||
| 240 | compatible = "st,designware-i2s"; | ||
| 241 | reg = <0xe0180000 0x1000>; | ||
| 242 | interrupt-names = "play_irq", "record_irq"; | ||
| 243 | interrupts = <0 10 0x4 | ||
| 244 | 0 11 0x4 >; | ||
| 245 | status = "disabled"; | ||
| 246 | }; | ||
| 247 | |||
| 248 | i2s@e0200000 { | ||
| 249 | compatible = "st,designware-i2s"; | ||
| 250 | reg = <0xe0200000 0x1000>; | ||
| 251 | interrupt-names = "play_irq", "record_irq"; | ||
| 252 | interrupts = <0 26 0x4 | ||
| 253 | 0 53 0x4>; | ||
| 254 | status = "disabled"; | ||
| 255 | }; | ||
| 256 | |||
| 257 | spi0: spi@e0100000 { | ||
| 258 | compatible = "arm,pl022", "arm,primecell"; | ||
| 259 | reg = <0xe0100000 0x1000>; | ||
| 260 | #address-cells = <1>; | ||
| 261 | #size-cells = <0>; | ||
| 262 | interrupts = <0 31 0x4>; | ||
| 263 | status = "disabled"; | ||
| 264 | }; | ||
| 265 | |||
| 218 | rtc@e0580000 { | 266 | rtc@e0580000 { |
| 219 | compatible = "st,spear-rtc"; | 267 | compatible = "st,spear600-rtc"; |
| 220 | reg = <0xe0580000 0x1000>; | 268 | reg = <0xe0580000 0x1000>; |
| 221 | interrupts = <0 36 0x4>; | 269 | interrupts = <0 36 0x4>; |
| 222 | status = "disabled"; | 270 | status = "disabled"; |
| @@ -232,7 +280,7 @@ | |||
| 232 | adc@e0080000 { | 280 | adc@e0080000 { |
| 233 | compatible = "st,spear600-adc"; | 281 | compatible = "st,spear600-adc"; |
| 234 | reg = <0xe0080000 0x1000>; | 282 | reg = <0xe0080000 0x1000>; |
| 235 | interrupts = <0 44 0x4>; | 283 | interrupts = <0 12 0x4>; |
| 236 | status = "disabled"; | 284 | status = "disabled"; |
| 237 | }; | 285 | }; |
| 238 | 286 | ||
| @@ -245,7 +293,8 @@ | |||
| 245 | timer@ec800600 { | 293 | timer@ec800600 { |
| 246 | compatible = "arm,cortex-a9-twd-timer"; | 294 | compatible = "arm,cortex-a9-twd-timer"; |
| 247 | reg = <0xec800600 0x20>; | 295 | reg = <0xec800600 0x20>; |
| 248 | interrupts = <1 13 0x301>; | 296 | interrupts = <1 13 0x4>; |
| 297 | status = "disabled"; | ||
| 249 | }; | 298 | }; |
| 250 | 299 | ||
| 251 | wdt@ec800620 { | 300 | wdt@ec800620 { |
| @@ -257,6 +306,7 @@ | |||
| 257 | thermal@e07008c4 { | 306 | thermal@e07008c4 { |
| 258 | compatible = "st,thermal-spear1340"; | 307 | compatible = "st,thermal-spear1340"; |
| 259 | reg = <0xe07008c4 0x4>; | 308 | reg = <0xe07008c4 0x4>; |
| 309 | thermal_flags = <0x7000>; | ||
| 260 | }; | 310 | }; |
| 261 | }; | 311 | }; |
| 262 | }; | 312 | }; |
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts index 1e7c7a8e2123..5de1431653e4 100644 --- a/arch/arm/boot/dts/spear300-evb.dts +++ b/arch/arm/boot/dts/spear300-evb.dts | |||
| @@ -100,15 +100,23 @@ | |||
| 100 | }; | 100 | }; |
| 101 | partition@10000 { | 101 | partition@10000 { |
| 102 | label = "u-boot"; | 102 | label = "u-boot"; |
| 103 | reg = <0x10000 0x40000>; | 103 | reg = <0x10000 0x50000>; |
| 104 | }; | 104 | }; |
| 105 | partition@50000 { | 105 | partition@60000 { |
| 106 | label = "environment"; | ||
| 107 | reg = <0x60000 0x10000>; | ||
| 108 | }; | ||
| 109 | partition@70000 { | ||
| 110 | label = "dtb"; | ||
| 111 | reg = <0x70000 0x10000>; | ||
| 112 | }; | ||
| 113 | partition@80000 { | ||
| 106 | label = "linux"; | 114 | label = "linux"; |
| 107 | reg = <0x50000 0x2c0000>; | 115 | reg = <0x80000 0x310000>; |
| 108 | }; | 116 | }; |
| 109 | partition@310000 { | 117 | partition@390000 { |
| 110 | label = "rootfs"; | 118 | label = "rootfs"; |
| 111 | reg = <0x310000 0x4f0000>; | 119 | reg = <0x390000 0x0>; |
| 112 | }; | 120 | }; |
| 113 | }; | 121 | }; |
| 114 | }; | 122 | }; |
| @@ -235,6 +243,8 @@ | |||
| 235 | 243 | ||
| 236 | serial@d0000000 { | 244 | serial@d0000000 { |
| 237 | status = "okay"; | 245 | status = "okay"; |
| 246 | pinctrl-names = "default"; | ||
| 247 | pinctrl-0 = <>; | ||
| 238 | }; | 248 | }; |
| 239 | 249 | ||
| 240 | wdt@fc880000 { | 250 | wdt@fc880000 { |
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index ed3627c116cc..090adc656015 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | }; | 27 | }; |
| 28 | 28 | ||
| 29 | clcd@60000000 { | 29 | clcd@60000000 { |
| 30 | compatible = "arm,clcd-pl110", "arm,primecell"; | 30 | compatible = "arm,pl110", "arm,primecell"; |
| 31 | reg = <0x60000000 0x1000>; | 31 | reg = <0x60000000 0x1000>; |
| 32 | interrupts = <30>; | 32 | interrupts = <30>; |
| 33 | status = "disabled"; | 33 | status = "disabled"; |
| @@ -52,6 +52,14 @@ | |||
| 52 | status = "disabled"; | 52 | status = "disabled"; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | shirq: interrupt-controller@0x50000000 { | ||
| 56 | compatible = "st,spear300-shirq"; | ||
| 57 | reg = <0x50000000 0x1000>; | ||
| 58 | interrupts = <28>; | ||
| 59 | #interrupt-cells = <1>; | ||
| 60 | interrupt-controller; | ||
| 61 | }; | ||
| 62 | |||
| 55 | apb { | 63 | apb { |
| 56 | #address-cells = <1>; | 64 | #address-cells = <1>; |
| 57 | #size-cells = <1>; | 65 | #size-cells = <1>; |
| @@ -64,12 +72,16 @@ | |||
| 64 | compatible = "arm,pl061", "arm,primecell"; | 72 | compatible = "arm,pl061", "arm,primecell"; |
| 65 | gpio-controller; | 73 | gpio-controller; |
| 66 | reg = <0xa9000000 0x1000>; | 74 | reg = <0xa9000000 0x1000>; |
| 75 | interrupts = <8>; | ||
| 76 | interrupt-parent = <&shirq>; | ||
| 67 | status = "disabled"; | 77 | status = "disabled"; |
| 68 | }; | 78 | }; |
| 69 | 79 | ||
| 70 | kbd@a0000000 { | 80 | kbd@a0000000 { |
| 71 | compatible = "st,spear300-kbd"; | 81 | compatible = "st,spear300-kbd"; |
| 72 | reg = <0xa0000000 0x1000>; | 82 | reg = <0xa0000000 0x1000>; |
| 83 | interrupts = <7>; | ||
| 84 | interrupt-parent = <&shirq>; | ||
| 73 | status = "disabled"; | 85 | status = "disabled"; |
| 74 | }; | 86 | }; |
| 75 | }; | 87 | }; |
diff --git a/arch/arm/boot/dts/spear310-evb.dts b/arch/arm/boot/dts/spear310-evb.dts index b00544e0cd5d..b09632963d15 100644 --- a/arch/arm/boot/dts/spear310-evb.dts +++ b/arch/arm/boot/dts/spear310-evb.dts | |||
| @@ -114,15 +114,23 @@ | |||
| 114 | }; | 114 | }; |
| 115 | partition@10000 { | 115 | partition@10000 { |
| 116 | label = "u-boot"; | 116 | label = "u-boot"; |
| 117 | reg = <0x10000 0x40000>; | 117 | reg = <0x10000 0x50000>; |
| 118 | }; | 118 | }; |
| 119 | partition@50000 { | 119 | partition@60000 { |
| 120 | label = "environment"; | ||
| 121 | reg = <0x60000 0x10000>; | ||
| 122 | }; | ||
| 123 | partition@70000 { | ||
| 124 | label = "dtb"; | ||
| 125 | reg = <0x70000 0x10000>; | ||
| 126 | }; | ||
| 127 | partition@80000 { | ||
| 120 | label = "linux"; | 128 | label = "linux"; |
| 121 | reg = <0x50000 0x2c0000>; | 129 | reg = <0x80000 0x310000>; |
| 122 | }; | 130 | }; |
| 123 | partition@310000 { | 131 | partition@390000 { |
| 124 | label = "rootfs"; | 132 | label = "rootfs"; |
| 125 | reg = <0x310000 0x4f0000>; | 133 | reg = <0x390000 0x0>; |
| 126 | }; | 134 | }; |
| 127 | }; | 135 | }; |
| 128 | }; | 136 | }; |
| @@ -158,26 +166,38 @@ | |||
| 158 | 166 | ||
| 159 | serial@d0000000 { | 167 | serial@d0000000 { |
| 160 | status = "okay"; | 168 | status = "okay"; |
| 169 | pinctrl-names = "default"; | ||
| 170 | pinctrl-0 = <>; | ||
| 161 | }; | 171 | }; |
| 162 | 172 | ||
| 163 | serial@b2000000 { | 173 | serial@b2000000 { |
| 164 | status = "okay"; | 174 | status = "okay"; |
| 175 | pinctrl-names = "default"; | ||
| 176 | pinctrl-0 = <>; | ||
| 165 | }; | 177 | }; |
| 166 | 178 | ||
| 167 | serial@b2080000 { | 179 | serial@b2080000 { |
| 168 | status = "okay"; | 180 | status = "okay"; |
| 181 | pinctrl-names = "default"; | ||
| 182 | pinctrl-0 = <>; | ||
| 169 | }; | 183 | }; |
| 170 | 184 | ||
| 171 | serial@b2100000 { | 185 | serial@b2100000 { |
| 172 | status = "okay"; | 186 | status = "okay"; |
| 187 | pinctrl-names = "default"; | ||
| 188 | pinctrl-0 = <>; | ||
| 173 | }; | 189 | }; |
| 174 | 190 | ||
| 175 | serial@b2180000 { | 191 | serial@b2180000 { |
| 176 | status = "okay"; | 192 | status = "okay"; |
| 193 | pinctrl-names = "default"; | ||
| 194 | pinctrl-0 = <>; | ||
| 177 | }; | 195 | }; |
| 178 | 196 | ||
| 179 | serial@b2200000 { | 197 | serial@b2200000 { |
| 180 | status = "okay"; | 198 | status = "okay"; |
| 199 | pinctrl-names = "default"; | ||
| 200 | pinctrl-0 = <>; | ||
| 181 | }; | 201 | }; |
| 182 | 202 | ||
| 183 | wdt@fc880000 { | 203 | wdt@fc880000 { |
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index 62fc4fb3e5f9..e814e5e97083 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi | |||
| @@ -22,9 +22,10 @@ | |||
| 22 | 0xb0000000 0xb0000000 0x10000000 | 22 | 0xb0000000 0xb0000000 0x10000000 |
| 23 | 0xd0000000 0xd0000000 0x30000000>; | 23 | 0xd0000000 0xd0000000 0x30000000>; |
| 24 | 24 | ||
| 25 | pinmux@b4000000 { | 25 | pinmux: pinmux@b4000000 { |
| 26 | compatible = "st,spear310-pinmux"; | 26 | compatible = "st,spear310-pinmux"; |
| 27 | reg = <0xb4000000 0x1000>; | 27 | reg = <0xb4000000 0x1000>; |
| 28 | #gpio-range-cells = <2>; | ||
| 28 | }; | 29 | }; |
| 29 | 30 | ||
| 30 | fsmc: flash@44000000 { | 31 | fsmc: flash@44000000 { |
| @@ -39,6 +40,14 @@ | |||
| 39 | status = "disabled"; | 40 | status = "disabled"; |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 43 | shirq: interrupt-controller@0xb4000000 { | ||
| 44 | compatible = "st,spear310-shirq"; | ||
| 45 | reg = <0xb4000000 0x1000>; | ||
| 46 | interrupts = <28 29 30 1>; | ||
| 47 | #interrupt-cells = <1>; | ||
| 48 | interrupt-controller; | ||
| 49 | }; | ||
| 50 | |||
| 42 | apb { | 51 | apb { |
| 43 | #address-cells = <1>; | 52 | #address-cells = <1>; |
| 44 | #size-cells = <1>; | 53 | #size-cells = <1>; |
| @@ -49,32 +58,61 @@ | |||
| 49 | serial@b2000000 { | 58 | serial@b2000000 { |
| 50 | compatible = "arm,pl011", "arm,primecell"; | 59 | compatible = "arm,pl011", "arm,primecell"; |
| 51 | reg = <0xb2000000 0x1000>; | 60 | reg = <0xb2000000 0x1000>; |
| 61 | interrupts = <8>; | ||
| 62 | interrupt-parent = <&shirq>; | ||
| 52 | status = "disabled"; | 63 | status = "disabled"; |
| 53 | }; | 64 | }; |
| 54 | 65 | ||
| 55 | serial@b2080000 { | 66 | serial@b2080000 { |
| 56 | compatible = "arm,pl011", "arm,primecell"; | 67 | compatible = "arm,pl011", "arm,primecell"; |
| 57 | reg = <0xb2080000 0x1000>; | 68 | reg = <0xb2080000 0x1000>; |
| 69 | interrupts = <9>; | ||
| 70 | interrupt-parent = <&shirq>; | ||
| 58 | status = "disabled"; | 71 | status = "disabled"; |
| 59 | }; | 72 | }; |
| 60 | 73 | ||
| 61 | serial@b2100000 { | 74 | serial@b2100000 { |
| 62 | compatible = "arm,pl011", "arm,primecell"; | 75 | compatible = "arm,pl011", "arm,primecell"; |
| 63 | reg = <0xb2100000 0x1000>; | 76 | reg = <0xb2100000 0x1000>; |
| 77 | interrupts = <10>; | ||
| 78 | interrupt-parent = <&shirq>; | ||
| 64 | status = "disabled"; | 79 | status = "disabled"; |
| 65 | }; | 80 | }; |
| 66 | 81 | ||
| 67 | serial@b2180000 { | 82 | serial@b2180000 { |
| 68 | compatible = "arm,pl011", "arm,primecell"; | 83 | compatible = "arm,pl011", "arm,primecell"; |
| 69 | reg = <0xb2180000 0x1000>; | 84 | reg = <0xb2180000 0x1000>; |
| 85 | interrupts = <11>; | ||
| 86 | interrupt-parent = <&shirq>; | ||
| 70 | status = "disabled"; | 87 | status = "disabled"; |
| 71 | }; | 88 | }; |
| 72 | 89 | ||
| 73 | serial@b2200000 { | 90 | serial@b2200000 { |
| 74 | compatible = "arm,pl011", "arm,primecell"; | 91 | compatible = "arm,pl011", "arm,primecell"; |
| 75 | reg = <0xb2200000 0x1000>; | 92 | reg = <0xb2200000 0x1000>; |
| 93 | interrupts = <12>; | ||
| 94 | interrupt-parent = <&shirq>; | ||
| 76 | status = "disabled"; | 95 | status = "disabled"; |
| 77 | }; | 96 | }; |
| 97 | |||
| 98 | gpiopinctrl: gpio@b4000000 { | ||
| 99 | compatible = "st,spear-plgpio"; | ||
| 100 | reg = <0xb4000000 0x1000>; | ||
| 101 | #interrupt-cells = <1>; | ||
| 102 | interrupt-controller; | ||
| 103 | gpio-controller; | ||
| 104 | #gpio-cells = <2>; | ||
| 105 | gpio-ranges = <&pinmux 0 102>; | ||
| 106 | status = "disabled"; | ||
| 107 | |||
| 108 | st-plgpio,ngpio = <102>; | ||
| 109 | st-plgpio,enb-reg = <0x10>; | ||
| 110 | st-plgpio,wdata-reg = <0x20>; | ||
| 111 | st-plgpio,dir-reg = <0x30>; | ||
| 112 | st-plgpio,ie-reg = <0x50>; | ||
| 113 | st-plgpio,rdata-reg = <0x40>; | ||
| 114 | st-plgpio,mis-reg = <0x60>; | ||
| 115 | }; | ||
| 78 | }; | 116 | }; |
| 79 | }; | 117 | }; |
| 80 | }; | 118 | }; |
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts index 082328bd64ab..fdedbb514102 100644 --- a/arch/arm/boot/dts/spear320-evb.dts +++ b/arch/arm/boot/dts/spear320-evb.dts | |||
| @@ -76,20 +76,12 @@ | |||
| 76 | st,function = "mii2"; | 76 | st,function = "mii2"; |
| 77 | }; | 77 | }; |
| 78 | pwm0_1 { | 78 | pwm0_1 { |
| 79 | st,pins = "pwm0_1_pin_14_15_grp"; | 79 | st,pins = "pwm0_1_pin_37_38_grp"; |
| 80 | st,function = "pwm0_1"; | 80 | st,function = "pwm0_1"; |
| 81 | }; | 81 | }; |
| 82 | pwm2 { | ||
| 83 | st,pins = "pwm2_pin_13_grp"; | ||
| 84 | st,function = "pwm2"; | ||
| 85 | }; | ||
| 86 | }; | 82 | }; |
| 87 | }; | 83 | }; |
| 88 | 84 | ||
| 89 | clcd@90000000 { | ||
| 90 | status = "okay"; | ||
| 91 | }; | ||
| 92 | |||
| 93 | dma@fc400000 { | 85 | dma@fc400000 { |
| 94 | status = "okay"; | 86 | status = "okay"; |
| 95 | }; | 87 | }; |
| @@ -103,6 +95,7 @@ | |||
| 103 | }; | 95 | }; |
| 104 | 96 | ||
| 105 | sdhci@70000000 { | 97 | sdhci@70000000 { |
| 98 | power-gpio = <&gpiopinctrl 61 1>; | ||
| 106 | status = "okay"; | 99 | status = "okay"; |
| 107 | }; | 100 | }; |
| 108 | 101 | ||
| @@ -122,15 +115,23 @@ | |||
| 122 | }; | 115 | }; |
| 123 | partition@10000 { | 116 | partition@10000 { |
| 124 | label = "u-boot"; | 117 | label = "u-boot"; |
| 125 | reg = <0x10000 0x40000>; | 118 | reg = <0x10000 0x50000>; |
| 119 | }; | ||
| 120 | partition@60000 { | ||
| 121 | label = "environment"; | ||
| 122 | reg = <0x60000 0x10000>; | ||
| 126 | }; | 123 | }; |
| 127 | partition@50000 { | 124 | partition@70000 { |
| 125 | label = "dtb"; | ||
| 126 | reg = <0x70000 0x10000>; | ||
| 127 | }; | ||
| 128 | partition@80000 { | ||
| 128 | label = "linux"; | 129 | label = "linux"; |
| 129 | reg = <0x50000 0x2c0000>; | 130 | reg = <0x80000 0x310000>; |
| 130 | }; | 131 | }; |
| 131 | partition@310000 { | 132 | partition@390000 { |
| 132 | label = "rootfs"; | 133 | label = "rootfs"; |
| 133 | reg = <0x310000 0x4f0000>; | 134 | reg = <0x390000 0x0>; |
| 134 | }; | 135 | }; |
| 135 | }; | 136 | }; |
| 136 | }; | 137 | }; |
| @@ -164,6 +165,10 @@ | |||
| 164 | status = "okay"; | 165 | status = "okay"; |
| 165 | }; | 166 | }; |
| 166 | 167 | ||
| 168 | gpio@b3000000 { | ||
| 169 | status = "okay"; | ||
| 170 | }; | ||
| 171 | |||
| 167 | i2c0: i2c@d0180000 { | 172 | i2c0: i2c@d0180000 { |
| 168 | status = "okay"; | 173 | status = "okay"; |
| 169 | }; | 174 | }; |
| @@ -178,14 +183,20 @@ | |||
| 178 | 183 | ||
| 179 | serial@d0000000 { | 184 | serial@d0000000 { |
| 180 | status = "okay"; | 185 | status = "okay"; |
| 186 | pinctrl-names = "default"; | ||
| 187 | pinctrl-0 = <>; | ||
| 181 | }; | 188 | }; |
| 182 | 189 | ||
| 183 | serial@a3000000 { | 190 | serial@a3000000 { |
| 184 | status = "okay"; | 191 | status = "okay"; |
| 192 | pinctrl-names = "default"; | ||
| 193 | pinctrl-0 = <>; | ||
| 185 | }; | 194 | }; |
| 186 | 195 | ||
| 187 | serial@a4000000 { | 196 | serial@a4000000 { |
| 188 | status = "okay"; | 197 | status = "okay"; |
| 198 | pinctrl-names = "default"; | ||
| 199 | pinctrl-0 = <>; | ||
| 189 | }; | 200 | }; |
| 190 | 201 | ||
| 191 | wdt@fc880000 { | 202 | wdt@fc880000 { |
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts new file mode 100644 index 000000000000..3075d2d3a8be --- /dev/null +++ b/arch/arm/boot/dts/spear320-hmi.dts | |||
| @@ -0,0 +1,305 @@ | |||
| 1 | /* | ||
| 2 | * DTS file for SPEAr320 Evaluation Baord | ||
| 3 | * | ||
| 4 | * Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com> | ||
| 5 | * | ||
| 6 | * The code contained herein is licensed under the GNU General Public | ||
| 7 | * License. You may obtain a copy of the GNU General Public License | ||
| 8 | * Version 2 or later at the following locations: | ||
| 9 | * | ||
| 10 | * http://www.opensource.org/licenses/gpl-license.html | ||
| 11 | * http://www.gnu.org/copyleft/gpl.html | ||
| 12 | */ | ||
| 13 | |||
| 14 | /dts-v1/; | ||
| 15 | /include/ "spear320.dtsi" | ||
| 16 | |||
| 17 | / { | ||
| 18 | model = "ST SPEAr320 HMI Board"; | ||
| 19 | compatible = "st,spear320-hmi", "st,spear320"; | ||
| 20 | #address-cells = <1>; | ||
| 21 | #size-cells = <1>; | ||
| 22 | |||
| 23 | memory { | ||
| 24 | reg = <0 0x40000000>; | ||
| 25 | }; | ||
| 26 | |||
| 27 | ahb { | ||
| 28 | pinmux@b3000000 { | ||
| 29 | st,pinmux-mode = <4>; | ||
| 30 | pinctrl-names = "default"; | ||
| 31 | pinctrl-0 = <&state_default>; | ||
| 32 | |||
| 33 | state_default: pinmux { | ||
| 34 | i2c0 { | ||
| 35 | st,pins = "i2c0_grp"; | ||
| 36 | st,function = "i2c0"; | ||
| 37 | }; | ||
| 38 | ssp0 { | ||
| 39 | st,pins = "ssp0_grp"; | ||
| 40 | st,function = "ssp0"; | ||
| 41 | }; | ||
| 42 | uart0 { | ||
| 43 | st,pins = "uart0_grp"; | ||
| 44 | st,function = "uart0"; | ||
| 45 | }; | ||
| 46 | clcd { | ||
| 47 | st,pins = "clcd_grp"; | ||
| 48 | st,function = "clcd"; | ||
| 49 | }; | ||
| 50 | fsmc { | ||
| 51 | st,pins = "fsmc_8bit_grp"; | ||
| 52 | st,function = "fsmc"; | ||
| 53 | }; | ||
| 54 | sdhci { | ||
| 55 | st,pins = "sdhci_cd_12_grp"; | ||
| 56 | st,function = "sdhci"; | ||
| 57 | }; | ||
| 58 | i2s { | ||
| 59 | st,pins = "i2s_grp"; | ||
| 60 | st,function = "i2s"; | ||
| 61 | }; | ||
| 62 | uart1 { | ||
| 63 | st,pins = "uart1_grp"; | ||
| 64 | st,function = "uart1"; | ||
| 65 | }; | ||
| 66 | uart2 { | ||
| 67 | st,pins = "uart2_grp"; | ||
| 68 | st,function = "uart2"; | ||
| 69 | }; | ||
| 70 | can0 { | ||
| 71 | st,pins = "can0_grp"; | ||
| 72 | st,function = "can0"; | ||
| 73 | }; | ||
| 74 | can1 { | ||
| 75 | st,pins = "can1_grp"; | ||
| 76 | st,function = "can1"; | ||
| 77 | }; | ||
| 78 | mii0_1 { | ||
| 79 | st,pins = "rmii0_1_grp"; | ||
| 80 | st,function = "mii0_1"; | ||
| 81 | }; | ||
| 82 | pwm0_1 { | ||
| 83 | st,pins = "pwm0_1_pin_37_38_grp"; | ||
| 84 | st,function = "pwm0_1"; | ||
| 85 | }; | ||
| 86 | pwm2 { | ||
| 87 | st,pins = "pwm2_pin_34_grp"; | ||
| 88 | st,function = "pwm2"; | ||
| 89 | }; | ||
| 90 | }; | ||
| 91 | }; | ||
| 92 | |||
| 93 | clcd@90000000 { | ||
| 94 | status = "okay"; | ||
| 95 | }; | ||
| 96 | |||
| 97 | dma@fc400000 { | ||
| 98 | status = "okay"; | ||
| 99 | }; | ||
| 100 | |||
| 101 | ehci@e1800000 { | ||
| 102 | status = "okay"; | ||
| 103 | }; | ||
| 104 | |||
| 105 | fsmc: flash@4c000000 { | ||
| 106 | status = "okay"; | ||
| 107 | |||
| 108 | partition@0 { | ||
| 109 | label = "xloader"; | ||
| 110 | reg = <0x0 0x80000>; | ||
| 111 | }; | ||
| 112 | partition@80000 { | ||
| 113 | label = "u-boot"; | ||
| 114 | reg = <0x80000 0x140000>; | ||
| 115 | }; | ||
| 116 | partition@1C0000 { | ||
| 117 | label = "environment"; | ||
| 118 | reg = <0x1C0000 0x40000>; | ||
| 119 | }; | ||
| 120 | partition@200000 { | ||
| 121 | label = "dtb"; | ||
| 122 | reg = <0x200000 0x40000>; | ||
| 123 | }; | ||
| 124 | partition@240000 { | ||
| 125 | label = "linux"; | ||
| 126 | reg = <0x240000 0xC00000>; | ||
| 127 | }; | ||
| 128 | partition@E40000 { | ||
| 129 | label = "rootfs"; | ||
| 130 | reg = <0xE40000 0x0>; | ||
| 131 | }; | ||
| 132 | }; | ||
| 133 | |||
| 134 | gpio_keys { | ||
| 135 | compatible = "gpio-keys"; | ||
| 136 | #address-cells = <1>; | ||
| 137 | #size-cells = <0>; | ||
| 138 | |||
| 139 | button@1 { | ||
| 140 | label = "user button 1"; | ||
| 141 | linux,code = <0x100>; | ||
| 142 | gpios = <&stmpegpio 3 0x4>; | ||
| 143 | debounce-interval = <20>; | ||
| 144 | gpio-key,wakeup = <1>; | ||
| 145 | }; | ||
| 146 | |||
| 147 | button@2 { | ||
| 148 | label = "user button 2"; | ||
| 149 | linux,code = <0x200>; | ||
| 150 | gpios = <&stmpegpio 2 0x4>; | ||
| 151 | debounce-interval = <20>; | ||
| 152 | gpio-key,wakeup = <1>; | ||
| 153 | }; | ||
| 154 | }; | ||
| 155 | |||
| 156 | ohci@e1900000 { | ||
| 157 | status = "okay"; | ||
| 158 | }; | ||
| 159 | |||
| 160 | ohci@e2100000 { | ||
| 161 | status = "okay"; | ||
| 162 | }; | ||
| 163 | |||
| 164 | pwm: pwm@a8000000 { | ||
| 165 | status = "okay"; | ||
| 166 | }; | ||
| 167 | |||
| 168 | sdhci@70000000 { | ||
| 169 | power-gpio = <&gpiopinctrl 50 1>; | ||
| 170 | power_always_enb; | ||
| 171 | status = "okay"; | ||
| 172 | }; | ||
| 173 | |||
| 174 | smi: flash@fc000000 { | ||
| 175 | status = "okay"; | ||
| 176 | clock-rate=<50000000>; | ||
| 177 | |||
| 178 | flash@f8000000 { | ||
| 179 | #address-cells = <1>; | ||
| 180 | #size-cells = <1>; | ||
| 181 | reg = <0xf8000000 0x800000>; | ||
| 182 | st,smi-fast-mode; | ||
| 183 | |||
| 184 | partition@0 { | ||
| 185 | label = "xloader"; | ||
| 186 | reg = <0x0 0x10000>; | ||
| 187 | }; | ||
| 188 | partition@10000 { | ||
| 189 | label = "u-boot"; | ||
| 190 | reg = <0x10000 0x50000>; | ||
| 191 | }; | ||
| 192 | partition@60000 { | ||
| 193 | label = "environment"; | ||
| 194 | reg = <0x60000 0x10000>; | ||
| 195 | }; | ||
| 196 | partition@70000 { | ||
| 197 | label = "dtb"; | ||
| 198 | reg = <0x70000 0x10000>; | ||
| 199 | }; | ||
| 200 | partition@80000 { | ||
| 201 | label = "linux"; | ||
| 202 | reg = <0x80000 0x310000>; | ||
| 203 | }; | ||
| 204 | partition@390000 { | ||
| 205 | label = "rootfs"; | ||
| 206 | reg = <0x390000 0x0>; | ||
| 207 | }; | ||
| 208 | }; | ||
| 209 | }; | ||
| 210 | |||
| 211 | spi0: spi@d0100000 { | ||
| 212 | status = "okay"; | ||
| 213 | }; | ||
| 214 | |||
| 215 | spi1: spi@a5000000 { | ||
| 216 | status = "okay"; | ||
| 217 | }; | ||
| 218 | |||
| 219 | spi2: spi@a6000000 { | ||
| 220 | status = "okay"; | ||
| 221 | }; | ||
| 222 | |||
| 223 | usbd@e1100000 { | ||
| 224 | status = "okay"; | ||
| 225 | }; | ||
| 226 | |||
| 227 | apb { | ||
| 228 | gpio0: gpio@fc980000 { | ||
| 229 | status = "okay"; | ||
| 230 | }; | ||
| 231 | |||
| 232 | gpio@b3000000 { | ||
| 233 | status = "okay"; | ||
| 234 | }; | ||
| 235 | |||
| 236 | i2c0: i2c@d0180000 { | ||
| 237 | status = "okay"; | ||
| 238 | |||
| 239 | stmpe811@41 { | ||
| 240 | compatible = "st,stmpe811"; | ||
| 241 | #address-cells = <1>; | ||
| 242 | #size-cells = <0>; | ||
| 243 | reg = <0x41>; | ||
| 244 | irq-over-gpio; | ||
| 245 | irq-gpios = <&gpiopinctrl 29 0x4>; | ||
| 246 | id = <0>; | ||
| 247 | blocks = <0x5>; | ||
| 248 | irq-trigger = <0x1>; | ||
| 249 | |||
| 250 | stmpegpio: stmpe-gpio { | ||
| 251 | compatible = "stmpe,gpio"; | ||
| 252 | reg = <0>; | ||
| 253 | gpio-controller; | ||
| 254 | #gpio-cells = <2>; | ||
| 255 | gpio,norequest-mask = <0xF3>; | ||
| 256 | }; | ||
| 257 | |||
| 258 | stmpe610-ts { | ||
| 259 | compatible = "stmpe,ts"; | ||
| 260 | reg = <0>; | ||
| 261 | ts,sample-time = <4>; | ||
| 262 | ts,mod-12b = <1>; | ||
| 263 | ts,ref-sel = <0>; | ||
| 264 | ts,adc-freq = <1>; | ||
| 265 | ts,ave-ctrl = <1>; | ||
| 266 | ts,touch-det-delay = <3>; | ||
| 267 | ts,settling = <4>; | ||
| 268 | ts,fraction-z = <7>; | ||
| 269 | ts,i-drive = <1>; | ||
| 270 | }; | ||
| 271 | }; | ||
| 272 | }; | ||
| 273 | |||
| 274 | i2c1: i2c@a7000000 { | ||
| 275 | status = "okay"; | ||
| 276 | }; | ||
| 277 | |||
| 278 | rtc@fc900000 { | ||
| 279 | status = "okay"; | ||
| 280 | }; | ||
| 281 | |||
| 282 | serial@d0000000 { | ||
| 283 | status = "okay"; | ||
| 284 | pinctrl-names = "default"; | ||
| 285 | pinctrl-0 = <>; | ||
| 286 | }; | ||
| 287 | |||
| 288 | serial@a3000000 { | ||
| 289 | status = "okay"; | ||
| 290 | pinctrl-names = "default"; | ||
| 291 | pinctrl-0 = <>; | ||
| 292 | }; | ||
| 293 | |||
| 294 | serial@a4000000 { | ||
| 295 | status = "okay"; | ||
| 296 | pinctrl-names = "default"; | ||
| 297 | pinctrl-0 = <>; | ||
| 298 | }; | ||
| 299 | |||
| 300 | wdt@fc880000 { | ||
| 301 | status = "okay"; | ||
| 302 | }; | ||
| 303 | }; | ||
| 304 | }; | ||
| 305 | }; | ||
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index 1f49d69595a0..c056a84deabf 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi | |||
| @@ -21,15 +21,17 @@ | |||
| 21 | ranges = <0x40000000 0x40000000 0x80000000 | 21 | ranges = <0x40000000 0x40000000 0x80000000 |
| 22 | 0xd0000000 0xd0000000 0x30000000>; | 22 | 0xd0000000 0xd0000000 0x30000000>; |
| 23 | 23 | ||
| 24 | pinmux@b3000000 { | 24 | pinmux: pinmux@b3000000 { |
| 25 | compatible = "st,spear320-pinmux"; | 25 | compatible = "st,spear320-pinmux"; |
| 26 | reg = <0xb3000000 0x1000>; | 26 | reg = <0xb3000000 0x1000>; |
| 27 | #gpio-range-cells = <2>; | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | clcd@90000000 { | 30 | clcd@90000000 { |
| 30 | compatible = "arm,clcd-pl110", "arm,primecell"; | 31 | compatible = "arm,pl110", "arm,primecell"; |
| 31 | reg = <0x90000000 0x1000>; | 32 | reg = <0x90000000 0x1000>; |
| 32 | interrupts = <33>; | 33 | interrupts = <8>; |
| 34 | interrupt-parent = <&shirq>; | ||
| 33 | status = "disabled"; | 35 | status = "disabled"; |
| 34 | }; | 36 | }; |
| 35 | 37 | ||
| @@ -48,27 +50,51 @@ | |||
| 48 | sdhci@70000000 { | 50 | sdhci@70000000 { |
| 49 | compatible = "st,sdhci-spear"; | 51 | compatible = "st,sdhci-spear"; |
| 50 | reg = <0x70000000 0x100>; | 52 | reg = <0x70000000 0x100>; |
| 51 | interrupts = <29>; | 53 | interrupts = <10>; |
| 54 | interrupt-parent = <&shirq>; | ||
| 52 | status = "disabled"; | 55 | status = "disabled"; |
| 53 | }; | 56 | }; |
| 54 | 57 | ||
| 58 | shirq: interrupt-controller@0xb3000000 { | ||
| 59 | compatible = "st,spear320-shirq"; | ||
| 60 | reg = <0xb3000000 0x1000>; | ||
| 61 | interrupts = <30 28 29 1>; | ||
| 62 | #interrupt-cells = <1>; | ||
| 63 | interrupt-controller; | ||
| 64 | }; | ||
| 65 | |||
| 55 | spi1: spi@a5000000 { | 66 | spi1: spi@a5000000 { |
| 56 | compatible = "arm,pl022", "arm,primecell"; | 67 | compatible = "arm,pl022", "arm,primecell"; |
| 57 | reg = <0xa5000000 0x1000>; | 68 | reg = <0xa5000000 0x1000>; |
| 69 | interrupts = <15>; | ||
| 70 | interrupt-parent = <&shirq>; | ||
| 71 | #address-cells = <1>; | ||
| 72 | #size-cells = <0>; | ||
| 58 | status = "disabled"; | 73 | status = "disabled"; |
| 59 | }; | 74 | }; |
| 60 | 75 | ||
| 61 | spi2: spi@a6000000 { | 76 | spi2: spi@a6000000 { |
| 62 | compatible = "arm,pl022", "arm,primecell"; | 77 | compatible = "arm,pl022", "arm,primecell"; |
| 63 | reg = <0xa6000000 0x1000>; | 78 | reg = <0xa6000000 0x1000>; |
| 79 | interrupts = <16>; | ||
| 80 | interrupt-parent = <&shirq>; | ||
| 81 | #address-cells = <1>; | ||
| 82 | #size-cells = <0>; | ||
| 64 | status = "disabled"; | 83 | status = "disabled"; |
| 65 | }; | 84 | }; |
| 66 | 85 | ||
| 86 | pwm: pwm@a8000000 { | ||
| 87 | compatible ="st,spear-pwm"; | ||
| 88 | reg = <0xa8000000 0x1000>; | ||
| 89 | #pwm-cells = <2>; | ||
| 90 | status = "disabled"; | ||
| 91 | }; | ||
| 92 | |||
| 67 | apb { | 93 | apb { |
| 68 | #address-cells = <1>; | 94 | #address-cells = <1>; |
| 69 | #size-cells = <1>; | 95 | #size-cells = <1>; |
| 70 | compatible = "simple-bus"; | 96 | compatible = "simple-bus"; |
| 71 | ranges = <0xa0000000 0xa0000000 0x10000000 | 97 | ranges = <0xa0000000 0xa0000000 0x20000000 |
| 72 | 0xd0000000 0xd0000000 0x30000000>; | 98 | 0xd0000000 0xd0000000 0x30000000>; |
| 73 | 99 | ||
| 74 | i2c1: i2c@a7000000 { | 100 | i2c1: i2c@a7000000 { |
| @@ -76,20 +102,46 @@ | |||
| 76 | #size-cells = <0>; | 102 | #size-cells = <0>; |
| 77 | compatible = "snps,designware-i2c"; | 103 | compatible = "snps,designware-i2c"; |
| 78 | reg = <0xa7000000 0x1000>; | 104 | reg = <0xa7000000 0x1000>; |
| 105 | interrupts = <21>; | ||
| 106 | interrupt-parent = <&shirq>; | ||
| 79 | status = "disabled"; | 107 | status = "disabled"; |
| 80 | }; | 108 | }; |
| 81 | 109 | ||
| 82 | serial@a3000000 { | 110 | serial@a3000000 { |
| 83 | compatible = "arm,pl011", "arm,primecell"; | 111 | compatible = "arm,pl011", "arm,primecell"; |
| 84 | reg = <0xa3000000 0x1000>; | 112 | reg = <0xa3000000 0x1000>; |
| 113 | interrupts = <13>; | ||
| 114 | interrupt-parent = <&shirq>; | ||
| 85 | status = "disabled"; | 115 | status = "disabled"; |
| 86 | }; | 116 | }; |
| 87 | 117 | ||
| 88 | serial@a4000000 { | 118 | serial@a4000000 { |
| 89 | compatible = "arm,pl011", "arm,primecell"; | 119 | compatible = "arm,pl011", "arm,primecell"; |
| 90 | reg = <0xa4000000 0x1000>; | 120 | reg = <0xa4000000 0x1000>; |
| 121 | interrupts = <14>; | ||
| 122 | interrupt-parent = <&shirq>; | ||
| 91 | status = "disabled"; | 123 | status = "disabled"; |
| 92 | }; | 124 | }; |
| 125 | |||
| 126 | gpiopinctrl: gpio@b3000000 { | ||
| 127 | compatible = "st,spear-plgpio"; | ||
| 128 | reg = <0xb3000000 0x1000>; | ||
| 129 | #interrupt-cells = <1>; | ||
| 130 | interrupt-controller; | ||
| 131 | gpio-controller; | ||
| 132 | #gpio-cells = <2>; | ||
| 133 | gpio-ranges = <&pinmux 0 102>; | ||
| 134 | status = "disabled"; | ||
| 135 | |||
| 136 | st-plgpio,ngpio = <102>; | ||
| 137 | st-plgpio,enb-reg = <0x24>; | ||
| 138 | st-plgpio,wdata-reg = <0x34>; | ||
| 139 | st-plgpio,dir-reg = <0x44>; | ||
| 140 | st-plgpio,ie-reg = <0x64>; | ||
| 141 | st-plgpio,rdata-reg = <0x54>; | ||
| 142 | st-plgpio,mis-reg = <0x84>; | ||
| 143 | st-plgpio,eit-reg = <0x94>; | ||
| 144 | }; | ||
| 93 | }; | 145 | }; |
| 94 | }; | 146 | }; |
| 95 | }; | 147 | }; |
diff --git a/arch/arm/boot/dts/spear3xx.dtsi b/arch/arm/boot/dts/spear3xx.dtsi index 3a8bb5736928..c2a852d43c48 100644 --- a/arch/arm/boot/dts/spear3xx.dtsi +++ b/arch/arm/boot/dts/spear3xx.dtsi | |||
| @@ -53,6 +53,7 @@ | |||
| 53 | reg = <0xe0800000 0x8000>; | 53 | reg = <0xe0800000 0x8000>; |
| 54 | interrupts = <23 22>; | 54 | interrupts = <23 22>; |
| 55 | interrupt-names = "macirq", "eth_wake_irq"; | 55 | interrupt-names = "macirq", "eth_wake_irq"; |
| 56 | phy-mode = "mii"; | ||
| 56 | status = "disabled"; | 57 | status = "disabled"; |
| 57 | }; | 58 | }; |
| 58 | 59 | ||
| @@ -69,6 +70,8 @@ | |||
| 69 | compatible = "arm,pl022", "arm,primecell"; | 70 | compatible = "arm,pl022", "arm,primecell"; |
| 70 | reg = <0xd0100000 0x1000>; | 71 | reg = <0xd0100000 0x1000>; |
| 71 | interrupts = <20>; | 72 | interrupts = <20>; |
| 73 | #address-cells = <1>; | ||
| 74 | #size-cells = <0>; | ||
| 72 | status = "disabled"; | 75 | status = "disabled"; |
| 73 | }; | 76 | }; |
| 74 | 77 | ||
| @@ -120,7 +123,7 @@ | |||
| 120 | }; | 123 | }; |
| 121 | 124 | ||
| 122 | rtc@fc900000 { | 125 | rtc@fc900000 { |
| 123 | compatible = "st,spear-rtc"; | 126 | compatible = "st,spear600-rtc"; |
| 124 | reg = <0xfc900000 0x1000>; | 127 | reg = <0xfc900000 0x1000>; |
| 125 | interrupts = <10>; | 128 | interrupts = <10>; |
| 126 | status = "disabled"; | 129 | status = "disabled"; |
diff --git a/arch/arm/boot/dts/spear600-evb.dts b/arch/arm/boot/dts/spear600-evb.dts index 1119c22c9a82..d865a891776d 100644 --- a/arch/arm/boot/dts/spear600-evb.dts +++ b/arch/arm/boot/dts/spear600-evb.dts | |||
| @@ -24,15 +24,35 @@ | |||
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | ahb { | 26 | ahb { |
| 27 | clcd@fc200000 { | ||
| 28 | status = "okay"; | ||
| 29 | }; | ||
| 30 | |||
| 27 | dma@fc400000 { | 31 | dma@fc400000 { |
| 28 | status = "okay"; | 32 | status = "okay"; |
| 29 | }; | 33 | }; |
| 30 | 34 | ||
| 35 | ehci@e1800000 { | ||
| 36 | status = "okay"; | ||
| 37 | }; | ||
| 38 | |||
| 39 | ehci@e2000000 { | ||
| 40 | status = "okay"; | ||
| 41 | }; | ||
| 42 | |||
| 31 | gmac: ethernet@e0800000 { | 43 | gmac: ethernet@e0800000 { |
| 32 | phy-mode = "gmii"; | 44 | phy-mode = "gmii"; |
| 33 | status = "okay"; | 45 | status = "okay"; |
| 34 | }; | 46 | }; |
| 35 | 47 | ||
| 48 | ohci@e1900000 { | ||
| 49 | status = "okay"; | ||
| 50 | }; | ||
| 51 | |||
| 52 | ohci@e2100000 { | ||
| 53 | status = "okay"; | ||
| 54 | }; | ||
| 55 | |||
| 36 | smi: flash@fc000000 { | 56 | smi: flash@fc000000 { |
| 37 | status = "okay"; | 57 | status = "okay"; |
| 38 | clock-rate=<50000000>; | 58 | clock-rate=<50000000>; |
| @@ -49,15 +69,23 @@ | |||
| 49 | }; | 69 | }; |
| 50 | partition@10000 { | 70 | partition@10000 { |
| 51 | label = "u-boot"; | 71 | label = "u-boot"; |
| 52 | reg = <0x10000 0x40000>; | 72 | reg = <0x10000 0x50000>; |
| 53 | }; | 73 | }; |
| 54 | partition@50000 { | 74 | partition@60000 { |
| 75 | label = "environment"; | ||
| 76 | reg = <0x60000 0x10000>; | ||
| 77 | }; | ||
| 78 | partition@70000 { | ||
| 79 | label = "dtb"; | ||
| 80 | reg = <0x70000 0x10000>; | ||
| 81 | }; | ||
| 82 | partition@80000 { | ||
| 55 | label = "linux"; | 83 | label = "linux"; |
| 56 | reg = <0x50000 0x2c0000>; | 84 | reg = <0x80000 0x310000>; |
| 57 | }; | 85 | }; |
| 58 | partition@310000 { | 86 | partition@390000 { |
| 59 | label = "rootfs"; | 87 | label = "rootfs"; |
| 60 | reg = <0x310000 0x4f0000>; | 88 | reg = <0x390000 0x0>; |
| 61 | }; | 89 | }; |
| 62 | }; | 90 | }; |
| 63 | }; | 91 | }; |
| @@ -65,10 +93,18 @@ | |||
| 65 | apb { | 93 | apb { |
| 66 | serial@d0000000 { | 94 | serial@d0000000 { |
| 67 | status = "okay"; | 95 | status = "okay"; |
| 96 | pinctrl-names = "default"; | ||
| 97 | pinctrl-0 = <>; | ||
| 68 | }; | 98 | }; |
| 69 | 99 | ||
| 70 | serial@d0080000 { | 100 | serial@d0080000 { |
| 71 | status = "okay"; | 101 | status = "okay"; |
| 102 | pinctrl-names = "default"; | ||
| 103 | pinctrl-0 = <>; | ||
| 104 | }; | ||
| 105 | |||
| 106 | rtc@fc900000 { | ||
| 107 | status = "okay"; | ||
| 72 | }; | 108 | }; |
| 73 | 109 | ||
| 74 | i2c@d0200000 { | 110 | i2c@d0200000 { |
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi index a3c36e47d7ef..e051dde5181f 100644 --- a/arch/arm/boot/dts/spear600.dtsi +++ b/arch/arm/boot/dts/spear600.dtsi | |||
| @@ -45,6 +45,14 @@ | |||
| 45 | #interrupt-cells = <1>; | 45 | #interrupt-cells = <1>; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | clcd@fc200000 { | ||
| 49 | compatible = "arm,pl110", "arm,primecell"; | ||
| 50 | reg = <0xfc200000 0x1000>; | ||
| 51 | interrupt-parent = <&vic1>; | ||
| 52 | interrupts = <12>; | ||
| 53 | status = "disabled"; | ||
| 54 | }; | ||
| 55 | |||
| 48 | dma@fc400000 { | 56 | dma@fc400000 { |
| 49 | compatible = "arm,pl080", "arm,primecell"; | 57 | compatible = "arm,pl080", "arm,primecell"; |
| 50 | reg = <0xfc400000 0x1000>; | 58 | reg = <0xfc400000 0x1000>; |
| @@ -59,6 +67,7 @@ | |||
| 59 | interrupt-parent = <&vic1>; | 67 | interrupt-parent = <&vic1>; |
| 60 | interrupts = <24 23>; | 68 | interrupts = <24 23>; |
| 61 | interrupt-names = "macirq", "eth_wake_irq"; | 69 | interrupt-names = "macirq", "eth_wake_irq"; |
| 70 | phy-mode = "gmii"; | ||
| 62 | status = "disabled"; | 71 | status = "disabled"; |
| 63 | }; | 72 | }; |
| 64 | 73 | ||
| @@ -178,6 +187,13 @@ | |||
| 178 | status = "disabled"; | 187 | status = "disabled"; |
| 179 | }; | 188 | }; |
| 180 | 189 | ||
| 190 | rtc@fc900000 { | ||
| 191 | compatible = "st,spear600-rtc"; | ||
| 192 | reg = <0xfc900000 0x1000>; | ||
| 193 | interrupts = <10>; | ||
| 194 | status = "disabled"; | ||
| 195 | }; | ||
| 196 | |||
| 181 | timer@f0000000 { | 197 | timer@f0000000 { |
| 182 | compatible = "st,spear-timer"; | 198 | compatible = "st,spear-timer"; |
| 183 | reg = <0xf0000000 0x400>; | 199 | reg = <0xf0000000 0x400>; |
diff --git a/arch/arm/mach-spear13xx/include/mach/spear.h b/arch/arm/mach-spear13xx/include/mach/spear.h index 07d90acc92c8..7cfa6818865a 100644 --- a/arch/arm/mach-spear13xx/include/mach/spear.h +++ b/arch/arm/mach-spear13xx/include/mach/spear.h | |||
| @@ -47,14 +47,6 @@ | |||
| 47 | #define DMAC1_BASE UL(0xEB000000) | 47 | #define DMAC1_BASE UL(0xEB000000) |
| 48 | #define MCIF_CF_BASE UL(0xB2800000) | 48 | #define MCIF_CF_BASE UL(0xB2800000) |
| 49 | 49 | ||
| 50 | /* Devices present in SPEAr1310 */ | ||
| 51 | #ifdef CONFIG_MACH_SPEAR1310 | ||
| 52 | #define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) | ||
| 53 | #define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) | ||
| 54 | #define SPEAR1310_RAS_BASE UL(0xD8400000) | ||
| 55 | #define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) | ||
| 56 | #endif /* CONFIG_MACH_SPEAR1310 */ | ||
| 57 | |||
| 58 | /* Debug uart for linux, will be used for debug and uncompress messages */ | 50 | /* Debug uart for linux, will be used for debug and uncompress messages */ |
| 59 | #define SPEAR_DBG_UART_BASE UART_BASE | 51 | #define SPEAR_DBG_UART_BASE UART_BASE |
| 60 | #define VA_SPEAR_DBG_UART_BASE VA_UART_BASE | 52 | #define VA_SPEAR_DBG_UART_BASE VA_UART_BASE |
diff --git a/arch/arm/mach-spear13xx/spear1310.c b/arch/arm/mach-spear13xx/spear1310.c index 9fbbfc5650aa..02f4724bb0d4 100644 --- a/arch/arm/mach-spear13xx/spear1310.c +++ b/arch/arm/mach-spear13xx/spear1310.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/amba/pl022.h> | 16 | #include <linux/amba/pl022.h> |
| 17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
| 18 | #include <linux/pata_arasan_cf_data.h> | ||
| 18 | #include <asm/hardware/gic.h> | 19 | #include <asm/hardware/gic.h> |
| 19 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
| 20 | #include <asm/mach/map.h> | 21 | #include <asm/mach/map.h> |
| @@ -27,16 +28,25 @@ | |||
| 27 | #define SPEAR1310_SATA1_BASE UL(0xB1800000) | 28 | #define SPEAR1310_SATA1_BASE UL(0xB1800000) |
| 28 | #define SPEAR1310_SATA2_BASE UL(0xB4000000) | 29 | #define SPEAR1310_SATA2_BASE UL(0xB4000000) |
| 29 | 30 | ||
| 31 | #define SPEAR1310_RAS_GRP1_BASE UL(0xD8000000) | ||
| 32 | #define VA_SPEAR1310_RAS_GRP1_BASE UL(0xFA000000) | ||
| 33 | #define SPEAR1310_RAS_BASE UL(0xD8400000) | ||
| 34 | #define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) | ||
| 35 | |||
| 36 | static struct arasan_cf_pdata cf_pdata = { | ||
| 37 | .cf_if_clk = CF_IF_CLK_166M, | ||
| 38 | .quirk = CF_BROKEN_UDMA, | ||
| 39 | .dma_priv = &cf_dma_priv, | ||
| 40 | }; | ||
| 41 | |||
| 30 | /* ssp device registration */ | 42 | /* ssp device registration */ |
| 31 | static struct pl022_ssp_controller ssp1_plat_data = { | 43 | static struct pl022_ssp_controller ssp1_plat_data = { |
| 32 | .bus_id = 0, | ||
| 33 | .enable_dma = 0, | 44 | .enable_dma = 0, |
| 34 | .num_chipselect = 3, | ||
| 35 | }; | 45 | }; |
| 36 | 46 | ||
| 37 | /* Add SPEAr1310 auxdata to pass platform data */ | 47 | /* Add SPEAr1310 auxdata to pass platform data */ |
| 38 | static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = { | 48 | static struct of_dev_auxdata spear1310_auxdata_lookup[] __initdata = { |
| 39 | OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_dma_priv), | 49 | OF_DEV_AUXDATA("arasan,cf-spear1340", MCIF_CF_BASE, NULL, &cf_pdata), |
| 40 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), | 50 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC0_BASE, NULL, &dmac_plat_data), |
| 41 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), | 51 | OF_DEV_AUXDATA("snps,dma-spear1340", DMAC1_BASE, NULL, &dmac_plat_data), |
| 42 | OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), | 52 | OF_DEV_AUXDATA("arm,pl022", SSP_BASE, NULL, &pl022_plat_data), |
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index 5633d698f1e1..c4af775a8451 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c | |||
| @@ -57,12 +57,10 @@ static struct dw_dma_slave ssp_dma_param[] = { | |||
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | struct pl022_ssp_controller pl022_plat_data = { | 59 | struct pl022_ssp_controller pl022_plat_data = { |
| 60 | .bus_id = 0, | ||
| 61 | .enable_dma = 1, | 60 | .enable_dma = 1, |
| 62 | .dma_filter = dw_dma_filter, | 61 | .dma_filter = dw_dma_filter, |
| 63 | .dma_rx_param = &ssp_dma_param[1], | 62 | .dma_rx_param = &ssp_dma_param[1], |
| 64 | .dma_tx_param = &ssp_dma_param[0], | 63 | .dma_tx_param = &ssp_dma_param[0], |
| 65 | .num_chipselect = 3, | ||
| 66 | }; | 64 | }; |
| 67 | 65 | ||
| 68 | /* CF device registration */ | 66 | /* CF device registration */ |
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index 803de76f5f36..f95e5b2b6686 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h | |||
| @@ -14,14 +14,6 @@ | |||
| 14 | #ifndef __MACH_IRQS_H | 14 | #ifndef __MACH_IRQS_H |
| 15 | #define __MACH_IRQS_H | 15 | #define __MACH_IRQS_H |
| 16 | 16 | ||
| 17 | /* FIXME: probe all these from DT */ | 17 | #define NR_IRQS 256 |
| 18 | #define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM 1 | ||
| 19 | #define SPEAR3XX_IRQ_GEN_RAS_1 28 | ||
| 20 | #define SPEAR3XX_IRQ_GEN_RAS_2 29 | ||
| 21 | #define SPEAR3XX_IRQ_GEN_RAS_3 30 | ||
| 22 | #define SPEAR3XX_IRQ_VIC_END 32 | ||
| 23 | #define SPEAR3XX_VIRQ_START SPEAR3XX_IRQ_VIC_END | ||
| 24 | |||
| 25 | #define NR_IRQS 160 | ||
| 26 | 18 | ||
| 27 | #endif /* __MACH_IRQS_H */ | 19 | #endif /* __MACH_IRQS_H */ |
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 6ec300549960..a69cbfdb07ee 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c | |||
| @@ -17,102 +17,9 @@ | |||
| 17 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
| 18 | #include <asm/hardware/vic.h> | 18 | #include <asm/hardware/vic.h> |
| 19 | #include <asm/mach/arch.h> | 19 | #include <asm/mach/arch.h> |
| 20 | #include <plat/shirq.h> | ||
| 21 | #include <mach/generic.h> | 20 | #include <mach/generic.h> |
| 22 | #include <mach/spear.h> | 21 | #include <mach/spear.h> |
| 23 | 22 | ||
| 24 | /* Base address of various IPs */ | ||
| 25 | #define SPEAR300_TELECOM_BASE UL(0x50000000) | ||
| 26 | |||
| 27 | /* Interrupt registers offsets and masks */ | ||
| 28 | #define SPEAR300_INT_ENB_MASK_REG 0x54 | ||
| 29 | #define SPEAR300_INT_STS_MASK_REG 0x58 | ||
| 30 | #define SPEAR300_IT_PERS_S_IRQ_MASK (1 << 0) | ||
| 31 | #define SPEAR300_IT_CHANGE_S_IRQ_MASK (1 << 1) | ||
| 32 | #define SPEAR300_I2S_IRQ_MASK (1 << 2) | ||
| 33 | #define SPEAR300_TDM_IRQ_MASK (1 << 3) | ||
| 34 | #define SPEAR300_CAMERA_L_IRQ_MASK (1 << 4) | ||
| 35 | #define SPEAR300_CAMERA_F_IRQ_MASK (1 << 5) | ||
| 36 | #define SPEAR300_CAMERA_V_IRQ_MASK (1 << 6) | ||
| 37 | #define SPEAR300_KEYBOARD_IRQ_MASK (1 << 7) | ||
| 38 | #define SPEAR300_GPIO1_IRQ_MASK (1 << 8) | ||
| 39 | |||
| 40 | #define SPEAR300_SHIRQ_RAS1_MASK 0x1FF | ||
| 41 | |||
| 42 | #define SPEAR300_SOC_CONFIG_BASE UL(0x99000000) | ||
| 43 | |||
| 44 | |||
| 45 | /* SPEAr300 Virtual irq definitions */ | ||
| 46 | /* IRQs sharing IRQ_GEN_RAS_1 */ | ||
| 47 | #define SPEAR300_VIRQ_IT_PERS_S (SPEAR3XX_VIRQ_START + 0) | ||
| 48 | #define SPEAR300_VIRQ_IT_CHANGE_S (SPEAR3XX_VIRQ_START + 1) | ||
| 49 | #define SPEAR300_VIRQ_I2S (SPEAR3XX_VIRQ_START + 2) | ||
| 50 | #define SPEAR300_VIRQ_TDM (SPEAR3XX_VIRQ_START + 3) | ||
| 51 | #define SPEAR300_VIRQ_CAMERA_L (SPEAR3XX_VIRQ_START + 4) | ||
| 52 | #define SPEAR300_VIRQ_CAMERA_F (SPEAR3XX_VIRQ_START + 5) | ||
| 53 | #define SPEAR300_VIRQ_CAMERA_V (SPEAR3XX_VIRQ_START + 6) | ||
| 54 | #define SPEAR300_VIRQ_KEYBOARD (SPEAR3XX_VIRQ_START + 7) | ||
| 55 | #define SPEAR300_VIRQ_GPIO1 (SPEAR3XX_VIRQ_START + 8) | ||
| 56 | |||
| 57 | /* IRQs sharing IRQ_GEN_RAS_3 */ | ||
| 58 | #define SPEAR300_IRQ_CLCD SPEAR3XX_IRQ_GEN_RAS_3 | ||
| 59 | |||
| 60 | /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ | ||
| 61 | #define SPEAR300_IRQ_SDHCI SPEAR3XX_IRQ_INTRCOMM_RAS_ARM | ||
| 62 | |||
| 63 | /* spear3xx shared irq */ | ||
| 64 | static struct shirq_dev_config shirq_ras1_config[] = { | ||
| 65 | { | ||
| 66 | .virq = SPEAR300_VIRQ_IT_PERS_S, | ||
| 67 | .enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK, | ||
| 68 | .status_mask = SPEAR300_IT_PERS_S_IRQ_MASK, | ||
| 69 | }, { | ||
| 70 | .virq = SPEAR300_VIRQ_IT_CHANGE_S, | ||
| 71 | .enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK, | ||
| 72 | .status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK, | ||
| 73 | }, { | ||
| 74 | .virq = SPEAR300_VIRQ_I2S, | ||
| 75 | .enb_mask = SPEAR300_I2S_IRQ_MASK, | ||
| 76 | .status_mask = SPEAR300_I2S_IRQ_MASK, | ||
| 77 | }, { | ||
| 78 | .virq = SPEAR300_VIRQ_TDM, | ||
| 79 | .enb_mask = SPEAR300_TDM_IRQ_MASK, | ||
| 80 | .status_mask = SPEAR300_TDM_IRQ_MASK, | ||
| 81 | }, { | ||
| 82 | .virq = SPEAR300_VIRQ_CAMERA_L, | ||
| 83 | .enb_mask = SPEAR300_CAMERA_L_IRQ_MASK, | ||
| 84 | .status_mask = SPEAR300_CAMERA_L_IRQ_MASK, | ||
| 85 | }, { | ||
| 86 | .virq = SPEAR300_VIRQ_CAMERA_F, | ||
| 87 | .enb_mask = SPEAR300_CAMERA_F_IRQ_MASK, | ||
| 88 | .status_mask = SPEAR300_CAMERA_F_IRQ_MASK, | ||
| 89 | }, { | ||
| 90 | .virq = SPEAR300_VIRQ_CAMERA_V, | ||
| 91 | .enb_mask = SPEAR300_CAMERA_V_IRQ_MASK, | ||
| 92 | .status_mask = SPEAR300_CAMERA_V_IRQ_MASK, | ||
| 93 | }, { | ||
| 94 | .virq = SPEAR300_VIRQ_KEYBOARD, | ||
| 95 | .enb_mask = SPEAR300_KEYBOARD_IRQ_MASK, | ||
| 96 | .status_mask = SPEAR300_KEYBOARD_IRQ_MASK, | ||
| 97 | }, { | ||
| 98 | .virq = SPEAR300_VIRQ_GPIO1, | ||
| 99 | .enb_mask = SPEAR300_GPIO1_IRQ_MASK, | ||
| 100 | .status_mask = SPEAR300_GPIO1_IRQ_MASK, | ||
| 101 | }, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct spear_shirq shirq_ras1 = { | ||
| 105 | .irq = SPEAR3XX_IRQ_GEN_RAS_1, | ||
| 106 | .dev_config = shirq_ras1_config, | ||
| 107 | .dev_count = ARRAY_SIZE(shirq_ras1_config), | ||
| 108 | .regs = { | ||
| 109 | .enb_reg = SPEAR300_INT_ENB_MASK_REG, | ||
| 110 | .status_reg = SPEAR300_INT_STS_MASK_REG, | ||
| 111 | .status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK, | ||
| 112 | .clear_reg = -1, | ||
| 113 | }, | ||
| 114 | }; | ||
| 115 | |||
| 116 | /* DMAC platform data's slave info */ | 23 | /* DMAC platform data's slave info */ |
| 117 | struct pl08x_channel_data spear300_dma_info[] = { | 24 | struct pl08x_channel_data spear300_dma_info[] = { |
| 118 | { | 25 | { |
| @@ -285,21 +192,11 @@ static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = { | |||
| 285 | 192 | ||
| 286 | static void __init spear300_dt_init(void) | 193 | static void __init spear300_dt_init(void) |
| 287 | { | 194 | { |
| 288 | int ret; | ||
| 289 | |||
| 290 | pl080_plat_data.slave_channels = spear300_dma_info; | 195 | pl080_plat_data.slave_channels = spear300_dma_info; |
| 291 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info); | 196 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info); |
| 292 | 197 | ||
| 293 | of_platform_populate(NULL, of_default_bus_match_table, | 198 | of_platform_populate(NULL, of_default_bus_match_table, |
| 294 | spear300_auxdata_lookup, NULL); | 199 | spear300_auxdata_lookup, NULL); |
| 295 | |||
| 296 | /* shared irq registration */ | ||
| 297 | shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K); | ||
| 298 | if (shirq_ras1.regs.base) { | ||
| 299 | ret = spear_shirq_register(&shirq_ras1); | ||
| 300 | if (ret) | ||
| 301 | pr_err("Error registering Shared IRQ\n"); | ||
| 302 | } | ||
| 303 | } | 200 | } |
| 304 | 201 | ||
| 305 | static const char * const spear300_dt_board_compat[] = { | 202 | static const char * const spear300_dt_board_compat[] = { |
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 1d0e435b9045..b963ebb10b56 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
| 19 | #include <asm/hardware/vic.h> | 19 | #include <asm/hardware/vic.h> |
| 20 | #include <asm/mach/arch.h> | 20 | #include <asm/mach/arch.h> |
| 21 | #include <plat/shirq.h> | ||
| 22 | #include <mach/generic.h> | 21 | #include <mach/generic.h> |
| 23 | #include <mach/spear.h> | 22 | #include <mach/spear.h> |
| 24 | 23 | ||
| @@ -27,176 +26,6 @@ | |||
| 27 | #define SPEAR310_UART3_BASE UL(0xB2100000) | 26 | #define SPEAR310_UART3_BASE UL(0xB2100000) |
| 28 | #define SPEAR310_UART4_BASE UL(0xB2180000) | 27 | #define SPEAR310_UART4_BASE UL(0xB2180000) |
| 29 | #define SPEAR310_UART5_BASE UL(0xB2200000) | 28 | #define SPEAR310_UART5_BASE UL(0xB2200000) |
| 30 | #define SPEAR310_SOC_CONFIG_BASE UL(0xB4000000) | ||
| 31 | |||
| 32 | /* Interrupt registers offsets and masks */ | ||
| 33 | #define SPEAR310_INT_STS_MASK_REG 0x04 | ||
| 34 | #define SPEAR310_SMII0_IRQ_MASK (1 << 0) | ||
| 35 | #define SPEAR310_SMII1_IRQ_MASK (1 << 1) | ||
| 36 | #define SPEAR310_SMII2_IRQ_MASK (1 << 2) | ||
| 37 | #define SPEAR310_SMII3_IRQ_MASK (1 << 3) | ||
| 38 | #define SPEAR310_WAKEUP_SMII0_IRQ_MASK (1 << 4) | ||
| 39 | #define SPEAR310_WAKEUP_SMII1_IRQ_MASK (1 << 5) | ||
| 40 | #define SPEAR310_WAKEUP_SMII2_IRQ_MASK (1 << 6) | ||
| 41 | #define SPEAR310_WAKEUP_SMII3_IRQ_MASK (1 << 7) | ||
| 42 | #define SPEAR310_UART1_IRQ_MASK (1 << 8) | ||
| 43 | #define SPEAR310_UART2_IRQ_MASK (1 << 9) | ||
| 44 | #define SPEAR310_UART3_IRQ_MASK (1 << 10) | ||
| 45 | #define SPEAR310_UART4_IRQ_MASK (1 << 11) | ||
| 46 | #define SPEAR310_UART5_IRQ_MASK (1 << 12) | ||
| 47 | #define SPEAR310_EMI_IRQ_MASK (1 << 13) | ||
| 48 | #define SPEAR310_TDM_HDLC_IRQ_MASK (1 << 14) | ||
| 49 | #define SPEAR310_RS485_0_IRQ_MASK (1 << 15) | ||
| 50 | #define SPEAR310_RS485_1_IRQ_MASK (1 << 16) | ||
| 51 | |||
| 52 | #define SPEAR310_SHIRQ_RAS1_MASK 0x000FF | ||
| 53 | #define SPEAR310_SHIRQ_RAS2_MASK 0x01F00 | ||
| 54 | #define SPEAR310_SHIRQ_RAS3_MASK 0x02000 | ||
| 55 | #define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK 0x1C000 | ||
| 56 | |||
| 57 | /* SPEAr310 Virtual irq definitions */ | ||
| 58 | /* IRQs sharing IRQ_GEN_RAS_1 */ | ||
| 59 | #define SPEAR310_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 0) | ||
| 60 | #define SPEAR310_VIRQ_SMII1 (SPEAR3XX_VIRQ_START + 1) | ||
| 61 | #define SPEAR310_VIRQ_SMII2 (SPEAR3XX_VIRQ_START + 2) | ||
| 62 | #define SPEAR310_VIRQ_SMII3 (SPEAR3XX_VIRQ_START + 3) | ||
| 63 | #define SPEAR310_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 4) | ||
| 64 | #define SPEAR310_VIRQ_WAKEUP_SMII1 (SPEAR3XX_VIRQ_START + 5) | ||
| 65 | #define SPEAR310_VIRQ_WAKEUP_SMII2 (SPEAR3XX_VIRQ_START + 6) | ||
| 66 | #define SPEAR310_VIRQ_WAKEUP_SMII3 (SPEAR3XX_VIRQ_START + 7) | ||
| 67 | |||
| 68 | /* IRQs sharing IRQ_GEN_RAS_2 */ | ||
| 69 | #define SPEAR310_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8) | ||
| 70 | #define SPEAR310_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9) | ||
| 71 | #define SPEAR310_VIRQ_UART3 (SPEAR3XX_VIRQ_START + 10) | ||
| 72 | #define SPEAR310_VIRQ_UART4 (SPEAR3XX_VIRQ_START + 11) | ||
| 73 | #define SPEAR310_VIRQ_UART5 (SPEAR3XX_VIRQ_START + 12) | ||
| 74 | |||
| 75 | /* IRQs sharing IRQ_GEN_RAS_3 */ | ||
| 76 | #define SPEAR310_VIRQ_EMI (SPEAR3XX_VIRQ_START + 13) | ||
| 77 | #define SPEAR310_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 14) | ||
| 78 | |||
| 79 | /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ | ||
| 80 | #define SPEAR310_VIRQ_TDM_HDLC (SPEAR3XX_VIRQ_START + 15) | ||
| 81 | #define SPEAR310_VIRQ_RS485_0 (SPEAR3XX_VIRQ_START + 16) | ||
| 82 | #define SPEAR310_VIRQ_RS485_1 (SPEAR3XX_VIRQ_START + 17) | ||
| 83 | |||
| 84 | |||
| 85 | /* spear3xx shared irq */ | ||
| 86 | static struct shirq_dev_config shirq_ras1_config[] = { | ||
| 87 | { | ||
| 88 | .virq = SPEAR310_VIRQ_SMII0, | ||
| 89 | .status_mask = SPEAR310_SMII0_IRQ_MASK, | ||
| 90 | }, { | ||
| 91 | .virq = SPEAR310_VIRQ_SMII1, | ||
| 92 | .status_mask = SPEAR310_SMII1_IRQ_MASK, | ||
| 93 | }, { | ||
| 94 | .virq = SPEAR310_VIRQ_SMII2, | ||
| 95 | .status_mask = SPEAR310_SMII2_IRQ_MASK, | ||
| 96 | }, { | ||
| 97 | .virq = SPEAR310_VIRQ_SMII3, | ||
| 98 | .status_mask = SPEAR310_SMII3_IRQ_MASK, | ||
| 99 | }, { | ||
| 100 | .virq = SPEAR310_VIRQ_WAKEUP_SMII0, | ||
| 101 | .status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK, | ||
| 102 | }, { | ||
| 103 | .virq = SPEAR310_VIRQ_WAKEUP_SMII1, | ||
| 104 | .status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK, | ||
| 105 | }, { | ||
| 106 | .virq = SPEAR310_VIRQ_WAKEUP_SMII2, | ||
| 107 | .status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK, | ||
| 108 | }, { | ||
| 109 | .virq = SPEAR310_VIRQ_WAKEUP_SMII3, | ||
| 110 | .status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK, | ||
| 111 | }, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct spear_shirq shirq_ras1 = { | ||
| 115 | .irq = SPEAR3XX_IRQ_GEN_RAS_1, | ||
| 116 | .dev_config = shirq_ras1_config, | ||
| 117 | .dev_count = ARRAY_SIZE(shirq_ras1_config), | ||
| 118 | .regs = { | ||
| 119 | .enb_reg = -1, | ||
| 120 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 121 | .status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK, | ||
| 122 | .clear_reg = -1, | ||
| 123 | }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | static struct shirq_dev_config shirq_ras2_config[] = { | ||
| 127 | { | ||
| 128 | .virq = SPEAR310_VIRQ_UART1, | ||
| 129 | .status_mask = SPEAR310_UART1_IRQ_MASK, | ||
| 130 | }, { | ||
| 131 | .virq = SPEAR310_VIRQ_UART2, | ||
| 132 | .status_mask = SPEAR310_UART2_IRQ_MASK, | ||
| 133 | }, { | ||
| 134 | .virq = SPEAR310_VIRQ_UART3, | ||
| 135 | .status_mask = SPEAR310_UART3_IRQ_MASK, | ||
| 136 | }, { | ||
| 137 | .virq = SPEAR310_VIRQ_UART4, | ||
| 138 | .status_mask = SPEAR310_UART4_IRQ_MASK, | ||
| 139 | }, { | ||
| 140 | .virq = SPEAR310_VIRQ_UART5, | ||
| 141 | .status_mask = SPEAR310_UART5_IRQ_MASK, | ||
| 142 | }, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static struct spear_shirq shirq_ras2 = { | ||
| 146 | .irq = SPEAR3XX_IRQ_GEN_RAS_2, | ||
| 147 | .dev_config = shirq_ras2_config, | ||
| 148 | .dev_count = ARRAY_SIZE(shirq_ras2_config), | ||
| 149 | .regs = { | ||
| 150 | .enb_reg = -1, | ||
| 151 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 152 | .status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK, | ||
| 153 | .clear_reg = -1, | ||
| 154 | }, | ||
| 155 | }; | ||
| 156 | |||
| 157 | static struct shirq_dev_config shirq_ras3_config[] = { | ||
| 158 | { | ||
| 159 | .virq = SPEAR310_VIRQ_EMI, | ||
| 160 | .status_mask = SPEAR310_EMI_IRQ_MASK, | ||
| 161 | }, | ||
| 162 | }; | ||
| 163 | |||
| 164 | static struct spear_shirq shirq_ras3 = { | ||
| 165 | .irq = SPEAR3XX_IRQ_GEN_RAS_3, | ||
| 166 | .dev_config = shirq_ras3_config, | ||
| 167 | .dev_count = ARRAY_SIZE(shirq_ras3_config), | ||
| 168 | .regs = { | ||
| 169 | .enb_reg = -1, | ||
| 170 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 171 | .status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK, | ||
| 172 | .clear_reg = -1, | ||
| 173 | }, | ||
| 174 | }; | ||
| 175 | |||
| 176 | static struct shirq_dev_config shirq_intrcomm_ras_config[] = { | ||
| 177 | { | ||
| 178 | .virq = SPEAR310_VIRQ_TDM_HDLC, | ||
| 179 | .status_mask = SPEAR310_TDM_HDLC_IRQ_MASK, | ||
| 180 | }, { | ||
| 181 | .virq = SPEAR310_VIRQ_RS485_0, | ||
| 182 | .status_mask = SPEAR310_RS485_0_IRQ_MASK, | ||
| 183 | }, { | ||
| 184 | .virq = SPEAR310_VIRQ_RS485_1, | ||
| 185 | .status_mask = SPEAR310_RS485_1_IRQ_MASK, | ||
| 186 | }, | ||
| 187 | }; | ||
| 188 | |||
| 189 | static struct spear_shirq shirq_intrcomm_ras = { | ||
| 190 | .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM, | ||
| 191 | .dev_config = shirq_intrcomm_ras_config, | ||
| 192 | .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), | ||
| 193 | .regs = { | ||
| 194 | .enb_reg = -1, | ||
| 195 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 196 | .status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK, | ||
| 197 | .clear_reg = -1, | ||
| 198 | }, | ||
| 199 | }; | ||
| 200 | 29 | ||
| 201 | /* DMAC platform data's slave info */ | 30 | /* DMAC platform data's slave info */ |
| 202 | struct pl08x_channel_data spear310_dma_info[] = { | 31 | struct pl08x_channel_data spear310_dma_info[] = { |
| @@ -405,42 +234,11 @@ static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = { | |||
| 405 | 234 | ||
| 406 | static void __init spear310_dt_init(void) | 235 | static void __init spear310_dt_init(void) |
| 407 | { | 236 | { |
| 408 | void __iomem *base; | ||
| 409 | int ret; | ||
| 410 | |||
| 411 | pl080_plat_data.slave_channels = spear310_dma_info; | 237 | pl080_plat_data.slave_channels = spear310_dma_info; |
| 412 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info); | 238 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info); |
| 413 | 239 | ||
| 414 | of_platform_populate(NULL, of_default_bus_match_table, | 240 | of_platform_populate(NULL, of_default_bus_match_table, |
| 415 | spear310_auxdata_lookup, NULL); | 241 | spear310_auxdata_lookup, NULL); |
| 416 | |||
| 417 | /* shared irq registration */ | ||
| 418 | base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K); | ||
| 419 | if (base) { | ||
| 420 | /* shirq 1 */ | ||
| 421 | shirq_ras1.regs.base = base; | ||
| 422 | ret = spear_shirq_register(&shirq_ras1); | ||
| 423 | if (ret) | ||
| 424 | pr_err("Error registering Shared IRQ 1\n"); | ||
| 425 | |||
| 426 | /* shirq 2 */ | ||
| 427 | shirq_ras2.regs.base = base; | ||
| 428 | ret = spear_shirq_register(&shirq_ras2); | ||
| 429 | if (ret) | ||
| 430 | pr_err("Error registering Shared IRQ 2\n"); | ||
| 431 | |||
| 432 | /* shirq 3 */ | ||
| 433 | shirq_ras3.regs.base = base; | ||
| 434 | ret = spear_shirq_register(&shirq_ras3); | ||
| 435 | if (ret) | ||
| 436 | pr_err("Error registering Shared IRQ 3\n"); | ||
| 437 | |||
| 438 | /* shirq 4 */ | ||
| 439 | shirq_intrcomm_ras.regs.base = base; | ||
| 440 | ret = spear_shirq_register(&shirq_intrcomm_ras); | ||
| 441 | if (ret) | ||
| 442 | pr_err("Error registering Shared IRQ 4\n"); | ||
| 443 | } | ||
| 444 | } | 242 | } |
| 445 | 243 | ||
| 446 | static const char * const spear310_dt_board_compat[] = { | 244 | static const char * const spear310_dt_board_compat[] = { |
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index fd823c624575..66e3a0c33e75 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
| 20 | #include <asm/hardware/vic.h> | 20 | #include <asm/hardware/vic.h> |
| 21 | #include <asm/mach/arch.h> | 21 | #include <asm/mach/arch.h> |
| 22 | #include <plat/shirq.h> | ||
| 23 | #include <mach/generic.h> | 22 | #include <mach/generic.h> |
| 24 | #include <mach/spear.h> | 23 | #include <mach/spear.h> |
| 25 | 24 | ||
| @@ -28,184 +27,6 @@ | |||
| 28 | #define SPEAR320_SSP0_BASE UL(0xA5000000) | 27 | #define SPEAR320_SSP0_BASE UL(0xA5000000) |
| 29 | #define SPEAR320_SSP1_BASE UL(0xA6000000) | 28 | #define SPEAR320_SSP1_BASE UL(0xA6000000) |
| 30 | 29 | ||
| 31 | /* Interrupt registers offsets and masks */ | ||
| 32 | #define SPEAR320_INT_STS_MASK_REG 0x04 | ||
| 33 | #define SPEAR320_INT_CLR_MASK_REG 0x04 | ||
| 34 | #define SPEAR320_INT_ENB_MASK_REG 0x08 | ||
| 35 | #define SPEAR320_GPIO_IRQ_MASK (1 << 0) | ||
| 36 | #define SPEAR320_I2S_PLAY_IRQ_MASK (1 << 1) | ||
| 37 | #define SPEAR320_I2S_REC_IRQ_MASK (1 << 2) | ||
| 38 | #define SPEAR320_EMI_IRQ_MASK (1 << 7) | ||
| 39 | #define SPEAR320_CLCD_IRQ_MASK (1 << 8) | ||
| 40 | #define SPEAR320_SPP_IRQ_MASK (1 << 9) | ||
| 41 | #define SPEAR320_SDHCI_IRQ_MASK (1 << 10) | ||
| 42 | #define SPEAR320_CAN_U_IRQ_MASK (1 << 11) | ||
| 43 | #define SPEAR320_CAN_L_IRQ_MASK (1 << 12) | ||
| 44 | #define SPEAR320_UART1_IRQ_MASK (1 << 13) | ||
| 45 | #define SPEAR320_UART2_IRQ_MASK (1 << 14) | ||
| 46 | #define SPEAR320_SSP1_IRQ_MASK (1 << 15) | ||
| 47 | #define SPEAR320_SSP2_IRQ_MASK (1 << 16) | ||
| 48 | #define SPEAR320_SMII0_IRQ_MASK (1 << 17) | ||
| 49 | #define SPEAR320_MII1_SMII1_IRQ_MASK (1 << 18) | ||
| 50 | #define SPEAR320_WAKEUP_SMII0_IRQ_MASK (1 << 19) | ||
| 51 | #define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK (1 << 20) | ||
| 52 | #define SPEAR320_I2C1_IRQ_MASK (1 << 21) | ||
| 53 | |||
| 54 | #define SPEAR320_SHIRQ_RAS1_MASK 0x000380 | ||
| 55 | #define SPEAR320_SHIRQ_RAS3_MASK 0x000007 | ||
| 56 | #define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK 0x3FF800 | ||
| 57 | |||
| 58 | /* SPEAr320 Virtual irq definitions */ | ||
| 59 | /* IRQs sharing IRQ_GEN_RAS_1 */ | ||
| 60 | #define SPEAR320_VIRQ_EMI (SPEAR3XX_VIRQ_START + 0) | ||
| 61 | #define SPEAR320_VIRQ_CLCD (SPEAR3XX_VIRQ_START + 1) | ||
| 62 | #define SPEAR320_VIRQ_SPP (SPEAR3XX_VIRQ_START + 2) | ||
| 63 | |||
| 64 | /* IRQs sharing IRQ_GEN_RAS_2 */ | ||
| 65 | #define SPEAR320_IRQ_SDHCI SPEAR3XX_IRQ_GEN_RAS_2 | ||
| 66 | |||
| 67 | /* IRQs sharing IRQ_GEN_RAS_3 */ | ||
| 68 | #define SPEAR320_VIRQ_PLGPIO (SPEAR3XX_VIRQ_START + 3) | ||
| 69 | #define SPEAR320_VIRQ_I2S_PLAY (SPEAR3XX_VIRQ_START + 4) | ||
| 70 | #define SPEAR320_VIRQ_I2S_REC (SPEAR3XX_VIRQ_START + 5) | ||
| 71 | |||
| 72 | /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ | ||
| 73 | #define SPEAR320_VIRQ_CANU (SPEAR3XX_VIRQ_START + 6) | ||
| 74 | #define SPEAR320_VIRQ_CANL (SPEAR3XX_VIRQ_START + 7) | ||
| 75 | #define SPEAR320_VIRQ_UART1 (SPEAR3XX_VIRQ_START + 8) | ||
| 76 | #define SPEAR320_VIRQ_UART2 (SPEAR3XX_VIRQ_START + 9) | ||
| 77 | #define SPEAR320_VIRQ_SSP1 (SPEAR3XX_VIRQ_START + 10) | ||
| 78 | #define SPEAR320_VIRQ_SSP2 (SPEAR3XX_VIRQ_START + 11) | ||
| 79 | #define SPEAR320_VIRQ_SMII0 (SPEAR3XX_VIRQ_START + 12) | ||
| 80 | #define SPEAR320_VIRQ_MII1_SMII1 (SPEAR3XX_VIRQ_START + 13) | ||
| 81 | #define SPEAR320_VIRQ_WAKEUP_SMII0 (SPEAR3XX_VIRQ_START + 14) | ||
| 82 | #define SPEAR320_VIRQ_WAKEUP_MII1_SMII1 (SPEAR3XX_VIRQ_START + 15) | ||
| 83 | #define SPEAR320_VIRQ_I2C1 (SPEAR3XX_VIRQ_START + 16) | ||
| 84 | |||
| 85 | /* spear3xx shared irq */ | ||
| 86 | static struct shirq_dev_config shirq_ras1_config[] = { | ||
| 87 | { | ||
| 88 | .virq = SPEAR320_VIRQ_EMI, | ||
| 89 | .status_mask = SPEAR320_EMI_IRQ_MASK, | ||
| 90 | .clear_mask = SPEAR320_EMI_IRQ_MASK, | ||
| 91 | }, { | ||
| 92 | .virq = SPEAR320_VIRQ_CLCD, | ||
| 93 | .status_mask = SPEAR320_CLCD_IRQ_MASK, | ||
| 94 | .clear_mask = SPEAR320_CLCD_IRQ_MASK, | ||
| 95 | }, { | ||
| 96 | .virq = SPEAR320_VIRQ_SPP, | ||
| 97 | .status_mask = SPEAR320_SPP_IRQ_MASK, | ||
| 98 | .clear_mask = SPEAR320_SPP_IRQ_MASK, | ||
| 99 | }, | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct spear_shirq shirq_ras1 = { | ||
| 103 | .irq = SPEAR3XX_IRQ_GEN_RAS_1, | ||
| 104 | .dev_config = shirq_ras1_config, | ||
| 105 | .dev_count = ARRAY_SIZE(shirq_ras1_config), | ||
| 106 | .regs = { | ||
| 107 | .enb_reg = -1, | ||
| 108 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 109 | .status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK, | ||
| 110 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 111 | .reset_to_clear = 1, | ||
| 112 | }, | ||
| 113 | }; | ||
| 114 | |||
| 115 | static struct shirq_dev_config shirq_ras3_config[] = { | ||
| 116 | { | ||
| 117 | .virq = SPEAR320_VIRQ_PLGPIO, | ||
| 118 | .enb_mask = SPEAR320_GPIO_IRQ_MASK, | ||
| 119 | .status_mask = SPEAR320_GPIO_IRQ_MASK, | ||
| 120 | .clear_mask = SPEAR320_GPIO_IRQ_MASK, | ||
| 121 | }, { | ||
| 122 | .virq = SPEAR320_VIRQ_I2S_PLAY, | ||
| 123 | .enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK, | ||
| 124 | .status_mask = SPEAR320_I2S_PLAY_IRQ_MASK, | ||
| 125 | .clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK, | ||
| 126 | }, { | ||
| 127 | .virq = SPEAR320_VIRQ_I2S_REC, | ||
| 128 | .enb_mask = SPEAR320_I2S_REC_IRQ_MASK, | ||
| 129 | .status_mask = SPEAR320_I2S_REC_IRQ_MASK, | ||
| 130 | .clear_mask = SPEAR320_I2S_REC_IRQ_MASK, | ||
| 131 | }, | ||
| 132 | }; | ||
| 133 | |||
| 134 | static struct spear_shirq shirq_ras3 = { | ||
| 135 | .irq = SPEAR3XX_IRQ_GEN_RAS_3, | ||
| 136 | .dev_config = shirq_ras3_config, | ||
| 137 | .dev_count = ARRAY_SIZE(shirq_ras3_config), | ||
| 138 | .regs = { | ||
| 139 | .enb_reg = SPEAR320_INT_ENB_MASK_REG, | ||
| 140 | .reset_to_enb = 1, | ||
| 141 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 142 | .status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK, | ||
| 143 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 144 | .reset_to_clear = 1, | ||
| 145 | }, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static struct shirq_dev_config shirq_intrcomm_ras_config[] = { | ||
| 149 | { | ||
| 150 | .virq = SPEAR320_VIRQ_CANU, | ||
| 151 | .status_mask = SPEAR320_CAN_U_IRQ_MASK, | ||
| 152 | .clear_mask = SPEAR320_CAN_U_IRQ_MASK, | ||
| 153 | }, { | ||
| 154 | .virq = SPEAR320_VIRQ_CANL, | ||
| 155 | .status_mask = SPEAR320_CAN_L_IRQ_MASK, | ||
| 156 | .clear_mask = SPEAR320_CAN_L_IRQ_MASK, | ||
| 157 | }, { | ||
| 158 | .virq = SPEAR320_VIRQ_UART1, | ||
| 159 | .status_mask = SPEAR320_UART1_IRQ_MASK, | ||
| 160 | .clear_mask = SPEAR320_UART1_IRQ_MASK, | ||
| 161 | }, { | ||
| 162 | .virq = SPEAR320_VIRQ_UART2, | ||
| 163 | .status_mask = SPEAR320_UART2_IRQ_MASK, | ||
| 164 | .clear_mask = SPEAR320_UART2_IRQ_MASK, | ||
| 165 | }, { | ||
| 166 | .virq = SPEAR320_VIRQ_SSP1, | ||
| 167 | .status_mask = SPEAR320_SSP1_IRQ_MASK, | ||
| 168 | .clear_mask = SPEAR320_SSP1_IRQ_MASK, | ||
| 169 | }, { | ||
| 170 | .virq = SPEAR320_VIRQ_SSP2, | ||
| 171 | .status_mask = SPEAR320_SSP2_IRQ_MASK, | ||
| 172 | .clear_mask = SPEAR320_SSP2_IRQ_MASK, | ||
| 173 | }, { | ||
| 174 | .virq = SPEAR320_VIRQ_SMII0, | ||
| 175 | .status_mask = SPEAR320_SMII0_IRQ_MASK, | ||
| 176 | .clear_mask = SPEAR320_SMII0_IRQ_MASK, | ||
| 177 | }, { | ||
| 178 | .virq = SPEAR320_VIRQ_MII1_SMII1, | ||
| 179 | .status_mask = SPEAR320_MII1_SMII1_IRQ_MASK, | ||
| 180 | .clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK, | ||
| 181 | }, { | ||
| 182 | .virq = SPEAR320_VIRQ_WAKEUP_SMII0, | ||
| 183 | .status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK, | ||
| 184 | .clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK, | ||
| 185 | }, { | ||
| 186 | .virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1, | ||
| 187 | .status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK, | ||
| 188 | .clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK, | ||
| 189 | }, { | ||
| 190 | .virq = SPEAR320_VIRQ_I2C1, | ||
| 191 | .status_mask = SPEAR320_I2C1_IRQ_MASK, | ||
| 192 | .clear_mask = SPEAR320_I2C1_IRQ_MASK, | ||
| 193 | }, | ||
| 194 | }; | ||
| 195 | |||
| 196 | static struct spear_shirq shirq_intrcomm_ras = { | ||
| 197 | .irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM, | ||
| 198 | .dev_config = shirq_intrcomm_ras_config, | ||
| 199 | .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config), | ||
| 200 | .regs = { | ||
| 201 | .enb_reg = -1, | ||
| 202 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 203 | .status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK, | ||
| 204 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 205 | .reset_to_clear = 1, | ||
| 206 | }, | ||
| 207 | }; | ||
| 208 | |||
| 209 | /* DMAC platform data's slave info */ | 30 | /* DMAC platform data's slave info */ |
| 210 | struct pl08x_channel_data spear320_dma_info[] = { | 31 | struct pl08x_channel_data spear320_dma_info[] = { |
| 211 | { | 32 | { |
| @@ -416,41 +237,17 @@ static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = { | |||
| 416 | 237 | ||
| 417 | static void __init spear320_dt_init(void) | 238 | static void __init spear320_dt_init(void) |
| 418 | { | 239 | { |
| 419 | void __iomem *base; | ||
| 420 | int ret; | ||
| 421 | |||
| 422 | pl080_plat_data.slave_channels = spear320_dma_info; | 240 | pl080_plat_data.slave_channels = spear320_dma_info; |
| 423 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info); | 241 | pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info); |
| 424 | 242 | ||
| 425 | of_platform_populate(NULL, of_default_bus_match_table, | 243 | of_platform_populate(NULL, of_default_bus_match_table, |
| 426 | spear320_auxdata_lookup, NULL); | 244 | spear320_auxdata_lookup, NULL); |
| 427 | |||
| 428 | /* shared irq registration */ | ||
| 429 | base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K); | ||
| 430 | if (base) { | ||
| 431 | /* shirq 1 */ | ||
| 432 | shirq_ras1.regs.base = base; | ||
| 433 | ret = spear_shirq_register(&shirq_ras1); | ||
| 434 | if (ret) | ||
| 435 | pr_err("Error registering Shared IRQ 1\n"); | ||
| 436 | |||
| 437 | /* shirq 3 */ | ||
| 438 | shirq_ras3.regs.base = base; | ||
| 439 | ret = spear_shirq_register(&shirq_ras3); | ||
| 440 | if (ret) | ||
| 441 | pr_err("Error registering Shared IRQ 3\n"); | ||
| 442 | |||
| 443 | /* shirq 4 */ | ||
| 444 | shirq_intrcomm_ras.regs.base = base; | ||
| 445 | ret = spear_shirq_register(&shirq_intrcomm_ras); | ||
| 446 | if (ret) | ||
| 447 | pr_err("Error registering Shared IRQ 4\n"); | ||
| 448 | } | ||
| 449 | } | 245 | } |
| 450 | 246 | ||
| 451 | static const char * const spear320_dt_board_compat[] = { | 247 | static const char * const spear320_dt_board_compat[] = { |
| 452 | "st,spear320", | 248 | "st,spear320", |
| 453 | "st,spear320-evb", | 249 | "st,spear320-evb", |
| 250 | "st,spear320-hmi", | ||
| 454 | NULL, | 251 | NULL, |
| 455 | }; | 252 | }; |
| 456 | 253 | ||
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index 98144baf8883..38fe95db31a7 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #include <linux/amba/pl022.h> | 16 | #include <linux/amba/pl022.h> |
| 17 | #include <linux/amba/pl08x.h> | 17 | #include <linux/amba/pl08x.h> |
| 18 | #include <linux/irqchip/spear-shirq.h> | ||
| 18 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
| 19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 20 | #include <asm/hardware/pl080.h> | 21 | #include <asm/hardware/pl080.h> |
| @@ -121,6 +122,9 @@ struct sys_timer spear3xx_timer = { | |||
| 121 | 122 | ||
| 122 | static const struct of_device_id vic_of_match[] __initconst = { | 123 | static const struct of_device_id vic_of_match[] __initconst = { |
| 123 | { .compatible = "arm,pl190-vic", .data = vic_of_init, }, | 124 | { .compatible = "arm,pl190-vic", .data = vic_of_init, }, |
| 125 | { .compatible = "st,spear300-shirq", .data = spear300_shirq_of_init, }, | ||
| 126 | { .compatible = "st,spear310-shirq", .data = spear310_shirq_of_init, }, | ||
| 127 | { .compatible = "st,spear320-shirq", .data = spear320_shirq_of_init, }, | ||
| 124 | { /* Sentinel */ } | 128 | { /* Sentinel */ } |
| 125 | }; | 129 | }; |
| 126 | 130 | ||
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index b8efac4daed8..ce2de0d6f2eb 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
| @@ -1445,7 +1445,6 @@ static struct platform_device pinctrl_device = { | |||
| 1445 | static struct u300_gpio_platform u300_gpio_plat = { | 1445 | static struct u300_gpio_platform u300_gpio_plat = { |
| 1446 | .ports = 7, | 1446 | .ports = 7, |
| 1447 | .gpio_base = 0, | 1447 | .gpio_base = 0, |
| 1448 | .gpio_irq_base = IRQ_U300_GPIO_BASE, | ||
| 1449 | .pinctrl_device = &pinctrl_device, | 1448 | .pinctrl_device = &pinctrl_device, |
| 1450 | }; | 1449 | }; |
| 1451 | 1450 | ||
| @@ -1804,7 +1803,7 @@ MACHINE_START(U300, "Ericsson AB U335 S335/B335 Prototype Board") | |||
| 1804 | /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ | 1803 | /* Maintainer: Linus Walleij <linus.walleij@stericsson.com> */ |
| 1805 | .atag_offset = 0x100, | 1804 | .atag_offset = 0x100, |
| 1806 | .map_io = u300_map_io, | 1805 | .map_io = u300_map_io, |
| 1807 | .nr_irqs = NR_IRQS_U300, | 1806 | .nr_irqs = 0, |
| 1808 | .init_irq = u300_init_irq, | 1807 | .init_irq = u300_init_irq, |
| 1809 | .handle_irq = vic_handle_irq, | 1808 | .handle_irq = vic_handle_irq, |
| 1810 | .timer = &u300_timer, | 1809 | .timer = &u300_timer, |
diff --git a/arch/arm/mach-u300/include/mach/irqs.h b/arch/arm/mach-u300/include/mach/irqs.h index e27425a63fa1..21d5e76a6cd3 100644 --- a/arch/arm/mach-u300/include/mach/irqs.h +++ b/arch/arm/mach-u300/include/mach/irqs.h | |||
| @@ -12,79 +12,69 @@ | |||
| 12 | #ifndef __MACH_IRQS_H | 12 | #ifndef __MACH_IRQS_H |
| 13 | #define __MACH_IRQS_H | 13 | #define __MACH_IRQS_H |
| 14 | 14 | ||
| 15 | #define IRQ_U300_INTCON0_START 1 | 15 | #define IRQ_U300_INTCON0_START 32 |
| 16 | #define IRQ_U300_INTCON1_START 33 | 16 | #define IRQ_U300_INTCON1_START 64 |
| 17 | /* These are on INTCON0 - 30 lines */ | 17 | /* These are on INTCON0 - 30 lines */ |
| 18 | #define IRQ_U300_IRQ0_EXT 1 | 18 | #define IRQ_U300_IRQ0_EXT 32 |
| 19 | #define IRQ_U300_IRQ1_EXT 2 | 19 | #define IRQ_U300_IRQ1_EXT 33 |
| 20 | #define IRQ_U300_DMA 3 | 20 | #define IRQ_U300_DMA 34 |
| 21 | #define IRQ_U300_VIDEO_ENC_0 4 | 21 | #define IRQ_U300_VIDEO_ENC_0 35 |
| 22 | #define IRQ_U300_VIDEO_ENC_1 5 | 22 | #define IRQ_U300_VIDEO_ENC_1 36 |
| 23 | #define IRQ_U300_AAIF_RX 6 | 23 | #define IRQ_U300_AAIF_RX 37 |
| 24 | #define IRQ_U300_AAIF_TX 7 | 24 | #define IRQ_U300_AAIF_TX 38 |
| 25 | #define IRQ_U300_AAIF_VGPIO 8 | 25 | #define IRQ_U300_AAIF_VGPIO 39 |
| 26 | #define IRQ_U300_AAIF_WAKEUP 9 | 26 | #define IRQ_U300_AAIF_WAKEUP 40 |
| 27 | #define IRQ_U300_PCM_I2S0_FRAME 10 | 27 | #define IRQ_U300_PCM_I2S0_FRAME 41 |
| 28 | #define IRQ_U300_PCM_I2S0_FIFO 11 | 28 | #define IRQ_U300_PCM_I2S0_FIFO 42 |
| 29 | #define IRQ_U300_PCM_I2S1_FRAME 12 | 29 | #define IRQ_U300_PCM_I2S1_FRAME 43 |
| 30 | #define IRQ_U300_PCM_I2S1_FIFO 13 | 30 | #define IRQ_U300_PCM_I2S1_FIFO 44 |
| 31 | #define IRQ_U300_XGAM_GAMCON 14 | 31 | #define IRQ_U300_XGAM_GAMCON 45 |
| 32 | #define IRQ_U300_XGAM_CDI 15 | 32 | #define IRQ_U300_XGAM_CDI 46 |
| 33 | #define IRQ_U300_XGAM_CDICON 16 | 33 | #define IRQ_U300_XGAM_CDICON 47 |
| 34 | #define IRQ_U300_XGAM_PDI 18 | 34 | #define IRQ_U300_XGAM_PDI 49 |
| 35 | #define IRQ_U300_XGAM_PDICON 19 | 35 | #define IRQ_U300_XGAM_PDICON 50 |
| 36 | #define IRQ_U300_XGAM_GAMEACC 20 | 36 | #define IRQ_U300_XGAM_GAMEACC 51 |
| 37 | #define IRQ_U300_XGAM_MCIDCT 21 | 37 | #define IRQ_U300_XGAM_MCIDCT 52 |
| 38 | #define IRQ_U300_APEX 22 | 38 | #define IRQ_U300_APEX 53 |
| 39 | #define IRQ_U300_UART0 23 | 39 | #define IRQ_U300_UART0 54 |
| 40 | #define IRQ_U300_SPI 24 | 40 | #define IRQ_U300_SPI 55 |
| 41 | #define IRQ_U300_TIMER_APP_OS 25 | 41 | #define IRQ_U300_TIMER_APP_OS 56 |
| 42 | #define IRQ_U300_TIMER_APP_DD 26 | 42 | #define IRQ_U300_TIMER_APP_DD 57 |
| 43 | #define IRQ_U300_TIMER_APP_GP1 27 | 43 | #define IRQ_U300_TIMER_APP_GP1 58 |
| 44 | #define IRQ_U300_TIMER_APP_GP2 28 | 44 | #define IRQ_U300_TIMER_APP_GP2 59 |
| 45 | #define IRQ_U300_TIMER_OS 29 | 45 | #define IRQ_U300_TIMER_OS 60 |
| 46 | #define IRQ_U300_TIMER_MS 30 | 46 | #define IRQ_U300_TIMER_MS 61 |
| 47 | #define IRQ_U300_KEYPAD_KEYBF 31 | 47 | #define IRQ_U300_KEYPAD_KEYBF 62 |
| 48 | #define IRQ_U300_KEYPAD_KEYBR 32 | 48 | #define IRQ_U300_KEYPAD_KEYBR 63 |
| 49 | /* These are on INTCON1 - 32 lines */ | 49 | /* These are on INTCON1 - 32 lines */ |
| 50 | #define IRQ_U300_GPIO_PORT0 33 | 50 | #define IRQ_U300_GPIO_PORT0 64 |
| 51 | #define IRQ_U300_GPIO_PORT1 34 | 51 | #define IRQ_U300_GPIO_PORT1 65 |
| 52 | #define IRQ_U300_GPIO_PORT2 35 | 52 | #define IRQ_U300_GPIO_PORT2 66 |
| 53 | 53 | ||
| 54 | /* These are for DB3150, DB3200 and DB3350 */ | 54 | /* These are for DB3150, DB3200 and DB3350 */ |
| 55 | #define IRQ_U300_WDOG 36 | 55 | #define IRQ_U300_WDOG 67 |
| 56 | #define IRQ_U300_EVHIST 37 | 56 | #define IRQ_U300_EVHIST 68 |
| 57 | #define IRQ_U300_MSPRO 38 | 57 | #define IRQ_U300_MSPRO 69 |
| 58 | #define IRQ_U300_MMCSD_MCIINTR0 39 | 58 | #define IRQ_U300_MMCSD_MCIINTR0 70 |
| 59 | #define IRQ_U300_MMCSD_MCIINTR1 40 | 59 | #define IRQ_U300_MMCSD_MCIINTR1 71 |
| 60 | #define IRQ_U300_I2C0 41 | 60 | #define IRQ_U300_I2C0 72 |
| 61 | #define IRQ_U300_I2C1 42 | 61 | #define IRQ_U300_I2C1 73 |
| 62 | #define IRQ_U300_RTC 43 | 62 | #define IRQ_U300_RTC 74 |
| 63 | #define IRQ_U300_NFIF 44 | 63 | #define IRQ_U300_NFIF 75 |
| 64 | #define IRQ_U300_NFIF2 45 | 64 | #define IRQ_U300_NFIF2 76 |
| 65 | 65 | ||
| 66 | /* The DB3350-specific interrupt lines */ | 66 | /* The DB3350-specific interrupt lines */ |
| 67 | #define IRQ_U300_ISP_F0 46 | 67 | #define IRQ_U300_ISP_F0 77 |
| 68 | #define IRQ_U300_ISP_F1 47 | 68 | #define IRQ_U300_ISP_F1 78 |
| 69 | #define IRQ_U300_ISP_F2 48 | 69 | #define IRQ_U300_ISP_F2 79 |
| 70 | #define IRQ_U300_ISP_F3 49 | 70 | #define IRQ_U300_ISP_F3 80 |
| 71 | #define IRQ_U300_ISP_F4 50 | 71 | #define IRQ_U300_ISP_F4 81 |
| 72 | #define IRQ_U300_GPIO_PORT3 51 | 72 | #define IRQ_U300_GPIO_PORT3 82 |
| 73 | #define IRQ_U300_SYSCON_PLL_LOCK 52 | 73 | #define IRQ_U300_SYSCON_PLL_LOCK 83 |
| 74 | #define IRQ_U300_UART1 53 | 74 | #define IRQ_U300_UART1 84 |
| 75 | #define IRQ_U300_GPIO_PORT4 54 | 75 | #define IRQ_U300_GPIO_PORT4 85 |
| 76 | #define IRQ_U300_GPIO_PORT5 55 | 76 | #define IRQ_U300_GPIO_PORT5 86 |
| 77 | #define IRQ_U300_GPIO_PORT6 56 | 77 | #define IRQ_U300_GPIO_PORT6 87 |
| 78 | #define U300_VIC_IRQS_END 57 | 78 | #define U300_VIC_IRQS_END 88 |
| 79 | |||
| 80 | /* Maximum 8*7 GPIO lines */ | ||
| 81 | #ifdef CONFIG_PINCTRL_COH901 | ||
| 82 | #define IRQ_U300_GPIO_BASE (U300_VIC_IRQS_END) | ||
| 83 | #define IRQ_U300_GPIO_END (IRQ_U300_GPIO_BASE + 56) | ||
| 84 | #else | ||
| 85 | #define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) | ||
| 86 | #endif | ||
| 87 | |||
| 88 | #define NR_IRQS_U300 (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START) | ||
| 89 | 79 | ||
| 90 | #endif | 80 | #endif |
diff --git a/arch/arm/plat-spear/Kconfig b/arch/arm/plat-spear/Kconfig index f8db7b2deb36..87dbd81bdf51 100644 --- a/arch/arm/plat-spear/Kconfig +++ b/arch/arm/plat-spear/Kconfig | |||
| @@ -12,6 +12,7 @@ config ARCH_SPEAR13XX | |||
| 12 | bool "ST SPEAr13xx with Device Tree" | 12 | bool "ST SPEAr13xx with Device Tree" |
| 13 | select ARM_GIC | 13 | select ARM_GIC |
| 14 | select CPU_V7 | 14 | select CPU_V7 |
| 15 | select GPIO_SPEAR_SPICS | ||
| 15 | select HAVE_SMP | 16 | select HAVE_SMP |
| 16 | select MIGHT_HAVE_CACHE_L2X0 | 17 | select MIGHT_HAVE_CACHE_L2X0 |
| 17 | select PINCTRL | 18 | select PINCTRL |
diff --git a/arch/arm/plat-spear/Makefile b/arch/arm/plat-spear/Makefile index 2607bd05c525..01e88532a5db 100644 --- a/arch/arm/plat-spear/Makefile +++ b/arch/arm/plat-spear/Makefile | |||
| @@ -5,5 +5,5 @@ | |||
| 5 | # Common support | 5 | # Common support |
| 6 | obj-y := restart.o time.o | 6 | obj-y := restart.o time.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o shirq.o | 8 | obj-$(CONFIG_ARCH_SPEAR3XX) += pl080.o |
| 9 | obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o | 9 | obj-$(CONFIG_ARCH_SPEAR6XX) += pl080.o |
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c deleted file mode 100644 index 853e891e1184..000000000000 --- a/arch/arm/plat-spear/shirq.c +++ /dev/null | |||
| @@ -1,118 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/plat-spear/shirq.c | ||
| 3 | * | ||
| 4 | * SPEAr platform shared irq layer source file | ||
| 5 | * | ||
| 6 | * Copyright (C) 2009 ST Microelectronics | ||
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | ||
| 8 | * | ||
| 9 | * This file is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2. This program is licensed "as is" without any | ||
| 11 | * warranty of any kind, whether express or implied. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/irq.h> | ||
| 17 | #include <linux/spinlock.h> | ||
| 18 | #include <plat/shirq.h> | ||
| 19 | |||
| 20 | struct spear_shirq *shirq; | ||
| 21 | static DEFINE_SPINLOCK(lock); | ||
| 22 | |||
| 23 | static void shirq_irq_mask(struct irq_data *d) | ||
| 24 | { | ||
| 25 | struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); | ||
| 26 | u32 val, id = d->irq - shirq->dev_config[0].virq; | ||
| 27 | unsigned long flags; | ||
| 28 | |||
| 29 | if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) | ||
| 30 | return; | ||
| 31 | |||
| 32 | spin_lock_irqsave(&lock, flags); | ||
| 33 | val = readl(shirq->regs.base + shirq->regs.enb_reg); | ||
| 34 | if (shirq->regs.reset_to_enb) | ||
| 35 | val |= shirq->dev_config[id].enb_mask; | ||
| 36 | else | ||
| 37 | val &= ~(shirq->dev_config[id].enb_mask); | ||
| 38 | writel(val, shirq->regs.base + shirq->regs.enb_reg); | ||
| 39 | spin_unlock_irqrestore(&lock, flags); | ||
| 40 | } | ||
| 41 | |||
| 42 | static void shirq_irq_unmask(struct irq_data *d) | ||
| 43 | { | ||
| 44 | struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); | ||
| 45 | u32 val, id = d->irq - shirq->dev_config[0].virq; | ||
| 46 | unsigned long flags; | ||
| 47 | |||
| 48 | if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1) | ||
| 49 | return; | ||
| 50 | |||
| 51 | spin_lock_irqsave(&lock, flags); | ||
| 52 | val = readl(shirq->regs.base + shirq->regs.enb_reg); | ||
| 53 | if (shirq->regs.reset_to_enb) | ||
| 54 | val &= ~(shirq->dev_config[id].enb_mask); | ||
| 55 | else | ||
| 56 | val |= shirq->dev_config[id].enb_mask; | ||
| 57 | writel(val, shirq->regs.base + shirq->regs.enb_reg); | ||
| 58 | spin_unlock_irqrestore(&lock, flags); | ||
| 59 | } | ||
| 60 | |||
| 61 | static struct irq_chip shirq_chip = { | ||
| 62 | .name = "spear_shirq", | ||
| 63 | .irq_ack = shirq_irq_mask, | ||
| 64 | .irq_mask = shirq_irq_mask, | ||
| 65 | .irq_unmask = shirq_irq_unmask, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static void shirq_handler(unsigned irq, struct irq_desc *desc) | ||
| 69 | { | ||
| 70 | u32 i, val, mask; | ||
| 71 | struct spear_shirq *shirq = irq_get_handler_data(irq); | ||
| 72 | |||
| 73 | desc->irq_data.chip->irq_ack(&desc->irq_data); | ||
| 74 | while ((val = readl(shirq->regs.base + shirq->regs.status_reg) & | ||
| 75 | shirq->regs.status_reg_mask)) { | ||
| 76 | for (i = 0; (i < shirq->dev_count) && val; i++) { | ||
| 77 | if (!(shirq->dev_config[i].status_mask & val)) | ||
| 78 | continue; | ||
| 79 | |||
| 80 | generic_handle_irq(shirq->dev_config[i].virq); | ||
| 81 | |||
| 82 | /* clear interrupt */ | ||
| 83 | val &= ~shirq->dev_config[i].status_mask; | ||
| 84 | if ((shirq->regs.clear_reg == -1) || | ||
| 85 | shirq->dev_config[i].clear_mask == -1) | ||
| 86 | continue; | ||
| 87 | mask = readl(shirq->regs.base + shirq->regs.clear_reg); | ||
| 88 | if (shirq->regs.reset_to_clear) | ||
| 89 | mask &= ~shirq->dev_config[i].clear_mask; | ||
| 90 | else | ||
| 91 | mask |= shirq->dev_config[i].clear_mask; | ||
| 92 | writel(mask, shirq->regs.base + shirq->regs.clear_reg); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | desc->irq_data.chip->irq_unmask(&desc->irq_data); | ||
| 96 | } | ||
| 97 | |||
| 98 | int spear_shirq_register(struct spear_shirq *shirq) | ||
| 99 | { | ||
| 100 | int i; | ||
| 101 | |||
| 102 | if (!shirq || !shirq->dev_config || !shirq->regs.base) | ||
| 103 | return -EFAULT; | ||
| 104 | |||
| 105 | if (!shirq->dev_count) | ||
| 106 | return -EINVAL; | ||
| 107 | |||
| 108 | irq_set_chained_handler(shirq->irq, shirq_handler); | ||
| 109 | for (i = 0; i < shirq->dev_count; i++) { | ||
| 110 | irq_set_chip_and_handler(shirq->dev_config[i].virq, | ||
| 111 | &shirq_chip, handle_simple_irq); | ||
| 112 | set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID); | ||
| 113 | irq_set_chip_data(shirq->dev_config[i].virq, shirq); | ||
| 114 | } | ||
| 115 | |||
| 116 | irq_set_handler_data(shirq->irq, shirq); | ||
| 117 | return 0; | ||
| 118 | } | ||
diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 0fcec2aae19c..cf7e17685a2c 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <mach/spear.h> | 20 | #include <mach/spear.h> |
| 21 | #include "clk.h" | 21 | #include "clk.h" |
| 22 | 22 | ||
| 23 | #define VA_SPEAR1310_RAS_BASE IOMEM(UL(0xFA400000)) | ||
| 23 | /* PLL related registers and bit values */ | 24 | /* PLL related registers and bit values */ |
| 24 | #define SPEAR1310_PLL_CFG (VA_MISC_BASE + 0x210) | 25 | #define SPEAR1310_PLL_CFG (VA_MISC_BASE + 0x210) |
| 25 | /* PLL_CFG bit values */ | 26 | /* PLL_CFG bit values */ |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 47150f5ded04..b0e67b200aa0 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
| @@ -86,11 +86,26 @@ config GPIO_DA9052 | |||
| 86 | help | 86 | help |
| 87 | Say yes here to enable the GPIO driver for the DA9052 chip. | 87 | Say yes here to enable the GPIO driver for the DA9052 chip. |
| 88 | 88 | ||
| 89 | config GPIO_DA9055 | ||
| 90 | tristate "Dialog Semiconductor DA9055 GPIO" | ||
| 91 | depends on MFD_DA9055 | ||
| 92 | help | ||
| 93 | Say yes here to enable the GPIO driver for the DA9055 chip. | ||
| 94 | |||
| 95 | The Dialog DA9055 PMIC chip has 3 GPIO pins that can be | ||
| 96 | be controller by this driver. | ||
| 97 | |||
| 98 | If driver is built as a module it will be called gpio-da9055. | ||
| 99 | |||
| 89 | config GPIO_MAX730X | 100 | config GPIO_MAX730X |
| 90 | tristate | 101 | tristate |
| 91 | 102 | ||
| 92 | comment "Memory mapped GPIO drivers:" | 103 | comment "Memory mapped GPIO drivers:" |
| 93 | 104 | ||
| 105 | config GPIO_CLPS711X | ||
| 106 | def_bool y | ||
| 107 | depends on ARCH_CLPS711X | ||
| 108 | |||
| 94 | config GPIO_GENERIC_PLATFORM | 109 | config GPIO_GENERIC_PLATFORM |
| 95 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" | 110 | tristate "Generic memory-mapped GPIO controller support (MMIO platform device)" |
| 96 | select GPIO_GENERIC | 111 | select GPIO_GENERIC |
| @@ -181,6 +196,13 @@ config GPIO_PXA | |||
| 181 | help | 196 | help |
| 182 | Say yes here to support the PXA GPIO device | 197 | Say yes here to support the PXA GPIO device |
| 183 | 198 | ||
| 199 | config GPIO_SPEAR_SPICS | ||
| 200 | bool "ST SPEAr13xx SPI Chip Select as GPIO support" | ||
| 201 | depends on PLAT_SPEAR | ||
| 202 | select GENERIC_IRQ_CHIP | ||
| 203 | help | ||
| 204 | Say yes here to support ST SPEAr SPI Chip Select as GPIO device | ||
| 205 | |||
| 184 | config GPIO_STA2X11 | 206 | config GPIO_STA2X11 |
| 185 | bool "STA2x11/ConneXt GPIO support" | 207 | bool "STA2x11/ConneXt GPIO support" |
| 186 | depends on MFD_STA2X11 | 208 | depends on MFD_STA2X11 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9aeed6707326..a268d99f4e43 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -16,8 +16,10 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o | |||
| 16 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o | 16 | obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o |
| 17 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o | 17 | obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o |
| 18 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 18 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
| 19 | obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o | ||
| 19 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 20 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
| 20 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 21 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
| 22 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o | ||
| 21 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | 23 | obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o |
| 22 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 24 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
| 23 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 25 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
| @@ -57,6 +59,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | |||
| 57 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 59 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
| 58 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 60 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
| 59 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o | 61 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o |
| 62 | obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o | ||
| 60 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o | 63 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o |
| 61 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 64 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
| 62 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o | 65 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o |
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c new file mode 100644 index 000000000000..ce63b75b13f5 --- /dev/null +++ b/drivers/gpio/gpio-clps711x.c | |||
| @@ -0,0 +1,199 @@ | |||
| 1 | /* | ||
| 2 | * CLPS711X GPIO driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/io.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/spinlock.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <mach/hardware.h> | ||
| 20 | |||
| 21 | #define CLPS711X_GPIO_PORTS 5 | ||
| 22 | #define CLPS711X_GPIO_NAME "gpio-clps711x" | ||
| 23 | |||
| 24 | struct clps711x_gpio { | ||
| 25 | struct gpio_chip chip[CLPS711X_GPIO_PORTS]; | ||
| 26 | spinlock_t lock; | ||
| 27 | }; | ||
| 28 | |||
| 29 | static void __iomem *clps711x_ports[] = { | ||
| 30 | CLPS711X_VIRT_BASE + PADR, | ||
| 31 | CLPS711X_VIRT_BASE + PBDR, | ||
| 32 | CLPS711X_VIRT_BASE + PCDR, | ||
| 33 | CLPS711X_VIRT_BASE + PDDR, | ||
| 34 | CLPS711X_VIRT_BASE + PEDR, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static void __iomem *clps711x_pdirs[] = { | ||
| 38 | CLPS711X_VIRT_BASE + PADDR, | ||
| 39 | CLPS711X_VIRT_BASE + PBDDR, | ||
| 40 | CLPS711X_VIRT_BASE + PCDDR, | ||
| 41 | CLPS711X_VIRT_BASE + PDDDR, | ||
| 42 | CLPS711X_VIRT_BASE + PEDDR, | ||
| 43 | }; | ||
| 44 | |||
| 45 | #define clps711x_port(x) clps711x_ports[x->base / 8] | ||
| 46 | #define clps711x_pdir(x) clps711x_pdirs[x->base / 8] | ||
| 47 | |||
| 48 | static int gpio_clps711x_get(struct gpio_chip *chip, unsigned offset) | ||
| 49 | { | ||
| 50 | return !!(readb(clps711x_port(chip)) & (1 << offset)); | ||
| 51 | } | ||
| 52 | |||
| 53 | static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset, | ||
| 54 | int value) | ||
| 55 | { | ||
| 56 | int tmp; | ||
| 57 | unsigned long flags; | ||
| 58 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
| 59 | |||
| 60 | spin_lock_irqsave(&gpio->lock, flags); | ||
| 61 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
| 62 | if (value) | ||
| 63 | tmp |= 1 << offset; | ||
| 64 | writeb(tmp, clps711x_port(chip)); | ||
| 65 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
| 66 | } | ||
| 67 | |||
| 68 | static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset) | ||
| 69 | { | ||
| 70 | int tmp; | ||
| 71 | unsigned long flags; | ||
| 72 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
| 73 | |||
| 74 | spin_lock_irqsave(&gpio->lock, flags); | ||
| 75 | tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); | ||
| 76 | writeb(tmp, clps711x_pdir(chip)); | ||
| 77 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset, | ||
| 83 | int value) | ||
| 84 | { | ||
| 85 | int tmp; | ||
| 86 | unsigned long flags; | ||
| 87 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
| 88 | |||
| 89 | spin_lock_irqsave(&gpio->lock, flags); | ||
| 90 | tmp = readb(clps711x_pdir(chip)) | (1 << offset); | ||
| 91 | writeb(tmp, clps711x_pdir(chip)); | ||
| 92 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
| 93 | if (value) | ||
| 94 | tmp |= 1 << offset; | ||
| 95 | writeb(tmp, clps711x_port(chip)); | ||
| 96 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
| 97 | |||
| 98 | return 0; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset) | ||
| 102 | { | ||
| 103 | int tmp; | ||
| 104 | unsigned long flags; | ||
| 105 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
| 106 | |||
| 107 | spin_lock_irqsave(&gpio->lock, flags); | ||
| 108 | tmp = readb(clps711x_pdir(chip)) | (1 << offset); | ||
| 109 | writeb(tmp, clps711x_pdir(chip)); | ||
| 110 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
| 111 | |||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset, | ||
| 116 | int value) | ||
| 117 | { | ||
| 118 | int tmp; | ||
| 119 | unsigned long flags; | ||
| 120 | struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev); | ||
| 121 | |||
| 122 | spin_lock_irqsave(&gpio->lock, flags); | ||
| 123 | tmp = readb(clps711x_pdir(chip)) & ~(1 << offset); | ||
| 124 | writeb(tmp, clps711x_pdir(chip)); | ||
| 125 | tmp = readb(clps711x_port(chip)) & ~(1 << offset); | ||
| 126 | if (value) | ||
| 127 | tmp |= 1 << offset; | ||
| 128 | writeb(tmp, clps711x_port(chip)); | ||
| 129 | spin_unlock_irqrestore(&gpio->lock, flags); | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | static struct { | ||
| 135 | char *name; | ||
| 136 | int nr; | ||
| 137 | int inv_dir; | ||
| 138 | } clps711x_gpio_ports[] __initconst = { | ||
| 139 | { "PORTA", 8, 0, }, | ||
| 140 | { "PORTB", 8, 0, }, | ||
| 141 | { "PORTC", 8, 0, }, | ||
| 142 | { "PORTD", 8, 1, }, | ||
| 143 | { "PORTE", 3, 0, }, | ||
| 144 | }; | ||
| 145 | |||
| 146 | static int __init gpio_clps711x_init(void) | ||
| 147 | { | ||
| 148 | int i; | ||
| 149 | struct platform_device *pdev; | ||
| 150 | struct clps711x_gpio *gpio; | ||
| 151 | |||
| 152 | pdev = platform_device_alloc(CLPS711X_GPIO_NAME, 0); | ||
| 153 | if (!pdev) { | ||
| 154 | pr_err("Cannot create platform device: %s\n", | ||
| 155 | CLPS711X_GPIO_NAME); | ||
| 156 | return -ENOMEM; | ||
| 157 | } | ||
| 158 | |||
| 159 | platform_device_add(pdev); | ||
| 160 | |||
| 161 | gpio = devm_kzalloc(&pdev->dev, sizeof(struct clps711x_gpio), | ||
| 162 | GFP_KERNEL); | ||
| 163 | if (!gpio) { | ||
| 164 | dev_err(&pdev->dev, "GPIO allocating memory error\n"); | ||
| 165 | platform_device_unregister(pdev); | ||
| 166 | return -ENOMEM; | ||
| 167 | } | ||
| 168 | |||
| 169 | platform_set_drvdata(pdev, gpio); | ||
| 170 | |||
| 171 | spin_lock_init(&gpio->lock); | ||
| 172 | |||
| 173 | for (i = 0; i < CLPS711X_GPIO_PORTS; i++) { | ||
| 174 | gpio->chip[i].owner = THIS_MODULE; | ||
| 175 | gpio->chip[i].dev = &pdev->dev; | ||
| 176 | gpio->chip[i].label = clps711x_gpio_ports[i].name; | ||
| 177 | gpio->chip[i].base = i * 8; | ||
| 178 | gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; | ||
| 179 | gpio->chip[i].get = gpio_clps711x_get; | ||
| 180 | gpio->chip[i].set = gpio_clps711x_set; | ||
| 181 | if (!clps711x_gpio_ports[i].inv_dir) { | ||
| 182 | gpio->chip[i].direction_input = gpio_clps711x_dir_in; | ||
| 183 | gpio->chip[i].direction_output = gpio_clps711x_dir_out; | ||
| 184 | } else { | ||
| 185 | gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv; | ||
| 186 | gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv; | ||
| 187 | } | ||
| 188 | WARN_ON(gpiochip_add(&gpio->chip[i])); | ||
| 189 | } | ||
| 190 | |||
| 191 | dev_info(&pdev->dev, "GPIO driver initialized\n"); | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | arch_initcall(gpio_clps711x_init); | ||
| 196 | |||
| 197 | MODULE_LICENSE("GPL v2"); | ||
| 198 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
| 199 | MODULE_DESCRIPTION("CLPS711X GPIO driver"); | ||
diff --git a/drivers/gpio/gpio-da9055.c b/drivers/gpio/gpio-da9055.c new file mode 100644 index 000000000000..55d83c7d9c7f --- /dev/null +++ b/drivers/gpio/gpio-da9055.c | |||
| @@ -0,0 +1,204 @@ | |||
| 1 | /* | ||
| 2 | * GPIO Driver for Dialog DA9055 PMICs. | ||
| 3 | * | ||
| 4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | ||
| 5 | * | ||
| 6 | * Author: David Dajun Chen <dchen@diasemi.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/gpio.h> | ||
| 17 | |||
| 18 | #include <linux/mfd/da9055/core.h> | ||
| 19 | #include <linux/mfd/da9055/reg.h> | ||
| 20 | #include <linux/mfd/da9055/pdata.h> | ||
| 21 | |||
| 22 | #define DA9055_VDD_IO 0x0 | ||
| 23 | #define DA9055_PUSH_PULL 0x3 | ||
| 24 | #define DA9055_ACT_LOW 0x0 | ||
| 25 | #define DA9055_GPI 0x1 | ||
| 26 | #define DA9055_PORT_MASK 0x3 | ||
| 27 | #define DA9055_PORT_SHIFT(offset) (4 * (offset % 2)) | ||
| 28 | |||
| 29 | #define DA9055_INPUT DA9055_GPI | ||
| 30 | #define DA9055_OUTPUT DA9055_PUSH_PULL | ||
| 31 | #define DA9055_IRQ_GPI0 3 | ||
| 32 | |||
| 33 | struct da9055_gpio { | ||
| 34 | struct da9055 *da9055; | ||
| 35 | struct gpio_chip gp; | ||
| 36 | }; | ||
| 37 | |||
| 38 | static inline struct da9055_gpio *to_da9055_gpio(struct gpio_chip *chip) | ||
| 39 | { | ||
| 40 | return container_of(chip, struct da9055_gpio, gp); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int da9055_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
| 44 | { | ||
| 45 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
| 46 | int gpio_direction = 0; | ||
| 47 | int ret; | ||
| 48 | |||
| 49 | /* Get GPIO direction */ | ||
| 50 | ret = da9055_reg_read(gpio->da9055, (offset >> 1) + DA9055_REG_GPIO0_1); | ||
| 51 | if (ret < 0) | ||
| 52 | return ret; | ||
| 53 | |||
| 54 | gpio_direction = ret & (DA9055_PORT_MASK) << DA9055_PORT_SHIFT(offset); | ||
| 55 | gpio_direction >>= DA9055_PORT_SHIFT(offset); | ||
| 56 | switch (gpio_direction) { | ||
| 57 | case DA9055_INPUT: | ||
| 58 | ret = da9055_reg_read(gpio->da9055, DA9055_REG_STATUS_B); | ||
| 59 | if (ret < 0) | ||
| 60 | return ret; | ||
| 61 | break; | ||
| 62 | case DA9055_OUTPUT: | ||
| 63 | ret = da9055_reg_read(gpio->da9055, DA9055_REG_GPIO_MODE0_2); | ||
| 64 | if (ret < 0) | ||
| 65 | return ret; | ||
| 66 | } | ||
| 67 | |||
| 68 | return ret & (1 << offset); | ||
| 69 | |||
| 70 | } | ||
| 71 | |||
| 72 | static void da9055_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | ||
| 73 | { | ||
| 74 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
| 75 | |||
| 76 | da9055_reg_update(gpio->da9055, | ||
| 77 | DA9055_REG_GPIO_MODE0_2, | ||
| 78 | 1 << offset, | ||
| 79 | value << offset); | ||
| 80 | } | ||
| 81 | |||
| 82 | static int da9055_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||
| 83 | { | ||
| 84 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
| 85 | unsigned char reg_byte; | ||
| 86 | |||
| 87 | reg_byte = (DA9055_ACT_LOW | DA9055_GPI) | ||
| 88 | << DA9055_PORT_SHIFT(offset); | ||
| 89 | |||
| 90 | return da9055_reg_update(gpio->da9055, (offset >> 1) + | ||
| 91 | DA9055_REG_GPIO0_1, | ||
| 92 | DA9055_PORT_MASK << | ||
| 93 | DA9055_PORT_SHIFT(offset), | ||
| 94 | reg_byte); | ||
| 95 | } | ||
| 96 | |||
| 97 | static int da9055_gpio_direction_output(struct gpio_chip *gc, | ||
| 98 | unsigned offset, int value) | ||
| 99 | { | ||
| 100 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
| 101 | unsigned char reg_byte; | ||
| 102 | int ret; | ||
| 103 | |||
| 104 | reg_byte = (DA9055_VDD_IO | DA9055_PUSH_PULL) | ||
| 105 | << DA9055_PORT_SHIFT(offset); | ||
| 106 | |||
| 107 | ret = da9055_reg_update(gpio->da9055, (offset >> 1) + | ||
| 108 | DA9055_REG_GPIO0_1, | ||
| 109 | DA9055_PORT_MASK << | ||
| 110 | DA9055_PORT_SHIFT(offset), | ||
| 111 | reg_byte); | ||
| 112 | if (ret < 0) | ||
| 113 | return ret; | ||
| 114 | |||
| 115 | da9055_gpio_set(gc, offset, value); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int da9055_gpio_to_irq(struct gpio_chip *gc, u32 offset) | ||
| 121 | { | ||
| 122 | struct da9055_gpio *gpio = to_da9055_gpio(gc); | ||
| 123 | struct da9055 *da9055 = gpio->da9055; | ||
| 124 | |||
| 125 | return regmap_irq_get_virq(da9055->irq_data, | ||
| 126 | DA9055_IRQ_GPI0 + offset); | ||
| 127 | } | ||
| 128 | |||
| 129 | static struct gpio_chip reference_gp __devinitdata = { | ||
| 130 | .label = "da9055-gpio", | ||
| 131 | .owner = THIS_MODULE, | ||
| 132 | .get = da9055_gpio_get, | ||
| 133 | .set = da9055_gpio_set, | ||
| 134 | .direction_input = da9055_gpio_direction_input, | ||
| 135 | .direction_output = da9055_gpio_direction_output, | ||
| 136 | .to_irq = da9055_gpio_to_irq, | ||
| 137 | .can_sleep = 1, | ||
| 138 | .ngpio = 3, | ||
| 139 | .base = -1, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static int __devinit da9055_gpio_probe(struct platform_device *pdev) | ||
| 143 | { | ||
| 144 | struct da9055_gpio *gpio; | ||
| 145 | struct da9055_pdata *pdata; | ||
| 146 | int ret; | ||
| 147 | |||
| 148 | gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); | ||
| 149 | if (gpio == NULL) | ||
| 150 | return -ENOMEM; | ||
| 151 | |||
| 152 | gpio->da9055 = dev_get_drvdata(pdev->dev.parent); | ||
| 153 | pdata = gpio->da9055->dev->platform_data; | ||
| 154 | |||
| 155 | gpio->gp = reference_gp; | ||
| 156 | if (pdata && pdata->gpio_base) | ||
| 157 | gpio->gp.base = pdata->gpio_base; | ||
| 158 | |||
| 159 | ret = gpiochip_add(&gpio->gp); | ||
| 160 | if (ret < 0) { | ||
| 161 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); | ||
| 162 | goto err_mem; | ||
| 163 | } | ||
| 164 | |||
| 165 | platform_set_drvdata(pdev, gpio); | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | |||
| 169 | err_mem: | ||
| 170 | return ret; | ||
| 171 | } | ||
| 172 | |||
| 173 | static int __devexit da9055_gpio_remove(struct platform_device *pdev) | ||
| 174 | { | ||
| 175 | struct da9055_gpio *gpio = platform_get_drvdata(pdev); | ||
| 176 | |||
| 177 | return gpiochip_remove(&gpio->gp); | ||
| 178 | } | ||
| 179 | |||
| 180 | static struct platform_driver da9055_gpio_driver = { | ||
| 181 | .probe = da9055_gpio_probe, | ||
| 182 | .remove = __devexit_p(da9055_gpio_remove), | ||
| 183 | .driver = { | ||
| 184 | .name = "da9055-gpio", | ||
| 185 | .owner = THIS_MODULE, | ||
| 186 | }, | ||
| 187 | }; | ||
| 188 | |||
| 189 | static int __init da9055_gpio_init(void) | ||
| 190 | { | ||
| 191 | return platform_driver_register(&da9055_gpio_driver); | ||
| 192 | } | ||
| 193 | subsys_initcall(da9055_gpio_init); | ||
| 194 | |||
| 195 | static void __exit da9055_gpio_exit(void) | ||
| 196 | { | ||
| 197 | platform_driver_unregister(&da9055_gpio_driver); | ||
| 198 | } | ||
| 199 | module_exit(da9055_gpio_exit); | ||
| 200 | |||
| 201 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | ||
| 202 | MODULE_DESCRIPTION("DA9055 GPIO Device Driver"); | ||
| 203 | MODULE_LICENSE("GPL"); | ||
| 204 | MODULE_ALIAS("platform:da9055-gpio"); | ||
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index efb4c2d0d132..b00706329d26 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | struct em_gio_priv { | 35 | struct em_gio_priv { |
| 36 | void __iomem *base0; | 36 | void __iomem *base0; |
| 37 | void __iomem *base1; | 37 | void __iomem *base1; |
| 38 | unsigned int irq_base; | ||
| 39 | spinlock_t sense_lock; | 38 | spinlock_t sense_lock; |
| 40 | struct platform_device *pdev; | 39 | struct platform_device *pdev; |
| 41 | struct gpio_chip gpio_chip; | 40 | struct gpio_chip gpio_chip; |
| @@ -214,7 +213,7 @@ static int em_gio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
| 214 | 213 | ||
| 215 | static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) | 214 | static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) |
| 216 | { | 215 | { |
| 217 | return irq_find_mapping(gpio_to_priv(chip)->irq_domain, offset); | 216 | return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); |
| 218 | } | 217 | } |
| 219 | 218 | ||
| 220 | static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, | 219 | static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, |
| @@ -234,40 +233,6 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { | |||
| 234 | .map = em_gio_irq_domain_map, | 233 | .map = em_gio_irq_domain_map, |
| 235 | }; | 234 | }; |
| 236 | 235 | ||
| 237 | static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | ||
| 238 | { | ||
| 239 | struct platform_device *pdev = p->pdev; | ||
| 240 | struct gpio_em_config *pdata = pdev->dev.platform_data; | ||
| 241 | |||
| 242 | p->irq_base = irq_alloc_descs(pdata->irq_base, 0, | ||
| 243 | pdata->number_of_pins, numa_node_id()); | ||
| 244 | if (p->irq_base < 0) { | ||
| 245 | dev_err(&pdev->dev, "cannot get irq_desc\n"); | ||
| 246 | return p->irq_base; | ||
| 247 | } | ||
| 248 | pr_debug("gio: hw base = %d, nr = %d, sw base = %d\n", | ||
| 249 | pdata->gpio_base, pdata->number_of_pins, p->irq_base); | ||
| 250 | |||
| 251 | p->irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
| 252 | pdata->number_of_pins, | ||
| 253 | p->irq_base, 0, | ||
| 254 | &em_gio_irq_domain_ops, p); | ||
| 255 | if (!p->irq_domain) { | ||
| 256 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
| 257 | return -ENXIO; | ||
| 258 | } | ||
| 259 | |||
| 260 | return 0; | ||
| 261 | } | ||
| 262 | |||
| 263 | static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) | ||
| 264 | { | ||
| 265 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; | ||
| 266 | |||
| 267 | irq_free_descs(p->irq_base, pdata->number_of_pins); | ||
| 268 | /* FIXME: irq domain wants to be freed! */ | ||
| 269 | } | ||
| 270 | |||
| 271 | static int __devinit em_gio_probe(struct platform_device *pdev) | 236 | static int __devinit em_gio_probe(struct platform_device *pdev) |
| 272 | { | 237 | { |
| 273 | struct gpio_em_config *pdata = pdev->dev.platform_data; | 238 | struct gpio_em_config *pdata = pdev->dev.platform_data; |
| @@ -334,8 +299,11 @@ static int __devinit em_gio_probe(struct platform_device *pdev) | |||
| 334 | irq_chip->irq_set_type = em_gio_irq_set_type; | 299 | irq_chip->irq_set_type = em_gio_irq_set_type; |
| 335 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; | 300 | irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; |
| 336 | 301 | ||
| 337 | ret = em_gio_irq_domain_init(p); | 302 | p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, |
| 338 | if (ret) { | 303 | pdata->number_of_pins, |
| 304 | &em_gio_irq_domain_ops, p); | ||
| 305 | if (!p->irq_domain) { | ||
| 306 | ret = -ENXIO; | ||
| 339 | dev_err(&pdev->dev, "cannot initialize irq domain\n"); | 307 | dev_err(&pdev->dev, "cannot initialize irq domain\n"); |
| 340 | goto err3; | 308 | goto err3; |
| 341 | } | 309 | } |
| @@ -364,7 +332,7 @@ err6: | |||
| 364 | err5: | 332 | err5: |
| 365 | free_irq(irq[0]->start, pdev); | 333 | free_irq(irq[0]->start, pdev); |
| 366 | err4: | 334 | err4: |
| 367 | em_gio_irq_domain_cleanup(p); | 335 | irq_domain_remove(p->irq_domain); |
| 368 | err3: | 336 | err3: |
| 369 | iounmap(p->base1); | 337 | iounmap(p->base1); |
| 370 | err2: | 338 | err2: |
| @@ -390,7 +358,7 @@ static int __devexit em_gio_remove(struct platform_device *pdev) | |||
| 390 | 358 | ||
| 391 | free_irq(irq[1]->start, pdev); | 359 | free_irq(irq[1]->start, pdev); |
| 392 | free_irq(irq[0]->start, pdev); | 360 | free_irq(irq[0]->start, pdev); |
| 393 | em_gio_irq_domain_cleanup(p); | 361 | irq_domain_remove(p->irq_domain); |
| 394 | iounmap(p->base1); | 362 | iounmap(p->base1); |
| 395 | iounmap(p->base0); | 363 | iounmap(p->base0); |
| 396 | kfree(p); | 364 | kfree(p); |
diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 05e2dac60b3b..c4bf86abd4d8 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c | |||
| @@ -167,10 +167,6 @@ int __devinit __max730x_probe(struct max7301 *ts) | |||
| 167 | int i, ret; | 167 | int i, ret; |
| 168 | 168 | ||
| 169 | pdata = dev->platform_data; | 169 | pdata = dev->platform_data; |
| 170 | if (!pdata || !pdata->base) { | ||
| 171 | dev_err(dev, "incorrect or missing platform data\n"); | ||
| 172 | return -EINVAL; | ||
| 173 | } | ||
| 174 | 170 | ||
| 175 | mutex_init(&ts->lock); | 171 | mutex_init(&ts->lock); |
| 176 | dev_set_drvdata(dev, ts); | 172 | dev_set_drvdata(dev, ts); |
| @@ -178,7 +174,12 @@ int __devinit __max730x_probe(struct max7301 *ts) | |||
| 178 | /* Power up the chip and disable IRQ output */ | 174 | /* Power up the chip and disable IRQ output */ |
| 179 | ts->write(dev, 0x04, 0x01); | 175 | ts->write(dev, 0x04, 0x01); |
| 180 | 176 | ||
| 181 | ts->input_pullup_active = pdata->input_pullup_active; | 177 | if (pdata) { |
| 178 | ts->input_pullup_active = pdata->input_pullup_active; | ||
| 179 | ts->chip.base = pdata->base; | ||
| 180 | } else { | ||
| 181 | ts->chip.base = -1; | ||
| 182 | } | ||
| 182 | ts->chip.label = dev->driver->name; | 183 | ts->chip.label = dev->driver->name; |
| 183 | 184 | ||
| 184 | ts->chip.direction_input = max7301_direction_input; | 185 | ts->chip.direction_input = max7301_direction_input; |
| @@ -186,7 +187,6 @@ int __devinit __max730x_probe(struct max7301 *ts) | |||
| 186 | ts->chip.direction_output = max7301_direction_output; | 187 | ts->chip.direction_output = max7301_direction_output; |
| 187 | ts->chip.set = max7301_set; | 188 | ts->chip.set = max7301_set; |
| 188 | 189 | ||
| 189 | ts->chip.base = pdata->base; | ||
| 190 | ts->chip.ngpio = PIN_NUMBER; | 190 | ts->chip.ngpio = PIN_NUMBER; |
| 191 | ts->chip.can_sleep = 1; | 191 | ts->chip.can_sleep = 1; |
| 192 | ts->chip.dev = dev; | 192 | ts->chip.dev = dev; |
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index be65c0451ad5..a515b9294e92 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c | |||
| @@ -168,12 +168,12 @@ static void __iomem *mvebu_gpioreg_level_mask(struct mvebu_gpio_chip *mvchip) | |||
| 168 | * Functions implementing the gpio_chip methods | 168 | * Functions implementing the gpio_chip methods |
| 169 | */ | 169 | */ |
| 170 | 170 | ||
| 171 | int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) | 171 | static int mvebu_gpio_request(struct gpio_chip *chip, unsigned pin) |
| 172 | { | 172 | { |
| 173 | return pinctrl_request_gpio(chip->base + pin); | 173 | return pinctrl_request_gpio(chip->base + pin); |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) | 176 | static void mvebu_gpio_free(struct gpio_chip *chip, unsigned pin) |
| 177 | { | 177 | { |
| 178 | pinctrl_free_gpio(chip->base + pin); | 178 | pinctrl_free_gpio(chip->base + pin); |
| 179 | } | 179 | } |
| @@ -546,6 +546,7 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
| 546 | mvchip->chip.label = dev_name(&pdev->dev); | 546 | mvchip->chip.label = dev_name(&pdev->dev); |
| 547 | mvchip->chip.dev = &pdev->dev; | 547 | mvchip->chip.dev = &pdev->dev; |
| 548 | mvchip->chip.request = mvebu_gpio_request; | 548 | mvchip->chip.request = mvebu_gpio_request; |
| 549 | mvchip->chip.free = mvebu_gpio_free; | ||
| 549 | mvchip->chip.direction_input = mvebu_gpio_direction_input; | 550 | mvchip->chip.direction_input = mvebu_gpio_direction_input; |
| 550 | mvchip->chip.get = mvebu_gpio_get; | 551 | mvchip->chip.get = mvebu_gpio_get; |
| 551 | mvchip->chip.direction_output = mvebu_gpio_direction_output; | 552 | mvchip->chip.direction_output = mvebu_gpio_direction_output; |
| @@ -673,8 +674,8 @@ static int __devinit mvebu_gpio_probe(struct platform_device *pdev) | |||
| 673 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 674 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
| 674 | 675 | ||
| 675 | /* Setup irq domain on top of the generic chip. */ | 676 | /* Setup irq domain on top of the generic chip. */ |
| 676 | mvchip->domain = irq_domain_add_legacy(np, mvchip->chip.ngpio, | 677 | mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio, |
| 677 | mvchip->irqbase, 0, | 678 | mvchip->irqbase, |
| 678 | &irq_domain_simple_ops, | 679 | &irq_domain_simple_ops, |
| 679 | mvchip); | 680 | mvchip); |
| 680 | if (!mvchip->domain) { | 681 | if (!mvchip->domain) { |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index d335af1d4d85..d71e5bdf7b97 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
| @@ -1105,7 +1105,7 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) | |||
| 1105 | if (!pdata) | 1105 | if (!pdata) |
| 1106 | return -EINVAL; | 1106 | return -EINVAL; |
| 1107 | 1107 | ||
| 1108 | bank = devm_kzalloc(&pdev->dev, sizeof(struct gpio_bank), GFP_KERNEL); | 1108 | bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); |
| 1109 | if (!bank) { | 1109 | if (!bank) { |
| 1110 | dev_err(dev, "Memory alloc failed\n"); | 1110 | dev_err(dev, "Memory alloc failed\n"); |
| 1111 | return -ENOMEM; | 1111 | return -ENOMEM; |
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 9c693ae17956..0c5eaf5f4c90 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
| 19 | #include <linux/irqdomain.h> | ||
| 19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 20 | #include <linux/i2c/pca953x.h> | 21 | #include <linux/i2c/pca953x.h> |
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| @@ -83,6 +84,7 @@ struct pca953x_chip { | |||
| 83 | u32 irq_trig_raise; | 84 | u32 irq_trig_raise; |
| 84 | u32 irq_trig_fall; | 85 | u32 irq_trig_fall; |
| 85 | int irq_base; | 86 | int irq_base; |
| 87 | struct irq_domain *domain; | ||
| 86 | #endif | 88 | #endif |
| 87 | 89 | ||
| 88 | struct i2c_client *client; | 90 | struct i2c_client *client; |
| @@ -333,14 +335,14 @@ static void pca953x_irq_mask(struct irq_data *d) | |||
| 333 | { | 335 | { |
| 334 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 336 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 335 | 337 | ||
| 336 | chip->irq_mask &= ~(1 << (d->irq - chip->irq_base)); | 338 | chip->irq_mask &= ~(1 << d->hwirq); |
| 337 | } | 339 | } |
| 338 | 340 | ||
| 339 | static void pca953x_irq_unmask(struct irq_data *d) | 341 | static void pca953x_irq_unmask(struct irq_data *d) |
| 340 | { | 342 | { |
| 341 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 343 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 342 | 344 | ||
| 343 | chip->irq_mask |= 1 << (d->irq - chip->irq_base); | 345 | chip->irq_mask |= 1 << d->hwirq; |
| 344 | } | 346 | } |
| 345 | 347 | ||
| 346 | static void pca953x_irq_bus_lock(struct irq_data *d) | 348 | static void pca953x_irq_bus_lock(struct irq_data *d) |
| @@ -372,8 +374,7 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) | |||
| 372 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) | 374 | static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) |
| 373 | { | 375 | { |
| 374 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); | 376 | struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); |
| 375 | u32 level = d->irq - chip->irq_base; | 377 | u32 mask = 1 << d->hwirq; |
| 376 | u32 mask = 1 << level; | ||
| 377 | 378 | ||
| 378 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { | 379 | if (!(type & IRQ_TYPE_EDGE_BOTH)) { |
| 379 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", | 380 | dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", |
| @@ -454,7 +455,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) | |||
| 454 | 455 | ||
| 455 | do { | 456 | do { |
| 456 | level = __ffs(pending); | 457 | level = __ffs(pending); |
| 457 | handle_nested_irq(level + chip->irq_base); | 458 | handle_nested_irq(irq_find_mapping(chip->domain, level)); |
| 458 | 459 | ||
| 459 | pending &= ~(1 << level); | 460 | pending &= ~(1 << level); |
| 460 | } while (pending); | 461 | } while (pending); |
| @@ -499,6 +500,17 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 499 | if (chip->irq_base < 0) | 500 | if (chip->irq_base < 0) |
| 500 | goto out_failed; | 501 | goto out_failed; |
| 501 | 502 | ||
| 503 | chip->domain = irq_domain_add_legacy(client->dev.of_node, | ||
| 504 | chip->gpio_chip.ngpio, | ||
| 505 | chip->irq_base, | ||
| 506 | 0, | ||
| 507 | &irq_domain_simple_ops, | ||
| 508 | NULL); | ||
| 509 | if (!chip->domain) { | ||
| 510 | ret = -ENODEV; | ||
| 511 | goto out_irqdesc_free; | ||
| 512 | } | ||
| 513 | |||
| 502 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { | 514 | for (lvl = 0; lvl < chip->gpio_chip.ngpio; lvl++) { |
| 503 | int irq = lvl + chip->irq_base; | 515 | int irq = lvl + chip->irq_base; |
| 504 | 516 | ||
| @@ -521,7 +533,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 521 | if (ret) { | 533 | if (ret) { |
| 522 | dev_err(&client->dev, "failed to request irq %d\n", | 534 | dev_err(&client->dev, "failed to request irq %d\n", |
| 523 | client->irq); | 535 | client->irq); |
| 524 | goto out_failed; | 536 | goto out_irqdesc_free; |
| 525 | } | 537 | } |
| 526 | 538 | ||
| 527 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; | 539 | chip->gpio_chip.to_irq = pca953x_gpio_to_irq; |
| @@ -529,6 +541,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, | |||
| 529 | 541 | ||
| 530 | return 0; | 542 | return 0; |
| 531 | 543 | ||
| 544 | out_irqdesc_free: | ||
| 545 | irq_free_descs(chip->irq_base, chip->gpio_chip.ngpio); | ||
| 532 | out_failed: | 546 | out_failed: |
| 533 | chip->irq_base = -1; | 547 | chip->irq_base = -1; |
| 534 | return ret; | 548 | return ret; |
| @@ -751,9 +765,38 @@ static int pca953x_remove(struct i2c_client *client) | |||
| 751 | return 0; | 765 | return 0; |
| 752 | } | 766 | } |
| 753 | 767 | ||
| 768 | static const struct of_device_id pca953x_dt_ids[] = { | ||
| 769 | { .compatible = "nxp,pca9534", }, | ||
| 770 | { .compatible = "nxp,pca9535", }, | ||
| 771 | { .compatible = "nxp,pca9536", }, | ||
| 772 | { .compatible = "nxp,pca9537", }, | ||
| 773 | { .compatible = "nxp,pca9538", }, | ||
| 774 | { .compatible = "nxp,pca9539", }, | ||
| 775 | { .compatible = "nxp,pca9554", }, | ||
| 776 | { .compatible = "nxp,pca9555", }, | ||
| 777 | { .compatible = "nxp,pca9556", }, | ||
| 778 | { .compatible = "nxp,pca9557", }, | ||
| 779 | { .compatible = "nxp,pca9574", }, | ||
| 780 | { .compatible = "nxp,pca9575", }, | ||
| 781 | |||
| 782 | { .compatible = "maxim,max7310", }, | ||
| 783 | { .compatible = "maxim,max7312", }, | ||
| 784 | { .compatible = "maxim,max7313", }, | ||
| 785 | { .compatible = "maxim,max7315", }, | ||
| 786 | |||
| 787 | { .compatible = "ti,pca6107", }, | ||
| 788 | { .compatible = "ti,tca6408", }, | ||
| 789 | { .compatible = "ti,tca6416", }, | ||
| 790 | { .compatible = "ti,tca6424", }, | ||
| 791 | { } | ||
| 792 | }; | ||
| 793 | |||
| 794 | MODULE_DEVICE_TABLE(of, pca953x_dt_ids); | ||
| 795 | |||
| 754 | static struct i2c_driver pca953x_driver = { | 796 | static struct i2c_driver pca953x_driver = { |
| 755 | .driver = { | 797 | .driver = { |
| 756 | .name = "pca953x", | 798 | .name = "pca953x", |
| 799 | .of_match_table = pca953x_dt_ids, | ||
| 757 | }, | 800 | }, |
| 758 | .probe = pca953x_probe, | 801 | .probe = pca953x_probe, |
| 759 | .remove = pca953x_remove, | 802 | .remove = pca953x_remove, |
diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 4ad0c4f9171c..e3a14fef79e1 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c | |||
| @@ -215,6 +215,7 @@ static void pch_gpio_setup(struct pch_gpio *chip) | |||
| 215 | struct gpio_chip *gpio = &chip->gpio; | 215 | struct gpio_chip *gpio = &chip->gpio; |
| 216 | 216 | ||
| 217 | gpio->label = dev_name(chip->dev); | 217 | gpio->label = dev_name(chip->dev); |
| 218 | gpio->dev = chip->dev; | ||
| 218 | gpio->owner = THIS_MODULE; | 219 | gpio->owner = THIS_MODULE; |
| 219 | gpio->direction_input = pch_gpio_direction_input; | 220 | gpio->direction_input = pch_gpio_direction_input; |
| 220 | gpio->get = pch_gpio_get; | 221 | gpio->get = pch_gpio_get; |
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b4b5da4fd2cc..31d9c9e79ea9 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c | |||
| @@ -216,39 +216,34 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base) | |||
| 216 | IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); | 216 | IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | 219 | static int pl061_probe(struct amba_device *adev, const struct amba_id *id) |
| 220 | { | 220 | { |
| 221 | struct pl061_platform_data *pdata; | 221 | struct device *dev = &adev->dev; |
| 222 | struct pl061_platform_data *pdata = dev->platform_data; | ||
| 222 | struct pl061_gpio *chip; | 223 | struct pl061_gpio *chip; |
| 223 | int ret, irq, i; | 224 | int ret, irq, i; |
| 224 | 225 | ||
| 225 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 226 | chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); |
| 226 | if (chip == NULL) | 227 | if (chip == NULL) |
| 227 | return -ENOMEM; | 228 | return -ENOMEM; |
| 228 | 229 | ||
| 229 | pdata = dev->dev.platform_data; | ||
| 230 | if (pdata) { | 230 | if (pdata) { |
| 231 | chip->gc.base = pdata->gpio_base; | 231 | chip->gc.base = pdata->gpio_base; |
| 232 | chip->irq_base = pdata->irq_base; | 232 | chip->irq_base = pdata->irq_base; |
| 233 | } else if (dev->dev.of_node) { | 233 | } else if (adev->dev.of_node) { |
| 234 | chip->gc.base = -1; | 234 | chip->gc.base = -1; |
| 235 | chip->irq_base = 0; | 235 | chip->irq_base = 0; |
| 236 | } else { | 236 | } else |
| 237 | ret = -ENODEV; | 237 | return -ENODEV; |
| 238 | goto free_mem; | ||
| 239 | } | ||
| 240 | 238 | ||
| 241 | if (!request_mem_region(dev->res.start, | 239 | if (!devm_request_mem_region(dev, adev->res.start, |
| 242 | resource_size(&dev->res), "pl061")) { | 240 | resource_size(&adev->res), "pl061")) |
| 243 | ret = -EBUSY; | 241 | return -EBUSY; |
| 244 | goto free_mem; | ||
| 245 | } | ||
| 246 | 242 | ||
| 247 | chip->base = ioremap(dev->res.start, resource_size(&dev->res)); | 243 | chip->base = devm_ioremap(dev, adev->res.start, |
| 248 | if (chip->base == NULL) { | 244 | resource_size(&adev->res)); |
| 249 | ret = -ENOMEM; | 245 | if (chip->base == NULL) |
| 250 | goto release_region; | 246 | return -ENOMEM; |
| 251 | } | ||
| 252 | 247 | ||
| 253 | spin_lock_init(&chip->lock); | 248 | spin_lock_init(&chip->lock); |
| 254 | 249 | ||
| @@ -258,13 +253,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 258 | chip->gc.set = pl061_set_value; | 253 | chip->gc.set = pl061_set_value; |
| 259 | chip->gc.to_irq = pl061_to_irq; | 254 | chip->gc.to_irq = pl061_to_irq; |
| 260 | chip->gc.ngpio = PL061_GPIO_NR; | 255 | chip->gc.ngpio = PL061_GPIO_NR; |
| 261 | chip->gc.label = dev_name(&dev->dev); | 256 | chip->gc.label = dev_name(dev); |
| 262 | chip->gc.dev = &dev->dev; | 257 | chip->gc.dev = dev; |
| 263 | chip->gc.owner = THIS_MODULE; | 258 | chip->gc.owner = THIS_MODULE; |
| 264 | 259 | ||
| 265 | ret = gpiochip_add(&chip->gc); | 260 | ret = gpiochip_add(&chip->gc); |
| 266 | if (ret) | 261 | if (ret) |
| 267 | goto iounmap; | 262 | return ret; |
| 268 | 263 | ||
| 269 | /* | 264 | /* |
| 270 | * irq_chip support | 265 | * irq_chip support |
| @@ -276,11 +271,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 276 | pl061_init_gc(chip, chip->irq_base); | 271 | pl061_init_gc(chip, chip->irq_base); |
| 277 | 272 | ||
| 278 | writeb(0, chip->base + GPIOIE); /* disable irqs */ | 273 | writeb(0, chip->base + GPIOIE); /* disable irqs */ |
| 279 | irq = dev->irq[0]; | 274 | irq = adev->irq[0]; |
| 280 | if (irq < 0) { | 275 | if (irq < 0) |
| 281 | ret = -ENODEV; | 276 | return -ENODEV; |
| 282 | goto iounmap; | 277 | |
| 283 | } | ||
| 284 | irq_set_chained_handler(irq, pl061_irq_handler); | 278 | irq_set_chained_handler(irq, pl061_irq_handler); |
| 285 | irq_set_handler_data(irq, chip); | 279 | irq_set_handler_data(irq, chip); |
| 286 | 280 | ||
| @@ -294,18 +288,9 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
| 294 | } | 288 | } |
| 295 | } | 289 | } |
| 296 | 290 | ||
| 297 | amba_set_drvdata(dev, chip); | 291 | amba_set_drvdata(adev, chip); |
| 298 | 292 | ||
| 299 | return 0; | 293 | return 0; |
| 300 | |||
| 301 | iounmap: | ||
| 302 | iounmap(chip->base); | ||
| 303 | release_region: | ||
| 304 | release_mem_region(dev->res.start, resource_size(&dev->res)); | ||
| 305 | free_mem: | ||
| 306 | kfree(chip); | ||
| 307 | |||
| 308 | return ret; | ||
| 309 | } | 294 | } |
| 310 | 295 | ||
| 311 | #ifdef CONFIG_PM | 296 | #ifdef CONFIG_PM |
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c new file mode 100644 index 000000000000..5f45fc4ed5d1 --- /dev/null +++ b/drivers/gpio/gpio-spear-spics.c | |||
| @@ -0,0 +1,217 @@ | |||
| 1 | /* | ||
| 2 | * SPEAr platform SPI chipselect abstraction over gpiolib | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 ST Microelectronics | ||
| 5 | * Shiraz Hashim <shiraz.hashim@st.com> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/gpio.h> | ||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/of.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/types.h> | ||
| 19 | |||
| 20 | /* maximum chipselects */ | ||
| 21 | #define NUM_OF_GPIO 4 | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Provision is available on some SPEAr SoCs to control ARM PL022 spi cs | ||
| 25 | * through system registers. This register lies outside spi (pl022) | ||
| 26 | * address space into system registers. | ||
| 27 | * | ||
| 28 | * It provides control for spi chip select lines so that any chipselect | ||
| 29 | * (out of 4 possible chipselects in pl022) can be made low to select | ||
| 30 | * the particular slave. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /** | ||
| 34 | * struct spear_spics - represents spi chip select control | ||
| 35 | * @base: base address | ||
| 36 | * @perip_cfg: configuration register | ||
| 37 | * @sw_enable_bit: bit to enable s/w control over chipselects | ||
| 38 | * @cs_value_bit: bit to program high or low chipselect | ||
| 39 | * @cs_enable_mask: mask to select bits required to select chipselect | ||
| 40 | * @cs_enable_shift: bit pos of cs_enable_mask | ||
| 41 | * @use_count: use count of a spi controller cs lines | ||
| 42 | * @last_off: stores last offset caller of set_value() | ||
| 43 | * @chip: gpio_chip abstraction | ||
| 44 | */ | ||
| 45 | struct spear_spics { | ||
| 46 | void __iomem *base; | ||
| 47 | u32 perip_cfg; | ||
| 48 | u32 sw_enable_bit; | ||
| 49 | u32 cs_value_bit; | ||
| 50 | u32 cs_enable_mask; | ||
| 51 | u32 cs_enable_shift; | ||
| 52 | unsigned long use_count; | ||
| 53 | int last_off; | ||
| 54 | struct gpio_chip chip; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* gpio framework specific routines */ | ||
| 58 | static int spics_get_value(struct gpio_chip *chip, unsigned offset) | ||
| 59 | { | ||
| 60 | return -ENXIO; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void spics_set_value(struct gpio_chip *chip, unsigned offset, int value) | ||
| 64 | { | ||
| 65 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
| 66 | chip); | ||
| 67 | u32 tmp; | ||
| 68 | |||
| 69 | /* select chip select from register */ | ||
| 70 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
| 71 | if (spics->last_off != offset) { | ||
| 72 | spics->last_off = offset; | ||
| 73 | tmp &= ~(spics->cs_enable_mask << spics->cs_enable_shift); | ||
| 74 | tmp |= offset << spics->cs_enable_shift; | ||
| 75 | } | ||
| 76 | |||
| 77 | /* toggle chip select line */ | ||
| 78 | tmp &= ~(0x1 << spics->cs_value_bit); | ||
| 79 | tmp |= value << spics->cs_value_bit; | ||
| 80 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
| 81 | } | ||
| 82 | |||
| 83 | static int spics_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 84 | { | ||
| 85 | return -ENXIO; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int spics_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 89 | int value) | ||
| 90 | { | ||
| 91 | spics_set_value(chip, offset, value); | ||
| 92 | return 0; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int spics_request(struct gpio_chip *chip, unsigned offset) | ||
| 96 | { | ||
| 97 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
| 98 | chip); | ||
| 99 | u32 tmp; | ||
| 100 | |||
| 101 | if (!spics->use_count++) { | ||
| 102 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
| 103 | tmp |= 0x1 << spics->sw_enable_bit; | ||
| 104 | tmp |= 0x1 << spics->cs_value_bit; | ||
| 105 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
| 106 | } | ||
| 107 | |||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 111 | static void spics_free(struct gpio_chip *chip, unsigned offset) | ||
| 112 | { | ||
| 113 | struct spear_spics *spics = container_of(chip, struct spear_spics, | ||
| 114 | chip); | ||
| 115 | u32 tmp; | ||
| 116 | |||
| 117 | if (!--spics->use_count) { | ||
| 118 | tmp = readl_relaxed(spics->base + spics->perip_cfg); | ||
| 119 | tmp &= ~(0x1 << spics->sw_enable_bit); | ||
| 120 | writel_relaxed(tmp, spics->base + spics->perip_cfg); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 124 | static int spics_gpio_probe(struct platform_device *pdev) | ||
| 125 | { | ||
| 126 | struct device_node *np = pdev->dev.of_node; | ||
| 127 | struct spear_spics *spics; | ||
| 128 | struct resource *res; | ||
| 129 | int ret; | ||
| 130 | |||
| 131 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 132 | if (!res) { | ||
| 133 | dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); | ||
| 134 | return -EBUSY; | ||
| 135 | } | ||
| 136 | |||
| 137 | spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); | ||
| 138 | if (!spics) { | ||
| 139 | dev_err(&pdev->dev, "memory allocation fail\n"); | ||
| 140 | return -ENOMEM; | ||
| 141 | } | ||
| 142 | |||
| 143 | spics->base = devm_request_and_ioremap(&pdev->dev, res); | ||
| 144 | if (!spics->base) { | ||
| 145 | dev_err(&pdev->dev, "request and ioremap fail\n"); | ||
| 146 | return -ENOMEM; | ||
| 147 | } | ||
| 148 | |||
| 149 | if (of_property_read_u32(np, "st-spics,peripcfg-reg", | ||
| 150 | &spics->perip_cfg)) | ||
| 151 | goto err_dt_data; | ||
| 152 | if (of_property_read_u32(np, "st-spics,sw-enable-bit", | ||
| 153 | &spics->sw_enable_bit)) | ||
| 154 | goto err_dt_data; | ||
| 155 | if (of_property_read_u32(np, "st-spics,cs-value-bit", | ||
| 156 | &spics->cs_value_bit)) | ||
| 157 | goto err_dt_data; | ||
| 158 | if (of_property_read_u32(np, "st-spics,cs-enable-mask", | ||
| 159 | &spics->cs_enable_mask)) | ||
| 160 | goto err_dt_data; | ||
| 161 | if (of_property_read_u32(np, "st-spics,cs-enable-shift", | ||
| 162 | &spics->cs_enable_shift)) | ||
| 163 | goto err_dt_data; | ||
| 164 | |||
| 165 | platform_set_drvdata(pdev, spics); | ||
| 166 | |||
| 167 | spics->chip.ngpio = NUM_OF_GPIO; | ||
| 168 | spics->chip.base = -1; | ||
| 169 | spics->chip.request = spics_request; | ||
| 170 | spics->chip.free = spics_free; | ||
| 171 | spics->chip.direction_input = spics_direction_input; | ||
| 172 | spics->chip.direction_output = spics_direction_output; | ||
| 173 | spics->chip.get = spics_get_value; | ||
| 174 | spics->chip.set = spics_set_value; | ||
| 175 | spics->chip.label = dev_name(&pdev->dev); | ||
| 176 | spics->chip.dev = &pdev->dev; | ||
| 177 | spics->chip.owner = THIS_MODULE; | ||
| 178 | spics->last_off = -1; | ||
| 179 | |||
| 180 | ret = gpiochip_add(&spics->chip); | ||
| 181 | if (ret) { | ||
| 182 | dev_err(&pdev->dev, "unable to add gpio chip\n"); | ||
| 183 | return ret; | ||
| 184 | } | ||
| 185 | |||
| 186 | dev_info(&pdev->dev, "spear spics registered\n"); | ||
| 187 | return 0; | ||
| 188 | |||
| 189 | err_dt_data: | ||
| 190 | dev_err(&pdev->dev, "DT probe failed\n"); | ||
| 191 | return -EINVAL; | ||
| 192 | } | ||
| 193 | |||
| 194 | static const struct of_device_id spics_gpio_of_match[] = { | ||
| 195 | { .compatible = "st,spear-spics-gpio" }, | ||
| 196 | {} | ||
| 197 | }; | ||
| 198 | MODULE_DEVICE_TABLE(of, spics_gpio_of_match); | ||
| 199 | |||
| 200 | static struct platform_driver spics_gpio_driver = { | ||
| 201 | .probe = spics_gpio_probe, | ||
| 202 | .driver = { | ||
| 203 | .owner = THIS_MODULE, | ||
| 204 | .name = "spear-spics-gpio", | ||
| 205 | .of_match_table = spics_gpio_of_match, | ||
| 206 | }, | ||
| 207 | }; | ||
| 208 | |||
| 209 | static int __init spics_gpio_init(void) | ||
| 210 | { | ||
| 211 | return platform_driver_register(&spics_gpio_driver); | ||
| 212 | } | ||
| 213 | subsys_initcall(spics_gpio_init); | ||
| 214 | |||
| 215 | MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>"); | ||
| 216 | MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); | ||
| 217 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1e48317e70fb..8c8447c7d2a8 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c | |||
| @@ -292,17 +292,15 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, | |||
| 292 | { | 292 | { |
| 293 | int base = tc3589x_gpio->irq_base; | 293 | int base = tc3589x_gpio->irq_base; |
| 294 | 294 | ||
| 295 | if (base) { | 295 | /* |
| 296 | tc3589x_gpio->domain = irq_domain_add_legacy( | 296 | * If this results in a linear domain, irq_create_mapping() will |
| 297 | NULL, tc3589x_gpio->chip.ngpio, base, | 297 | * take care of allocating IRQ descriptors at runtime. When a base |
| 298 | 0, &tc3589x_irq_ops, tc3589x_gpio); | 298 | * is provided, the IRQ descriptors will be allocated when the |
| 299 | } | 299 | * domain is instantiated. |
| 300 | else { | 300 | */ |
| 301 | tc3589x_gpio->domain = irq_domain_add_linear( | 301 | tc3589x_gpio->domain = irq_domain_add_simple(np, |
| 302 | np, tc3589x_gpio->chip.ngpio, | 302 | tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops, |
| 303 | &tc3589x_irq_ops, tc3589x_gpio); | 303 | tc3589x_gpio); |
| 304 | } | ||
| 305 | |||
| 306 | if (!tc3589x_gpio->domain) { | 304 | if (!tc3589x_gpio->domain) { |
| 307 | dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); | 305 | dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); |
| 308 | return -ENOSYS; | 306 | return -ENOSYS; |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index d982593d7563..5389be8c2b51 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/irqdomain.h> | 28 | #include <linux/irqdomain.h> |
| 29 | #include <linux/pinctrl/consumer.h> | 29 | #include <linux/pinctrl/consumer.h> |
| 30 | #include <linux/pm.h> | ||
| 30 | 31 | ||
| 31 | #include <asm/mach/irq.h> | 32 | #include <asm/mach/irq.h> |
| 32 | 33 | ||
| @@ -64,7 +65,7 @@ struct tegra_gpio_bank { | |||
| 64 | int bank; | 65 | int bank; |
| 65 | int irq; | 66 | int irq; |
| 66 | spinlock_t lvl_lock[4]; | 67 | spinlock_t lvl_lock[4]; |
| 67 | #ifdef CONFIG_PM | 68 | #ifdef CONFIG_PM_SLEEP |
| 68 | u32 cnf[4]; | 69 | u32 cnf[4]; |
| 69 | u32 out[4]; | 70 | u32 out[4]; |
| 70 | u32 oe[4]; | 71 | u32 oe[4]; |
| @@ -109,20 +110,18 @@ static void tegra_gpio_enable(int gpio) | |||
| 109 | { | 110 | { |
| 110 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); | 111 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1); |
| 111 | } | 112 | } |
| 112 | EXPORT_SYMBOL_GPL(tegra_gpio_enable); | ||
| 113 | 113 | ||
| 114 | static void tegra_gpio_disable(int gpio) | 114 | static void tegra_gpio_disable(int gpio) |
| 115 | { | 115 | { |
| 116 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); | 116 | tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0); |
| 117 | } | 117 | } |
| 118 | EXPORT_SYMBOL_GPL(tegra_gpio_disable); | ||
| 119 | 118 | ||
| 120 | int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) | 119 | static int tegra_gpio_request(struct gpio_chip *chip, unsigned offset) |
| 121 | { | 120 | { |
| 122 | return pinctrl_request_gpio(offset); | 121 | return pinctrl_request_gpio(offset); |
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) | 124 | static void tegra_gpio_free(struct gpio_chip *chip, unsigned offset) |
| 126 | { | 125 | { |
| 127 | pinctrl_free_gpio(offset); | 126 | pinctrl_free_gpio(offset); |
| 128 | tegra_gpio_disable(offset); | 127 | tegra_gpio_disable(offset); |
| @@ -135,6 +134,11 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
| 135 | 134 | ||
| 136 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) | 135 | static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 137 | { | 136 | { |
| 137 | /* If gpio is in output mode then read from the out value */ | ||
| 138 | if ((tegra_gpio_readl(GPIO_OE(offset)) >> GPIO_BIT(offset)) & 1) | ||
| 139 | return (tegra_gpio_readl(GPIO_OUT(offset)) >> | ||
| 140 | GPIO_BIT(offset)) & 0x1; | ||
| 141 | |||
| 138 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; | 142 | return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1; |
| 139 | } | 143 | } |
| 140 | 144 | ||
| @@ -285,8 +289,8 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
| 285 | 289 | ||
| 286 | } | 290 | } |
| 287 | 291 | ||
| 288 | #ifdef CONFIG_PM | 292 | #ifdef CONFIG_PM_SLEEP |
| 289 | void tegra_gpio_resume(void) | 293 | static int tegra_gpio_resume(struct device *dev) |
| 290 | { | 294 | { |
| 291 | unsigned long flags; | 295 | unsigned long flags; |
| 292 | int b; | 296 | int b; |
| @@ -308,9 +312,10 @@ void tegra_gpio_resume(void) | |||
| 308 | } | 312 | } |
| 309 | 313 | ||
| 310 | local_irq_restore(flags); | 314 | local_irq_restore(flags); |
| 315 | return 0; | ||
| 311 | } | 316 | } |
| 312 | 317 | ||
| 313 | void tegra_gpio_suspend(void) | 318 | static int tegra_gpio_suspend(struct device *dev) |
| 314 | { | 319 | { |
| 315 | unsigned long flags; | 320 | unsigned long flags; |
| 316 | int b; | 321 | int b; |
| @@ -330,6 +335,7 @@ void tegra_gpio_suspend(void) | |||
| 330 | } | 335 | } |
| 331 | } | 336 | } |
| 332 | local_irq_restore(flags); | 337 | local_irq_restore(flags); |
| 338 | return 0; | ||
| 333 | } | 339 | } |
| 334 | 340 | ||
| 335 | static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) | 341 | static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable) |
| @@ -345,11 +351,15 @@ static struct irq_chip tegra_gpio_irq_chip = { | |||
| 345 | .irq_mask = tegra_gpio_irq_mask, | 351 | .irq_mask = tegra_gpio_irq_mask, |
| 346 | .irq_unmask = tegra_gpio_irq_unmask, | 352 | .irq_unmask = tegra_gpio_irq_unmask, |
| 347 | .irq_set_type = tegra_gpio_irq_set_type, | 353 | .irq_set_type = tegra_gpio_irq_set_type, |
| 348 | #ifdef CONFIG_PM | 354 | #ifdef CONFIG_PM_SLEEP |
| 349 | .irq_set_wake = tegra_gpio_wake_enable, | 355 | .irq_set_wake = tegra_gpio_wake_enable, |
| 350 | #endif | 356 | #endif |
| 351 | }; | 357 | }; |
| 352 | 358 | ||
| 359 | static const struct dev_pm_ops tegra_gpio_pm_ops = { | ||
| 360 | SET_SYSTEM_SLEEP_PM_OPS(tegra_gpio_suspend, tegra_gpio_resume) | ||
| 361 | }; | ||
| 362 | |||
| 353 | struct tegra_gpio_soc_config { | 363 | struct tegra_gpio_soc_config { |
| 354 | u32 bank_stride; | 364 | u32 bank_stride; |
| 355 | u32 upper_offset; | 365 | u32 upper_offset; |
| @@ -380,7 +390,6 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 380 | { | 390 | { |
| 381 | const struct of_device_id *match; | 391 | const struct of_device_id *match; |
| 382 | struct tegra_gpio_soc_config *config; | 392 | struct tegra_gpio_soc_config *config; |
| 383 | int irq_base; | ||
| 384 | struct resource *res; | 393 | struct resource *res; |
| 385 | struct tegra_gpio_bank *bank; | 394 | struct tegra_gpio_bank *bank; |
| 386 | int gpio; | 395 | int gpio; |
| @@ -417,14 +426,11 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 417 | return -ENODEV; | 426 | return -ENODEV; |
| 418 | } | 427 | } |
| 419 | 428 | ||
| 420 | irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0); | 429 | irq_domain = irq_domain_add_linear(pdev->dev.of_node, |
| 421 | if (irq_base < 0) { | 430 | tegra_gpio_chip.ngpio, |
| 422 | dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n"); | ||
| 423 | return -ENODEV; | ||
| 424 | } | ||
| 425 | irq_domain = irq_domain_add_legacy(pdev->dev.of_node, | ||
| 426 | tegra_gpio_chip.ngpio, irq_base, 0, | ||
| 427 | &irq_domain_simple_ops, NULL); | 431 | &irq_domain_simple_ops, NULL); |
| 432 | if (!irq_domain) | ||
| 433 | return -ENODEV; | ||
| 428 | 434 | ||
| 429 | for (i = 0; i < tegra_gpio_bank_count; i++) { | 435 | for (i = 0; i < tegra_gpio_bank_count; i++) { |
| 430 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); | 436 | res = platform_get_resource(pdev, IORESOURCE_IRQ, i); |
| @@ -464,7 +470,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev) | |||
| 464 | gpiochip_add(&tegra_gpio_chip); | 470 | gpiochip_add(&tegra_gpio_chip); |
| 465 | 471 | ||
| 466 | for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { | 472 | for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) { |
| 467 | int irq = irq_find_mapping(irq_domain, gpio); | 473 | int irq = irq_create_mapping(irq_domain, gpio); |
| 468 | /* No validity check; all Tegra GPIOs are valid IRQs */ | 474 | /* No validity check; all Tegra GPIOs are valid IRQs */ |
| 469 | 475 | ||
| 470 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; | 476 | bank = &tegra_gpio_banks[GPIO_BANK(gpio)]; |
| @@ -493,6 +499,7 @@ static struct platform_driver tegra_gpio_driver = { | |||
| 493 | .driver = { | 499 | .driver = { |
| 494 | .name = "tegra-gpio", | 500 | .name = "tegra-gpio", |
| 495 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
| 502 | .pm = &tegra_gpio_pm_ops, | ||
| 496 | .of_match_table = tegra_gpio_of_match, | 503 | .of_match_table = tegra_gpio_of_match, |
| 497 | }, | 504 | }, |
| 498 | .probe = tegra_gpio_probe, | 505 | .probe = tegra_gpio_probe, |
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c5f8ca233e1f..d2138b0fd4ca 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c | |||
| @@ -88,11 +88,15 @@ static inline int gpio_twl4030_write(u8 address, u8 data) | |||
| 88 | /*----------------------------------------------------------------------*/ | 88 | /*----------------------------------------------------------------------*/ |
| 89 | 89 | ||
| 90 | /* | 90 | /* |
| 91 | * LED register offsets (use TWL4030_MODULE_{LED,PWMA,PWMB})) | 91 | * LED register offsets from TWL_MODULE_LED base |
| 92 | * PWMs A and B are dedicated to LEDs A and B, respectively. | 92 | * PWMs A and B are dedicated to LEDs A and B, respectively. |
| 93 | */ | 93 | */ |
| 94 | 94 | ||
| 95 | #define TWL4030_LED_LEDEN 0x0 | 95 | #define TWL4030_LED_LEDEN_REG 0x00 |
| 96 | #define TWL4030_PWMAON_REG 0x01 | ||
| 97 | #define TWL4030_PWMAOFF_REG 0x02 | ||
| 98 | #define TWL4030_PWMBON_REG 0x03 | ||
| 99 | #define TWL4030_PWMBOFF_REG 0x04 | ||
| 96 | 100 | ||
| 97 | /* LEDEN bits */ | 101 | /* LEDEN bits */ |
| 98 | #define LEDEN_LEDAON BIT(0) | 102 | #define LEDEN_LEDAON BIT(0) |
| @@ -104,9 +108,6 @@ static inline int gpio_twl4030_write(u8 address, u8 data) | |||
| 104 | #define LEDEN_PWM_LENGTHA BIT(6) | 108 | #define LEDEN_PWM_LENGTHA BIT(6) |
| 105 | #define LEDEN_PWM_LENGTHB BIT(7) | 109 | #define LEDEN_PWM_LENGTHB BIT(7) |
| 106 | 110 | ||
| 107 | #define TWL4030_PWMx_PWMxON 0x0 | ||
| 108 | #define TWL4030_PWMx_PWMxOFF 0x1 | ||
| 109 | |||
| 110 | #define PWMxON_LENGTH BIT(7) | 111 | #define PWMxON_LENGTH BIT(7) |
| 111 | 112 | ||
| 112 | /*----------------------------------------------------------------------*/ | 113 | /*----------------------------------------------------------------------*/ |
| @@ -145,7 +146,7 @@ static void twl4030_led_set_value(int led, int value) | |||
| 145 | else | 146 | else |
| 146 | cached_leden |= mask; | 147 | cached_leden |= mask; |
| 147 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, | 148 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, |
| 148 | TWL4030_LED_LEDEN); | 149 | TWL4030_LED_LEDEN_REG); |
| 149 | mutex_unlock(&gpio_lock); | 150 | mutex_unlock(&gpio_lock); |
| 150 | } | 151 | } |
| 151 | 152 | ||
| @@ -216,33 +217,33 @@ static int twl_request(struct gpio_chip *chip, unsigned offset) | |||
| 216 | if (offset >= TWL4030_GPIO_MAX) { | 217 | if (offset >= TWL4030_GPIO_MAX) { |
| 217 | u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT | 218 | u8 ledclr_mask = LEDEN_LEDAON | LEDEN_LEDAEXT |
| 218 | | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; | 219 | | LEDEN_LEDAPWM | LEDEN_PWM_LENGTHA; |
| 219 | u8 module = TWL4030_MODULE_PWMA; | 220 | u8 reg = TWL4030_PWMAON_REG; |
| 220 | 221 | ||
| 221 | offset -= TWL4030_GPIO_MAX; | 222 | offset -= TWL4030_GPIO_MAX; |
| 222 | if (offset) { | 223 | if (offset) { |
| 223 | ledclr_mask <<= 1; | 224 | ledclr_mask <<= 1; |
| 224 | module = TWL4030_MODULE_PWMB; | 225 | reg = TWL4030_PWMBON_REG; |
| 225 | } | 226 | } |
| 226 | 227 | ||
| 227 | /* initialize PWM to always-drive */ | 228 | /* initialize PWM to always-drive */ |
| 228 | status = twl_i2c_write_u8(module, 0x7f, | 229 | /* Configure PWM OFF register first */ |
| 229 | TWL4030_PWMx_PWMxOFF); | 230 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg + 1); |
| 230 | if (status < 0) | 231 | if (status < 0) |
| 231 | goto done; | 232 | goto done; |
| 232 | status = twl_i2c_write_u8(module, 0x7f, | 233 | |
| 233 | TWL4030_PWMx_PWMxON); | 234 | /* Followed by PWM ON register */ |
| 235 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, 0x7f, reg); | ||
| 234 | if (status < 0) | 236 | if (status < 0) |
| 235 | goto done; | 237 | goto done; |
| 236 | 238 | ||
| 237 | /* init LED to not-driven (high) */ | 239 | /* init LED to not-driven (high) */ |
| 238 | module = TWL4030_MODULE_LED; | 240 | status = twl_i2c_read_u8(TWL4030_MODULE_LED, &cached_leden, |
| 239 | status = twl_i2c_read_u8(module, &cached_leden, | 241 | TWL4030_LED_LEDEN_REG); |
| 240 | TWL4030_LED_LEDEN); | ||
| 241 | if (status < 0) | 242 | if (status < 0) |
| 242 | goto done; | 243 | goto done; |
| 243 | cached_leden &= ~ledclr_mask; | 244 | cached_leden &= ~ledclr_mask; |
| 244 | status = twl_i2c_write_u8(module, cached_leden, | 245 | status = twl_i2c_write_u8(TWL4030_MODULE_LED, cached_leden, |
| 245 | TWL4030_LED_LEDEN); | 246 | TWL4030_LED_LEDEN_REG); |
| 246 | if (status < 0) | 247 | if (status < 0) |
| 247 | goto done; | 248 | goto done; |
| 248 | 249 | ||
diff --git a/drivers/gpio/gpio-vt8500.c b/drivers/gpio/gpio-vt8500.c index bcd8e4aa7c7d..9ed2a2b347fa 100644 --- a/drivers/gpio/gpio-vt8500.c +++ b/drivers/gpio/gpio-vt8500.c | |||
| @@ -96,6 +96,7 @@ static struct vt8500_gpio_data wm8505_data = { | |||
| 96 | VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), | 96 | VT8500_BANK(0x5C, 0x84, 0xAC, 0xD4, 12), |
| 97 | VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), | 97 | VT8500_BANK(0x60, 0x88, 0xB0, 0xD8, 16), |
| 98 | VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), | 98 | VT8500_BANK(0x64, 0x8C, 0xB4, 0xDC, 22), |
| 99 | VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), | ||
| 99 | }, | 100 | }, |
| 100 | }; | 101 | }; |
| 101 | 102 | ||
| @@ -115,6 +116,7 @@ static struct vt8500_gpio_data wm8650_data = { | |||
| 115 | VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), | 116 | VT8500_BANK(0x58, 0x98, 0xD8, 0x18, 32), |
| 116 | VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), | 117 | VT8500_BANK(0x5C, 0x9C, 0xDC, 0x1C, 32), |
| 117 | VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), | 118 | VT8500_BANK(0x7C, 0xBC, 0xFC, 0x3C, 32), |
| 119 | VT8500_BANK(0x500, 0x504, 0x508, 0x50C, 6), | ||
| 118 | }, | 120 | }, |
| 119 | }; | 121 | }; |
| 120 | 122 | ||
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index f1a45997aea8..a40cd84c5c10 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
| 21 | #include <linux/of_gpio.h> | 21 | #include <linux/of_gpio.h> |
| 22 | #include <linux/pinctrl/pinctrl.h> | ||
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 23 | 24 | ||
| 24 | /* Private data structure for of_gpiochip_find_and_xlate */ | 25 | /* Private data structure for of_gpiochip_find_and_xlate */ |
| @@ -216,6 +217,42 @@ err0: | |||
| 216 | } | 217 | } |
| 217 | EXPORT_SYMBOL(of_mm_gpiochip_add); | 218 | EXPORT_SYMBOL(of_mm_gpiochip_add); |
| 218 | 219 | ||
| 220 | #ifdef CONFIG_PINCTRL | ||
| 221 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) | ||
| 222 | { | ||
| 223 | struct device_node *np = chip->of_node; | ||
| 224 | struct of_phandle_args pinspec; | ||
| 225 | struct pinctrl_dev *pctldev; | ||
| 226 | int index = 0, ret; | ||
| 227 | |||
| 228 | if (!np) | ||
| 229 | return; | ||
| 230 | |||
| 231 | do { | ||
| 232 | ret = of_parse_phandle_with_args(np, "gpio-ranges", | ||
| 233 | "#gpio-range-cells", index, &pinspec); | ||
| 234 | if (ret) | ||
| 235 | break; | ||
| 236 | |||
| 237 | pctldev = of_pinctrl_get(pinspec.np); | ||
| 238 | if (!pctldev) | ||
| 239 | break; | ||
| 240 | |||
| 241 | ret = gpiochip_add_pin_range(chip, | ||
| 242 | pinctrl_dev_get_name(pctldev), | ||
| 243 | pinspec.args[0], | ||
| 244 | pinspec.args[1]); | ||
| 245 | |||
| 246 | if (ret) | ||
| 247 | break; | ||
| 248 | |||
| 249 | } while (index++); | ||
| 250 | } | ||
| 251 | |||
| 252 | #else | ||
| 253 | static void of_gpiochip_add_pin_range(struct gpio_chip *chip) {} | ||
| 254 | #endif | ||
| 255 | |||
| 219 | void of_gpiochip_add(struct gpio_chip *chip) | 256 | void of_gpiochip_add(struct gpio_chip *chip) |
| 220 | { | 257 | { |
| 221 | if ((!chip->of_node) && (chip->dev)) | 258 | if ((!chip->of_node) && (chip->dev)) |
| @@ -229,11 +266,14 @@ void of_gpiochip_add(struct gpio_chip *chip) | |||
| 229 | chip->of_xlate = of_gpio_simple_xlate; | 266 | chip->of_xlate = of_gpio_simple_xlate; |
| 230 | } | 267 | } |
| 231 | 268 | ||
| 269 | of_gpiochip_add_pin_range(chip); | ||
| 232 | of_node_get(chip->of_node); | 270 | of_node_get(chip->of_node); |
| 233 | } | 271 | } |
| 234 | 272 | ||
| 235 | void of_gpiochip_remove(struct gpio_chip *chip) | 273 | void of_gpiochip_remove(struct gpio_chip *chip) |
| 236 | { | 274 | { |
| 275 | gpiochip_remove_pin_ranges(chip); | ||
| 276 | |||
| 237 | if (chip->of_node) | 277 | if (chip->of_node) |
| 238 | of_node_put(chip->of_node); | 278 | of_node_put(chip->of_node); |
| 239 | } | 279 | } |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1c8d9e3380e1..b667f768c23b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
| @@ -191,6 +191,32 @@ err: | |||
| 191 | return ret; | 191 | return ret; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | /* caller ensures gpio is valid and requested, chip->get_direction may sleep */ | ||
| 195 | static int gpio_get_direction(unsigned gpio) | ||
| 196 | { | ||
| 197 | struct gpio_chip *chip; | ||
| 198 | struct gpio_desc *desc = &gpio_desc[gpio]; | ||
| 199 | int status = -EINVAL; | ||
| 200 | |||
| 201 | chip = gpio_to_chip(gpio); | ||
| 202 | gpio -= chip->base; | ||
| 203 | |||
| 204 | if (!chip->get_direction) | ||
| 205 | return status; | ||
| 206 | |||
| 207 | status = chip->get_direction(chip, gpio); | ||
| 208 | if (status > 0) { | ||
| 209 | /* GPIOF_DIR_IN, or other positive */ | ||
| 210 | status = 1; | ||
| 211 | clear_bit(FLAG_IS_OUT, &desc->flags); | ||
| 212 | } | ||
| 213 | if (status == 0) { | ||
| 214 | /* GPIOF_DIR_OUT */ | ||
| 215 | set_bit(FLAG_IS_OUT, &desc->flags); | ||
| 216 | } | ||
| 217 | return status; | ||
| 218 | } | ||
| 219 | |||
| 194 | #ifdef CONFIG_GPIO_SYSFS | 220 | #ifdef CONFIG_GPIO_SYSFS |
| 195 | 221 | ||
| 196 | /* lock protects against unexport_gpio() being called while | 222 | /* lock protects against unexport_gpio() being called while |
| @@ -223,6 +249,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
| 223 | struct device_attribute *attr, char *buf) | 249 | struct device_attribute *attr, char *buf) |
| 224 | { | 250 | { |
| 225 | const struct gpio_desc *desc = dev_get_drvdata(dev); | 251 | const struct gpio_desc *desc = dev_get_drvdata(dev); |
| 252 | unsigned gpio = desc - gpio_desc; | ||
| 226 | ssize_t status; | 253 | ssize_t status; |
| 227 | 254 | ||
| 228 | mutex_lock(&sysfs_lock); | 255 | mutex_lock(&sysfs_lock); |
| @@ -230,6 +257,7 @@ static ssize_t gpio_direction_show(struct device *dev, | |||
| 230 | if (!test_bit(FLAG_EXPORT, &desc->flags)) | 257 | if (!test_bit(FLAG_EXPORT, &desc->flags)) |
| 231 | status = -EIO; | 258 | status = -EIO; |
| 232 | else | 259 | else |
| 260 | gpio_get_direction(gpio); | ||
| 233 | status = sprintf(buf, "%s\n", | 261 | status = sprintf(buf, "%s\n", |
| 234 | test_bit(FLAG_IS_OUT, &desc->flags) | 262 | test_bit(FLAG_IS_OUT, &desc->flags) |
| 235 | ? "out" : "in"); | 263 | ? "out" : "in"); |
| @@ -704,8 +732,9 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
| 704 | { | 732 | { |
| 705 | unsigned long flags; | 733 | unsigned long flags; |
| 706 | struct gpio_desc *desc; | 734 | struct gpio_desc *desc; |
| 707 | int status = -EINVAL; | 735 | int status; |
| 708 | const char *ioname = NULL; | 736 | const char *ioname = NULL; |
| 737 | struct device *dev; | ||
| 709 | 738 | ||
| 710 | /* can't export until sysfs is available ... */ | 739 | /* can't export until sysfs is available ... */ |
| 711 | if (!gpio_class.p) { | 740 | if (!gpio_class.p) { |
| @@ -713,59 +742,66 @@ int gpio_export(unsigned gpio, bool direction_may_change) | |||
| 713 | return -ENOENT; | 742 | return -ENOENT; |
| 714 | } | 743 | } |
| 715 | 744 | ||
| 716 | if (!gpio_is_valid(gpio)) | 745 | if (!gpio_is_valid(gpio)) { |
| 717 | goto done; | 746 | pr_debug("%s: gpio %d is not valid\n", __func__, gpio); |
| 747 | return -EINVAL; | ||
| 748 | } | ||
| 718 | 749 | ||
| 719 | mutex_lock(&sysfs_lock); | 750 | mutex_lock(&sysfs_lock); |
| 720 | 751 | ||
| 721 | spin_lock_irqsave(&gpio_lock, flags); | 752 | spin_lock_irqsave(&gpio_lock, flags); |
| 722 | desc = &gpio_desc[gpio]; | 753 | desc = &gpio_desc[gpio]; |
| 723 | if (test_bit(FLAG_REQUESTED, &desc->flags) | 754 | if (!test_bit(FLAG_REQUESTED, &desc->flags) || |
| 724 | && !test_bit(FLAG_EXPORT, &desc->flags)) { | 755 | test_bit(FLAG_EXPORT, &desc->flags)) { |
| 725 | status = 0; | 756 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 726 | if (!desc->chip->direction_input | 757 | pr_debug("%s: gpio %d unavailable (requested=%d, exported=%d)\n", |
| 727 | || !desc->chip->direction_output) | 758 | __func__, gpio, |
| 728 | direction_may_change = false; | 759 | test_bit(FLAG_REQUESTED, &desc->flags), |
| 760 | test_bit(FLAG_EXPORT, &desc->flags)); | ||
| 761 | status = -EPERM; | ||
| 762 | goto fail_unlock; | ||
| 729 | } | 763 | } |
| 764 | |||
| 765 | if (!desc->chip->direction_input || !desc->chip->direction_output) | ||
| 766 | direction_may_change = false; | ||
| 730 | spin_unlock_irqrestore(&gpio_lock, flags); | 767 | spin_unlock_irqrestore(&gpio_lock, flags); |
| 731 | 768 | ||
| 732 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) | 769 | if (desc->chip->names && desc->chip->names[gpio - desc->chip->base]) |
| 733 | ioname = desc->chip->names[gpio - desc->chip->base]; | 770 | ioname = desc->chip->names[gpio - desc->chip->base]; |
| 734 | 771 | ||
| 735 | if (status == 0) { | 772 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), |
| 736 | struct device *dev; | 773 | desc, ioname ? ioname : "gpio%u", gpio); |
| 737 | 774 | if (IS_ERR(dev)) { | |
| 738 | dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0), | 775 | status = PTR_ERR(dev); |
| 739 | desc, ioname ? ioname : "gpio%u", gpio); | 776 | goto fail_unlock; |
| 740 | if (!IS_ERR(dev)) { | ||
| 741 | status = sysfs_create_group(&dev->kobj, | ||
| 742 | &gpio_attr_group); | ||
| 743 | |||
| 744 | if (!status && direction_may_change) | ||
| 745 | status = device_create_file(dev, | ||
| 746 | &dev_attr_direction); | ||
| 747 | |||
| 748 | if (!status && gpio_to_irq(gpio) >= 0 | ||
| 749 | && (direction_may_change | ||
| 750 | || !test_bit(FLAG_IS_OUT, | ||
| 751 | &desc->flags))) | ||
| 752 | status = device_create_file(dev, | ||
| 753 | &dev_attr_edge); | ||
| 754 | |||
| 755 | if (status != 0) | ||
| 756 | device_unregister(dev); | ||
| 757 | } else | ||
| 758 | status = PTR_ERR(dev); | ||
| 759 | if (status == 0) | ||
| 760 | set_bit(FLAG_EXPORT, &desc->flags); | ||
| 761 | } | 777 | } |
| 762 | 778 | ||
| 763 | mutex_unlock(&sysfs_lock); | 779 | status = sysfs_create_group(&dev->kobj, &gpio_attr_group); |
| 764 | |||
| 765 | done: | ||
| 766 | if (status) | 780 | if (status) |
| 767 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | 781 | goto fail_unregister_device; |
| 768 | 782 | ||
| 783 | if (direction_may_change) { | ||
| 784 | status = device_create_file(dev, &dev_attr_direction); | ||
| 785 | if (status) | ||
| 786 | goto fail_unregister_device; | ||
| 787 | } | ||
| 788 | |||
| 789 | if (gpio_to_irq(gpio) >= 0 && (direction_may_change || | ||
| 790 | !test_bit(FLAG_IS_OUT, &desc->flags))) { | ||
| 791 | status = device_create_file(dev, &dev_attr_edge); | ||
| 792 | if (status) | ||
| 793 | goto fail_unregister_device; | ||
| 794 | } | ||
| 795 | |||
| 796 | set_bit(FLAG_EXPORT, &desc->flags); | ||
| 797 | mutex_unlock(&sysfs_lock); | ||
| 798 | return 0; | ||
| 799 | |||
| 800 | fail_unregister_device: | ||
| 801 | device_unregister(dev); | ||
| 802 | fail_unlock: | ||
| 803 | mutex_unlock(&sysfs_lock); | ||
| 804 | pr_debug("%s: gpio%d status %d\n", __func__, gpio, status); | ||
| 769 | return status; | 805 | return status; |
| 770 | } | 806 | } |
| 771 | EXPORT_SYMBOL_GPL(gpio_export); | 807 | EXPORT_SYMBOL_GPL(gpio_export); |
| @@ -1075,6 +1111,7 @@ int gpiochip_add(struct gpio_chip *chip) | |||
| 1075 | * inputs (often with pullups enabled) so power | 1111 | * inputs (often with pullups enabled) so power |
| 1076 | * usage is minimized. Linux code should set the | 1112 | * usage is minimized. Linux code should set the |
| 1077 | * gpio direction first thing; but until it does, | 1113 | * gpio direction first thing; but until it does, |
| 1114 | * and in case chip->get_direction is not set, | ||
| 1078 | * we may expose the wrong direction in sysfs. | 1115 | * we may expose the wrong direction in sysfs. |
| 1079 | */ | 1116 | */ |
| 1080 | gpio_desc[id].flags = !chip->direction_input | 1117 | gpio_desc[id].flags = !chip->direction_input |
| @@ -1083,6 +1120,10 @@ int gpiochip_add(struct gpio_chip *chip) | |||
| 1083 | } | 1120 | } |
| 1084 | } | 1121 | } |
| 1085 | 1122 | ||
| 1123 | #ifdef CONFIG_PINCTRL | ||
| 1124 | INIT_LIST_HEAD(&chip->pin_ranges); | ||
| 1125 | #endif | ||
| 1126 | |||
| 1086 | of_gpiochip_add(chip); | 1127 | of_gpiochip_add(chip); |
| 1087 | 1128 | ||
| 1088 | unlock: | 1129 | unlock: |
| @@ -1123,6 +1164,7 @@ int gpiochip_remove(struct gpio_chip *chip) | |||
| 1123 | 1164 | ||
| 1124 | spin_lock_irqsave(&gpio_lock, flags); | 1165 | spin_lock_irqsave(&gpio_lock, flags); |
| 1125 | 1166 | ||
| 1167 | gpiochip_remove_pin_ranges(chip); | ||
| 1126 | of_gpiochip_remove(chip); | 1168 | of_gpiochip_remove(chip); |
| 1127 | 1169 | ||
| 1128 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { | 1170 | for (id = chip->base; id < chip->base + chip->ngpio; id++) { |
| @@ -1180,6 +1222,47 @@ struct gpio_chip *gpiochip_find(void *data, | |||
| 1180 | } | 1222 | } |
| 1181 | EXPORT_SYMBOL_GPL(gpiochip_find); | 1223 | EXPORT_SYMBOL_GPL(gpiochip_find); |
| 1182 | 1224 | ||
| 1225 | #ifdef CONFIG_PINCTRL | ||
| 1226 | |||
| 1227 | int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
| 1228 | unsigned int pin_base, unsigned int npins) | ||
| 1229 | { | ||
| 1230 | struct gpio_pin_range *pin_range; | ||
| 1231 | |||
| 1232 | pin_range = devm_kzalloc(chip->dev, sizeof(*pin_range), GFP_KERNEL); | ||
| 1233 | if (!pin_range) { | ||
| 1234 | pr_err("%s: GPIO chip: failed to allocate pin ranges\n", | ||
| 1235 | chip->label); | ||
| 1236 | return -ENOMEM; | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | pin_range->range.name = chip->label; | ||
| 1240 | pin_range->range.base = chip->base; | ||
| 1241 | pin_range->range.pin_base = pin_base; | ||
| 1242 | pin_range->range.npins = npins; | ||
| 1243 | pin_range->pctldev = find_pinctrl_and_add_gpio_range(pinctl_name, | ||
| 1244 | &pin_range->range); | ||
| 1245 | |||
| 1246 | list_add_tail(&pin_range->node, &chip->pin_ranges); | ||
| 1247 | |||
| 1248 | return 0; | ||
| 1249 | } | ||
| 1250 | EXPORT_SYMBOL_GPL(gpiochip_add_pin_range); | ||
| 1251 | |||
| 1252 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip) | ||
| 1253 | { | ||
| 1254 | struct gpio_pin_range *pin_range, *tmp; | ||
| 1255 | |||
| 1256 | list_for_each_entry_safe(pin_range, tmp, &chip->pin_ranges, node) { | ||
| 1257 | list_del(&pin_range->node); | ||
| 1258 | pinctrl_remove_gpio_range(pin_range->pctldev, | ||
| 1259 | &pin_range->range); | ||
| 1260 | } | ||
| 1261 | } | ||
| 1262 | EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges); | ||
| 1263 | |||
| 1264 | #endif /* CONFIG_PINCTRL */ | ||
| 1265 | |||
| 1183 | /* These "optional" allocation calls help prevent drivers from stomping | 1266 | /* These "optional" allocation calls help prevent drivers from stomping |
| 1184 | * on each other, and help provide better diagnostics in debugfs. | 1267 | * on each other, and help provide better diagnostics in debugfs. |
| 1185 | * They're called even less than the "set direction" calls. | 1268 | * They're called even less than the "set direction" calls. |
| @@ -1228,9 +1311,15 @@ int gpio_request(unsigned gpio, const char *label) | |||
| 1228 | desc_set_label(desc, NULL); | 1311 | desc_set_label(desc, NULL); |
| 1229 | module_put(chip->owner); | 1312 | module_put(chip->owner); |
| 1230 | clear_bit(FLAG_REQUESTED, &desc->flags); | 1313 | clear_bit(FLAG_REQUESTED, &desc->flags); |
| 1314 | goto done; | ||
| 1231 | } | 1315 | } |
| 1232 | } | 1316 | } |
| 1233 | 1317 | if (chip->get_direction) { | |
| 1318 | /* chip->get_direction may sleep */ | ||
| 1319 | spin_unlock_irqrestore(&gpio_lock, flags); | ||
| 1320 | gpio_get_direction(gpio); | ||
| 1321 | spin_lock_irqsave(&gpio_lock, flags); | ||
| 1322 | } | ||
| 1234 | done: | 1323 | done: |
| 1235 | if (status) | 1324 | if (status) |
| 1236 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", | 1325 | pr_debug("gpio_request: gpio-%d (%s) status %d\n", |
| @@ -1766,6 +1855,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
| 1766 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) | 1855 | if (!test_bit(FLAG_REQUESTED, &gdesc->flags)) |
| 1767 | continue; | 1856 | continue; |
| 1768 | 1857 | ||
| 1858 | gpio_get_direction(gpio); | ||
| 1769 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); | 1859 | is_out = test_bit(FLAG_IS_OUT, &gdesc->flags); |
| 1770 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", | 1860 | seq_printf(s, " gpio-%-3d (%-20.20s) %s %s", |
| 1771 | gpio, gdesc->label, | 1861 | gpio, gdesc->label, |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 054321db4350..bf7b43696cdb 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
| @@ -1 +1,2 @@ | |||
| 1 | obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o | 1 | obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o |
| 2 | obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o | ||
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c new file mode 100644 index 000000000000..80e1d2fd9d4c --- /dev/null +++ b/drivers/irqchip/spear-shirq.c | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * SPEAr platform shared irq layer source file | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009-2012 ST Microelectronics | ||
| 5 | * Viresh Kumar <viresh.linux@gmail.com> | ||
| 6 | * | ||
| 7 | * Copyright (C) 2012 ST Microelectronics | ||
| 8 | * Shiraz Hashim <shiraz.hashim@st.com> | ||
| 9 | * | ||
| 10 | * This file is licensed under the terms of the GNU General Public | ||
| 11 | * License version 2. This program is licensed "as is" without any | ||
| 12 | * warranty of any kind, whether express or implied. | ||
| 13 | */ | ||
| 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 15 | |||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/export.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/io.h> | ||
| 20 | #include <linux/irq.h> | ||
| 21 | #include <linux/irqdomain.h> | ||
| 22 | #include <linux/irqchip/spear-shirq.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_address.h> | ||
| 25 | #include <linux/of_irq.h> | ||
| 26 | #include <linux/spinlock.h> | ||
| 27 | |||
| 28 | static DEFINE_SPINLOCK(lock); | ||
| 29 | |||
| 30 | /* spear300 shared irq registers offsets and masks */ | ||
| 31 | #define SPEAR300_INT_ENB_MASK_REG 0x54 | ||
| 32 | #define SPEAR300_INT_STS_MASK_REG 0x58 | ||
| 33 | |||
| 34 | static struct spear_shirq spear300_shirq_ras1 = { | ||
| 35 | .irq_nr = 9, | ||
| 36 | .irq_bit_off = 0, | ||
| 37 | .regs = { | ||
| 38 | .enb_reg = SPEAR300_INT_ENB_MASK_REG, | ||
| 39 | .status_reg = SPEAR300_INT_STS_MASK_REG, | ||
| 40 | .clear_reg = -1, | ||
| 41 | }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct spear_shirq *spear300_shirq_blocks[] = { | ||
| 45 | &spear300_shirq_ras1, | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* spear310 shared irq registers offsets and masks */ | ||
| 49 | #define SPEAR310_INT_STS_MASK_REG 0x04 | ||
| 50 | |||
| 51 | static struct spear_shirq spear310_shirq_ras1 = { | ||
| 52 | .irq_nr = 8, | ||
| 53 | .irq_bit_off = 0, | ||
| 54 | .regs = { | ||
| 55 | .enb_reg = -1, | ||
| 56 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 57 | .clear_reg = -1, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct spear_shirq spear310_shirq_ras2 = { | ||
| 62 | .irq_nr = 5, | ||
| 63 | .irq_bit_off = 8, | ||
| 64 | .regs = { | ||
| 65 | .enb_reg = -1, | ||
| 66 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 67 | .clear_reg = -1, | ||
| 68 | }, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static struct spear_shirq spear310_shirq_ras3 = { | ||
| 72 | .irq_nr = 1, | ||
| 73 | .irq_bit_off = 13, | ||
| 74 | .regs = { | ||
| 75 | .enb_reg = -1, | ||
| 76 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 77 | .clear_reg = -1, | ||
| 78 | }, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static struct spear_shirq spear310_shirq_intrcomm_ras = { | ||
| 82 | .irq_nr = 3, | ||
| 83 | .irq_bit_off = 14, | ||
| 84 | .regs = { | ||
| 85 | .enb_reg = -1, | ||
| 86 | .status_reg = SPEAR310_INT_STS_MASK_REG, | ||
| 87 | .clear_reg = -1, | ||
| 88 | }, | ||
| 89 | }; | ||
| 90 | |||
| 91 | static struct spear_shirq *spear310_shirq_blocks[] = { | ||
| 92 | &spear310_shirq_ras1, | ||
| 93 | &spear310_shirq_ras2, | ||
| 94 | &spear310_shirq_ras3, | ||
| 95 | &spear310_shirq_intrcomm_ras, | ||
| 96 | }; | ||
| 97 | |||
| 98 | /* spear320 shared irq registers offsets and masks */ | ||
| 99 | #define SPEAR320_INT_STS_MASK_REG 0x04 | ||
| 100 | #define SPEAR320_INT_CLR_MASK_REG 0x04 | ||
| 101 | #define SPEAR320_INT_ENB_MASK_REG 0x08 | ||
| 102 | |||
| 103 | static struct spear_shirq spear320_shirq_ras1 = { | ||
| 104 | .irq_nr = 3, | ||
| 105 | .irq_bit_off = 7, | ||
| 106 | .regs = { | ||
| 107 | .enb_reg = -1, | ||
| 108 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 109 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 110 | .reset_to_clear = 1, | ||
| 111 | }, | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct spear_shirq spear320_shirq_ras2 = { | ||
| 115 | .irq_nr = 1, | ||
| 116 | .irq_bit_off = 10, | ||
| 117 | .regs = { | ||
| 118 | .enb_reg = -1, | ||
| 119 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 120 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 121 | .reset_to_clear = 1, | ||
| 122 | }, | ||
| 123 | }; | ||
| 124 | |||
| 125 | static struct spear_shirq spear320_shirq_ras3 = { | ||
| 126 | .irq_nr = 3, | ||
| 127 | .irq_bit_off = 0, | ||
| 128 | .invalid_irq = 1, | ||
| 129 | .regs = { | ||
| 130 | .enb_reg = SPEAR320_INT_ENB_MASK_REG, | ||
| 131 | .reset_to_enb = 1, | ||
| 132 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 133 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 134 | .reset_to_clear = 1, | ||
| 135 | }, | ||
| 136 | }; | ||
| 137 | |||
| 138 | static struct spear_shirq spear320_shirq_intrcomm_ras = { | ||
| 139 | .irq_nr = 11, | ||
| 140 | .irq_bit_off = 11, | ||
| 141 | .regs = { | ||
| 142 | .enb_reg = -1, | ||
| 143 | .status_reg = SPEAR320_INT_STS_MASK_REG, | ||
| 144 | .clear_reg = SPEAR320_INT_CLR_MASK_REG, | ||
| 145 | .reset_to_clear = 1, | ||
| 146 | }, | ||
| 147 | }; | ||
| 148 | |||
| 149 | static struct spear_shirq *spear320_shirq_blocks[] = { | ||
| 150 | &spear320_shirq_ras3, | ||
| 151 | &spear320_shirq_ras1, | ||
| 152 | &spear320_shirq_ras2, | ||
| 153 | &spear320_shirq_intrcomm_ras, | ||
| 154 | }; | ||
| 155 | |||
| 156 | static void shirq_irq_mask_unmask(struct irq_data *d, bool mask) | ||
| 157 | { | ||
| 158 | struct spear_shirq *shirq = irq_data_get_irq_chip_data(d); | ||
| 159 | u32 val, offset = d->irq - shirq->irq_base; | ||
| 160 | unsigned long flags; | ||
| 161 | |||
| 162 | if (shirq->regs.enb_reg == -1) | ||
| 163 | return; | ||
| 164 | |||
| 165 | spin_lock_irqsave(&lock, flags); | ||
| 166 | val = readl(shirq->base + shirq->regs.enb_reg); | ||
| 167 | |||
| 168 | if (mask ^ shirq->regs.reset_to_enb) | ||
| 169 | val &= ~(0x1 << shirq->irq_bit_off << offset); | ||
| 170 | else | ||
| 171 | val |= 0x1 << shirq->irq_bit_off << offset; | ||
| 172 | |||
| 173 | writel(val, shirq->base + shirq->regs.enb_reg); | ||
| 174 | spin_unlock_irqrestore(&lock, flags); | ||
| 175 | |||
| 176 | } | ||
| 177 | |||
| 178 | static void shirq_irq_mask(struct irq_data *d) | ||
| 179 | { | ||
| 180 | shirq_irq_mask_unmask(d, 1); | ||
| 181 | } | ||
| 182 | |||
| 183 | static void shirq_irq_unmask(struct irq_data *d) | ||
| 184 | { | ||
| 185 | shirq_irq_mask_unmask(d, 0); | ||
| 186 | } | ||
| 187 | |||
| 188 | static struct irq_chip shirq_chip = { | ||
| 189 | .name = "spear-shirq", | ||
| 190 | .irq_ack = shirq_irq_mask, | ||
| 191 | .irq_mask = shirq_irq_mask, | ||
| 192 | .irq_unmask = shirq_irq_unmask, | ||
| 193 | }; | ||
| 194 | |||
| 195 | static void shirq_handler(unsigned irq, struct irq_desc *desc) | ||
| 196 | { | ||
| 197 | u32 i, j, val, mask, tmp; | ||
| 198 | struct irq_chip *chip; | ||
| 199 | struct spear_shirq *shirq = irq_get_handler_data(irq); | ||
| 200 | |||
| 201 | chip = irq_get_chip(irq); | ||
| 202 | chip->irq_ack(&desc->irq_data); | ||
| 203 | |||
| 204 | mask = ((0x1 << shirq->irq_nr) - 1) << shirq->irq_bit_off; | ||
| 205 | while ((val = readl(shirq->base + shirq->regs.status_reg) & | ||
| 206 | mask)) { | ||
| 207 | |||
| 208 | val >>= shirq->irq_bit_off; | ||
| 209 | for (i = 0, j = 1; i < shirq->irq_nr; i++, j <<= 1) { | ||
| 210 | |||
| 211 | if (!(j & val)) | ||
| 212 | continue; | ||
| 213 | |||
| 214 | generic_handle_irq(shirq->irq_base + i); | ||
| 215 | |||
| 216 | /* clear interrupt */ | ||
| 217 | if (shirq->regs.clear_reg == -1) | ||
| 218 | continue; | ||
| 219 | |||
| 220 | tmp = readl(shirq->base + shirq->regs.clear_reg); | ||
| 221 | if (shirq->regs.reset_to_clear) | ||
| 222 | tmp &= ~(j << shirq->irq_bit_off); | ||
| 223 | else | ||
| 224 | tmp |= (j << shirq->irq_bit_off); | ||
| 225 | writel(tmp, shirq->base + shirq->regs.clear_reg); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | chip->irq_unmask(&desc->irq_data); | ||
| 229 | } | ||
| 230 | |||
| 231 | static void __init spear_shirq_register(struct spear_shirq *shirq) | ||
| 232 | { | ||
| 233 | int i; | ||
| 234 | |||
| 235 | if (shirq->invalid_irq) | ||
| 236 | return; | ||
| 237 | |||
| 238 | irq_set_chained_handler(shirq->irq, shirq_handler); | ||
| 239 | for (i = 0; i < shirq->irq_nr; i++) { | ||
| 240 | irq_set_chip_and_handler(shirq->irq_base + i, | ||
| 241 | &shirq_chip, handle_simple_irq); | ||
| 242 | set_irq_flags(shirq->irq_base + i, IRQF_VALID); | ||
| 243 | irq_set_chip_data(shirq->irq_base + i, shirq); | ||
| 244 | } | ||
| 245 | |||
| 246 | irq_set_handler_data(shirq->irq, shirq); | ||
| 247 | } | ||
| 248 | |||
| 249 | static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr, | ||
| 250 | struct device_node *np) | ||
| 251 | { | ||
| 252 | int i, irq_base, hwirq = 0, irq_nr = 0; | ||
| 253 | static struct irq_domain *shirq_domain; | ||
| 254 | void __iomem *base; | ||
| 255 | |||
| 256 | base = of_iomap(np, 0); | ||
| 257 | if (!base) { | ||
| 258 | pr_err("%s: failed to map shirq registers\n", __func__); | ||
| 259 | return -ENXIO; | ||
| 260 | } | ||
| 261 | |||
| 262 | for (i = 0; i < block_nr; i++) | ||
| 263 | irq_nr += shirq_blocks[i]->irq_nr; | ||
| 264 | |||
| 265 | irq_base = irq_alloc_descs(-1, 0, irq_nr, 0); | ||
| 266 | if (IS_ERR_VALUE(irq_base)) { | ||
| 267 | pr_err("%s: irq desc alloc failed\n", __func__); | ||
| 268 | goto err_unmap; | ||
| 269 | } | ||
| 270 | |||
| 271 | shirq_domain = irq_domain_add_legacy(np, irq_nr, irq_base, 0, | ||
| 272 | &irq_domain_simple_ops, NULL); | ||
| 273 | if (WARN_ON(!shirq_domain)) { | ||
| 274 | pr_warn("%s: irq domain init failed\n", __func__); | ||
| 275 | goto err_free_desc; | ||
| 276 | } | ||
| 277 | |||
| 278 | for (i = 0; i < block_nr; i++) { | ||
| 279 | shirq_blocks[i]->base = base; | ||
| 280 | shirq_blocks[i]->irq_base = irq_find_mapping(shirq_domain, | ||
| 281 | hwirq); | ||
| 282 | shirq_blocks[i]->irq = irq_of_parse_and_map(np, i); | ||
| 283 | |||
| 284 | spear_shirq_register(shirq_blocks[i]); | ||
| 285 | hwirq += shirq_blocks[i]->irq_nr; | ||
| 286 | } | ||
| 287 | |||
| 288 | return 0; | ||
| 289 | |||
| 290 | err_free_desc: | ||
| 291 | irq_free_descs(irq_base, irq_nr); | ||
| 292 | err_unmap: | ||
| 293 | iounmap(base); | ||
| 294 | return -ENXIO; | ||
| 295 | } | ||
| 296 | |||
| 297 | int __init spear300_shirq_of_init(struct device_node *np, | ||
| 298 | struct device_node *parent) | ||
| 299 | { | ||
| 300 | return shirq_init(spear300_shirq_blocks, | ||
| 301 | ARRAY_SIZE(spear300_shirq_blocks), np); | ||
| 302 | } | ||
| 303 | |||
| 304 | int __init spear310_shirq_of_init(struct device_node *np, | ||
| 305 | struct device_node *parent) | ||
| 306 | { | ||
| 307 | return shirq_init(spear310_shirq_blocks, | ||
| 308 | ARRAY_SIZE(spear310_shirq_blocks), np); | ||
| 309 | } | ||
| 310 | |||
| 311 | int __init spear320_shirq_of_init(struct device_node *np, | ||
| 312 | struct device_node *parent) | ||
| 313 | { | ||
| 314 | return shirq_init(spear320_shirq_blocks, | ||
| 315 | ARRAY_SIZE(spear320_shirq_blocks), np); | ||
| 316 | } | ||
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index aeecf0f72cad..4d4b08b51f83 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
| @@ -143,8 +143,8 @@ config PINCTRL_SINGLE | |||
| 143 | This selects the device tree based generic pinctrl driver. | 143 | This selects the device tree based generic pinctrl driver. |
| 144 | 144 | ||
| 145 | config PINCTRL_SIRF | 145 | config PINCTRL_SIRF |
| 146 | bool "CSR SiRFprimaII pin controller driver" | 146 | bool "CSR SiRFprimaII/SiRFmarco pin controller driver" |
| 147 | depends on ARCH_PRIMA2 | 147 | depends on ARCH_SIRF |
| 148 | select PINMUX | 148 | select PINMUX |
| 149 | 149 | ||
| 150 | config PINCTRL_TEGRA | 150 | config PINCTRL_TEGRA |
| @@ -188,27 +188,7 @@ config PINCTRL_EXYNOS4 | |||
| 188 | depends on OF && GPIOLIB | 188 | depends on OF && GPIOLIB |
| 189 | select PINCTRL_SAMSUNG | 189 | select PINCTRL_SAMSUNG |
| 190 | 190 | ||
| 191 | config PINCTRL_MVEBU | 191 | source "drivers/pinctrl/mvebu/Kconfig" |
| 192 | bool | ||
| 193 | depends on ARCH_MVEBU | ||
| 194 | select PINMUX | ||
| 195 | select PINCONF | ||
| 196 | |||
| 197 | config PINCTRL_DOVE | ||
| 198 | bool | ||
| 199 | select PINCTRL_MVEBU | ||
| 200 | |||
| 201 | config PINCTRL_KIRKWOOD | ||
| 202 | bool | ||
| 203 | select PINCTRL_MVEBU | ||
| 204 | |||
| 205 | config PINCTRL_ARMADA_370 | ||
| 206 | bool | ||
| 207 | select PINCTRL_MVEBU | ||
| 208 | |||
| 209 | config PINCTRL_ARMADA_XP | ||
| 210 | bool | ||
| 211 | select PINCTRL_MVEBU | ||
| 212 | 192 | ||
| 213 | source "drivers/pinctrl/spear/Kconfig" | 193 | source "drivers/pinctrl/spear/Kconfig" |
| 214 | 194 | ||
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f395ba5cec25..3cb6a0a668a8 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
| @@ -36,12 +36,8 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o | |||
| 36 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o | 36 | obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o |
| 37 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o | 37 | obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o |
| 38 | obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o | 38 | obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o |
| 39 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | ||
| 40 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
| 41 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
| 42 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
| 43 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
| 44 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o | 39 | obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o |
| 45 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o | 40 | obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o |
| 46 | 41 | ||
| 42 | obj-$(CONFIG_PLAT_ORION) += mvebu/ | ||
| 47 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 43 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2e39c04fc16b..71db586b2afd 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
| @@ -345,6 +345,33 @@ void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, | |||
| 345 | } | 345 | } |
| 346 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); | 346 | EXPORT_SYMBOL_GPL(pinctrl_add_gpio_ranges); |
| 347 | 347 | ||
| 348 | struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, | ||
| 349 | struct pinctrl_gpio_range *range) | ||
| 350 | { | ||
| 351 | struct pinctrl_dev *pctldev = get_pinctrl_dev_from_devname(devname); | ||
| 352 | |||
| 353 | if (!pctldev) | ||
| 354 | return NULL; | ||
| 355 | |||
| 356 | pinctrl_add_gpio_range(pctldev, range); | ||
| 357 | return pctldev; | ||
| 358 | } | ||
| 359 | EXPORT_SYMBOL_GPL(find_pinctrl_and_add_gpio_range); | ||
| 360 | |||
| 361 | /** | ||
| 362 | * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller | ||
| 363 | * @pctldev: pin controller device to remove the range from | ||
| 364 | * @range: the GPIO range to remove | ||
| 365 | */ | ||
| 366 | void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, | ||
| 367 | struct pinctrl_gpio_range *range) | ||
| 368 | { | ||
| 369 | mutex_lock(&pinctrl_mutex); | ||
| 370 | list_del(&range->node); | ||
| 371 | mutex_unlock(&pinctrl_mutex); | ||
| 372 | } | ||
| 373 | EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); | ||
| 374 | |||
| 348 | /** | 375 | /** |
| 349 | * pinctrl_get_group_selector() - returns the group selector for a group | 376 | * pinctrl_get_group_selector() - returns the group selector for a group |
| 350 | * @pctldev: the pin controller handling the group | 377 | * @pctldev: the pin controller handling the group |
| @@ -563,6 +590,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
| 563 | return -EPROBE_DEFER; | 590 | return -EPROBE_DEFER; |
| 564 | } | 591 | } |
| 565 | 592 | ||
| 593 | setting->dev_name = map->dev_name; | ||
| 594 | |||
| 566 | switch (map->type) { | 595 | switch (map->type) { |
| 567 | case PIN_MAP_TYPE_MUX_GROUP: | 596 | case PIN_MAP_TYPE_MUX_GROUP: |
| 568 | ret = pinmux_map_to_setting(map, setting); | 597 | ret = pinmux_map_to_setting(map, setting); |
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 1f40ff68a8c4..12f5694f3d5d 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
| @@ -105,12 +105,14 @@ struct pinctrl_setting_configs { | |||
| 105 | * @type: the type of setting | 105 | * @type: the type of setting |
| 106 | * @pctldev: pin control device handling to be programmed. Not used for | 106 | * @pctldev: pin control device handling to be programmed. Not used for |
| 107 | * PIN_MAP_TYPE_DUMMY_STATE. | 107 | * PIN_MAP_TYPE_DUMMY_STATE. |
| 108 | * @dev_name: the name of the device using this state | ||
| 108 | * @data: Data specific to the setting type | 109 | * @data: Data specific to the setting type |
| 109 | */ | 110 | */ |
| 110 | struct pinctrl_setting { | 111 | struct pinctrl_setting { |
| 111 | struct list_head node; | 112 | struct list_head node; |
| 112 | enum pinctrl_map_type type; | 113 | enum pinctrl_map_type type; |
| 113 | struct pinctrl_dev *pctldev; | 114 | struct pinctrl_dev *pctldev; |
| 115 | const char *dev_name; | ||
| 114 | union { | 116 | union { |
| 115 | struct pinctrl_setting_mux mux; | 117 | struct pinctrl_setting_mux mux; |
| 116 | struct pinctrl_setting_configs configs; | 118 | struct pinctrl_setting_configs configs; |
diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index fcb1de45473c..fe2d1af7cfa0 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c | |||
| @@ -106,6 +106,17 @@ static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) | |||
| 106 | return NULL; | 106 | return NULL; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | struct pinctrl_dev *of_pinctrl_get(struct device_node *np) | ||
| 110 | { | ||
| 111 | struct pinctrl_dev *pctldev; | ||
| 112 | |||
| 113 | pctldev = find_pinctrl_by_of_node(np); | ||
| 114 | if (!pctldev) | ||
| 115 | return NULL; | ||
| 116 | |||
| 117 | return pctldev; | ||
| 118 | } | ||
| 119 | |||
| 109 | static int dt_to_map_one_config(struct pinctrl *p, const char *statename, | 120 | static int dt_to_map_one_config(struct pinctrl *p, const char *statename, |
| 110 | struct device_node *np_config) | 121 | struct device_node *np_config) |
| 111 | { | 122 | { |
diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig new file mode 100644 index 000000000000..366fa541ee91 --- /dev/null +++ b/drivers/pinctrl/mvebu/Kconfig | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | if PLAT_ORION | ||
| 2 | |||
| 3 | config PINCTRL_MVEBU | ||
| 4 | bool | ||
| 5 | select PINMUX | ||
| 6 | select PINCONF | ||
| 7 | |||
| 8 | config PINCTRL_DOVE | ||
| 9 | bool | ||
| 10 | select PINCTRL_MVEBU | ||
| 11 | |||
| 12 | config PINCTRL_KIRKWOOD | ||
| 13 | bool | ||
| 14 | select PINCTRL_MVEBU | ||
| 15 | |||
| 16 | config PINCTRL_ARMADA_370 | ||
| 17 | bool | ||
| 18 | select PINCTRL_MVEBU | ||
| 19 | |||
| 20 | config PINCTRL_ARMADA_XP | ||
| 21 | bool | ||
| 22 | select PINCTRL_MVEBU | ||
| 23 | |||
| 24 | endif | ||
diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile new file mode 100644 index 000000000000..37c253297af0 --- /dev/null +++ b/drivers/pinctrl/mvebu/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o | ||
| 2 | obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o | ||
| 3 | obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o | ||
| 4 | obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o | ||
| 5 | obj-$(CONFIG_PINCTRL_ARMADA_XP) += pinctrl-armada-xp.o | ||
diff --git a/drivers/pinctrl/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c index c907647de6ad..c907647de6ad 100644 --- a/drivers/pinctrl/pinctrl-armada-370.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c | |||
diff --git a/drivers/pinctrl/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c index 40bd52a46b4e..40bd52a46b4e 100644 --- a/drivers/pinctrl/pinctrl-armada-xp.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c | |||
diff --git a/drivers/pinctrl/pinctrl-dove.c b/drivers/pinctrl/mvebu/pinctrl-dove.c index ffe74b27d66d..ffe74b27d66d 100644 --- a/drivers/pinctrl/pinctrl-dove.c +++ b/drivers/pinctrl/mvebu/pinctrl-dove.c | |||
diff --git a/drivers/pinctrl/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c index 9a74ef674a0e..9a74ef674a0e 100644 --- a/drivers/pinctrl/pinctrl-kirkwood.c +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c | |||
diff --git a/drivers/pinctrl/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index 8e6266c6249a..6c44b7e8964c 100644 --- a/drivers/pinctrl/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/pinctrl/pinctrl.h> | 24 | #include <linux/pinctrl/pinctrl.h> |
| 25 | #include <linux/pinctrl/pinmux.h> | 25 | #include <linux/pinctrl/pinmux.h> |
| 26 | 26 | ||
| 27 | #include "core.h" | ||
| 28 | #include "pinctrl-mvebu.h" | 27 | #include "pinctrl-mvebu.h" |
| 29 | 28 | ||
| 30 | #define MPPS_PER_REG 8 | 29 | #define MPPS_PER_REG 8 |
diff --git a/drivers/pinctrl/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h index 90bd3beee860..90bd3beee860 100644 --- a/drivers/pinctrl/pinctrl-mvebu.h +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h | |||
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index b446c9641212..5c7daf9169e8 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/irqdomain.h> | ||
| 16 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 17 | #include <linux/err.h> | 18 | #include <linux/err.h> |
| 18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| @@ -64,10 +65,8 @@ struct u300_gpio { | |||
| 64 | struct gpio_chip chip; | 65 | struct gpio_chip chip; |
| 65 | struct list_head port_list; | 66 | struct list_head port_list; |
| 66 | struct clk *clk; | 67 | struct clk *clk; |
| 67 | struct resource *memres; | ||
| 68 | void __iomem *base; | 68 | void __iomem *base; |
| 69 | struct device *dev; | 69 | struct device *dev; |
| 70 | int irq_base; | ||
| 71 | u32 stride; | 70 | u32 stride; |
| 72 | /* Register offsets */ | 71 | /* Register offsets */ |
| 73 | u32 pcr; | 72 | u32 pcr; |
| @@ -83,6 +82,7 @@ struct u300_gpio_port { | |||
| 83 | struct list_head node; | 82 | struct list_head node; |
| 84 | struct u300_gpio *gpio; | 83 | struct u300_gpio *gpio; |
| 85 | char name[8]; | 84 | char name[8]; |
| 85 | struct irq_domain *domain; | ||
| 86 | int irq; | 86 | int irq; |
| 87 | int number; | 87 | int number; |
| 88 | u8 toggle_edge_mode; | 88 | u8 toggle_edge_mode; |
| @@ -314,10 +314,30 @@ static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | |||
| 314 | static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 314 | static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
| 315 | { | 315 | { |
| 316 | struct u300_gpio *gpio = to_u300_gpio(chip); | 316 | struct u300_gpio *gpio = to_u300_gpio(chip); |
| 317 | int retirq = gpio->irq_base + offset; | 317 | int portno = offset >> 3; |
| 318 | struct u300_gpio_port *port = NULL; | ||
| 319 | struct list_head *p; | ||
| 320 | int retirq; | ||
| 321 | |||
| 322 | list_for_each(p, &gpio->port_list) { | ||
| 323 | port = list_entry(p, struct u300_gpio_port, node); | ||
| 324 | if (port->number == portno) | ||
| 325 | break; | ||
| 326 | } | ||
| 327 | if (port == NULL) { | ||
| 328 | dev_err(gpio->dev, "could not locate port for GPIO %d IRQ\n", | ||
| 329 | offset); | ||
| 330 | return -EINVAL; | ||
| 331 | } | ||
| 332 | |||
| 333 | /* | ||
| 334 | * The local hwirqs on the port are the lower three bits, there | ||
| 335 | * are exactly 8 IRQs per port since they are 8-bit | ||
| 336 | */ | ||
| 337 | retirq = irq_find_mapping(port->domain, (offset & 0x7)); | ||
| 318 | 338 | ||
| 319 | dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, | 339 | dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d from port %d\n", |
| 320 | retirq); | 340 | offset, retirq, port->number); |
| 321 | return retirq; | 341 | return retirq; |
| 322 | } | 342 | } |
| 323 | 343 | ||
| @@ -467,7 +487,7 @@ static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) | |||
| 467 | { | 487 | { |
| 468 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 488 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
| 469 | struct u300_gpio *gpio = port->gpio; | 489 | struct u300_gpio *gpio = port->gpio; |
| 470 | int offset = d->irq - gpio->irq_base; | 490 | int offset = (port->number << 3) + d->hwirq; |
| 471 | u32 val; | 491 | u32 val; |
| 472 | 492 | ||
| 473 | if ((trigger & IRQF_TRIGGER_RISING) && | 493 | if ((trigger & IRQF_TRIGGER_RISING) && |
| @@ -503,10 +523,12 @@ static void u300_gpio_irq_enable(struct irq_data *d) | |||
| 503 | { | 523 | { |
| 504 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 524 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
| 505 | struct u300_gpio *gpio = port->gpio; | 525 | struct u300_gpio *gpio = port->gpio; |
| 506 | int offset = d->irq - gpio->irq_base; | 526 | int offset = (port->number << 3) + d->hwirq; |
| 507 | u32 val; | 527 | u32 val; |
| 508 | unsigned long flags; | 528 | unsigned long flags; |
| 509 | 529 | ||
| 530 | dev_dbg(gpio->dev, "enable IRQ for hwirq %lu on port %s, offset %d\n", | ||
| 531 | d->hwirq, port->name, offset); | ||
| 510 | local_irq_save(flags); | 532 | local_irq_save(flags); |
| 511 | val = readl(U300_PIN_REG(offset, ien)); | 533 | val = readl(U300_PIN_REG(offset, ien)); |
| 512 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); | 534 | writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); |
| @@ -517,7 +539,7 @@ static void u300_gpio_irq_disable(struct irq_data *d) | |||
| 517 | { | 539 | { |
| 518 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); | 540 | struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); |
| 519 | struct u300_gpio *gpio = port->gpio; | 541 | struct u300_gpio *gpio = port->gpio; |
| 520 | int offset = d->irq - gpio->irq_base; | 542 | int offset = (port->number << 3) + d->hwirq; |
| 521 | u32 val; | 543 | u32 val; |
| 522 | unsigned long flags; | 544 | unsigned long flags; |
| 523 | 545 | ||
| @@ -555,8 +577,7 @@ static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
| 555 | int irqoffset; | 577 | int irqoffset; |
| 556 | 578 | ||
| 557 | for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { | 579 | for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { |
| 558 | int pin_irq = gpio->irq_base + (port->number << 3) | 580 | int pin_irq = irq_find_mapping(port->domain, irqoffset); |
| 559 | + irqoffset; | ||
| 560 | int offset = pinoffset + irqoffset; | 581 | int offset = pinoffset + irqoffset; |
| 561 | 582 | ||
| 562 | dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", | 583 | dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", |
| @@ -631,6 +652,8 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) | |||
| 631 | list_for_each_safe(p, n, &gpio->port_list) { | 652 | list_for_each_safe(p, n, &gpio->port_list) { |
| 632 | port = list_entry(p, struct u300_gpio_port, node); | 653 | port = list_entry(p, struct u300_gpio_port, node); |
| 633 | list_del(&port->node); | 654 | list_del(&port->node); |
| 655 | if (port->domain) | ||
| 656 | irq_domain_remove(port->domain); | ||
| 634 | kfree(port); | 657 | kfree(port); |
| 635 | } | 658 | } |
| 636 | } | 659 | } |
| @@ -639,56 +662,46 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
| 639 | { | 662 | { |
| 640 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); | 663 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); |
| 641 | struct u300_gpio *gpio; | 664 | struct u300_gpio *gpio; |
| 665 | struct resource *memres; | ||
| 642 | int err = 0; | 666 | int err = 0; |
| 643 | int portno; | 667 | int portno; |
| 644 | u32 val; | 668 | u32 val; |
| 645 | u32 ifr; | 669 | u32 ifr; |
| 646 | int i; | 670 | int i; |
| 647 | 671 | ||
| 648 | gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); | 672 | gpio = devm_kzalloc(&pdev->dev, sizeof(struct u300_gpio), GFP_KERNEL); |
| 649 | if (gpio == NULL) { | 673 | if (gpio == NULL) |
| 650 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
| 651 | return -ENOMEM; | 674 | return -ENOMEM; |
| 652 | } | ||
| 653 | 675 | ||
| 654 | gpio->chip = u300_gpio_chip; | 676 | gpio->chip = u300_gpio_chip; |
| 655 | gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; | 677 | gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; |
| 656 | gpio->irq_base = plat->gpio_irq_base; | ||
| 657 | gpio->chip.dev = &pdev->dev; | 678 | gpio->chip.dev = &pdev->dev; |
| 658 | gpio->chip.base = plat->gpio_base; | 679 | gpio->chip.base = plat->gpio_base; |
| 659 | gpio->dev = &pdev->dev; | 680 | gpio->dev = &pdev->dev; |
| 660 | 681 | ||
| 661 | /* Get GPIO clock */ | 682 | memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 662 | gpio->clk = clk_get(gpio->dev, NULL); | 683 | if (!memres) { |
| 684 | dev_err(gpio->dev, "could not get GPIO memory resource\n"); | ||
| 685 | return -ENODEV; | ||
| 686 | } | ||
| 687 | |||
| 688 | gpio->base = devm_request_and_ioremap(&pdev->dev, memres); | ||
| 689 | if (!gpio->base) { | ||
| 690 | dev_err(gpio->dev, "could not get remap memory\n"); | ||
| 691 | return -ENOMEM; | ||
| 692 | } | ||
| 693 | |||
| 694 | gpio->clk = devm_clk_get(gpio->dev, NULL); | ||
| 663 | if (IS_ERR(gpio->clk)) { | 695 | if (IS_ERR(gpio->clk)) { |
| 664 | err = PTR_ERR(gpio->clk); | 696 | err = PTR_ERR(gpio->clk); |
| 665 | dev_err(gpio->dev, "could not get GPIO clock\n"); | 697 | dev_err(gpio->dev, "could not get GPIO clock\n"); |
| 666 | goto err_no_clk; | 698 | return err; |
| 667 | } | 699 | } |
| 700 | |||
| 668 | err = clk_prepare_enable(gpio->clk); | 701 | err = clk_prepare_enable(gpio->clk); |
| 669 | if (err) { | 702 | if (err) { |
| 670 | dev_err(gpio->dev, "could not enable GPIO clock\n"); | 703 | dev_err(gpio->dev, "could not enable GPIO clock\n"); |
| 671 | goto err_no_clk_enable; | 704 | return err; |
| 672 | } | ||
| 673 | |||
| 674 | gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 675 | if (!gpio->memres) { | ||
| 676 | dev_err(gpio->dev, "could not get GPIO memory resource\n"); | ||
| 677 | err = -ENODEV; | ||
| 678 | goto err_no_resource; | ||
| 679 | } | ||
| 680 | |||
| 681 | if (!request_mem_region(gpio->memres->start, | ||
| 682 | resource_size(gpio->memres), | ||
| 683 | "GPIO Controller")) { | ||
| 684 | err = -ENODEV; | ||
| 685 | goto err_no_ioregion; | ||
| 686 | } | ||
| 687 | |||
| 688 | gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); | ||
| 689 | if (!gpio->base) { | ||
| 690 | err = -ENOMEM; | ||
| 691 | goto err_no_ioremap; | ||
| 692 | } | 705 | } |
| 693 | 706 | ||
| 694 | dev_info(gpio->dev, | 707 | dev_info(gpio->dev, |
| @@ -732,18 +745,26 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
| 732 | port->irq = platform_get_irq_byname(pdev, | 745 | port->irq = platform_get_irq_byname(pdev, |
| 733 | port->name); | 746 | port->name); |
| 734 | 747 | ||
| 735 | dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, | 748 | dev_dbg(gpio->dev, "register IRQ %d for port %s\n", port->irq, |
| 736 | port->name); | 749 | port->name); |
| 737 | 750 | ||
| 751 | port->domain = irq_domain_add_linear(pdev->dev.of_node, | ||
| 752 | U300_GPIO_PINS_PER_PORT, | ||
| 753 | &irq_domain_simple_ops, | ||
| 754 | port); | ||
| 755 | if (!port->domain) | ||
| 756 | goto err_no_domain; | ||
| 757 | |||
| 738 | irq_set_chained_handler(port->irq, u300_gpio_irq_handler); | 758 | irq_set_chained_handler(port->irq, u300_gpio_irq_handler); |
| 739 | irq_set_handler_data(port->irq, port); | 759 | irq_set_handler_data(port->irq, port); |
| 740 | 760 | ||
| 741 | /* For each GPIO pin set the unique IRQ handler */ | 761 | /* For each GPIO pin set the unique IRQ handler */ |
| 742 | for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { | 762 | for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { |
| 743 | int irqno = gpio->irq_base + (portno << 3) + i; | 763 | int irqno = irq_create_mapping(port->domain, i); |
| 744 | 764 | ||
| 745 | dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", | 765 | dev_dbg(gpio->dev, "GPIO%d on port %s gets IRQ %d\n", |
| 746 | irqno, port->name); | 766 | gpio->chip.base + (port->number << 3) + i, |
| 767 | port->name, irqno); | ||
| 747 | irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, | 768 | irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, |
| 748 | handle_simple_irq); | 769 | handle_simple_irq); |
| 749 | set_irq_flags(irqno, IRQF_VALID); | 770 | set_irq_flags(irqno, IRQF_VALID); |
| @@ -776,18 +797,10 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
| 776 | err_no_pinctrl: | 797 | err_no_pinctrl: |
| 777 | err = gpiochip_remove(&gpio->chip); | 798 | err = gpiochip_remove(&gpio->chip); |
| 778 | err_no_chip: | 799 | err_no_chip: |
| 800 | err_no_domain: | ||
| 779 | err_no_port: | 801 | err_no_port: |
| 780 | u300_gpio_free_ports(gpio); | 802 | u300_gpio_free_ports(gpio); |
| 781 | iounmap(gpio->base); | ||
| 782 | err_no_ioremap: | ||
| 783 | release_mem_region(gpio->memres->start, resource_size(gpio->memres)); | ||
| 784 | err_no_ioregion: | ||
| 785 | err_no_resource: | ||
| 786 | clk_disable_unprepare(gpio->clk); | 803 | clk_disable_unprepare(gpio->clk); |
| 787 | err_no_clk_enable: | ||
| 788 | clk_put(gpio->clk); | ||
| 789 | err_no_clk: | ||
| 790 | kfree(gpio); | ||
| 791 | dev_info(&pdev->dev, "module ERROR:%d\n", err); | 804 | dev_info(&pdev->dev, "module ERROR:%d\n", err); |
| 792 | return err; | 805 | return err; |
| 793 | } | 806 | } |
| @@ -806,13 +819,8 @@ static int __exit u300_gpio_remove(struct platform_device *pdev) | |||
| 806 | return err; | 819 | return err; |
| 807 | } | 820 | } |
| 808 | u300_gpio_free_ports(gpio); | 821 | u300_gpio_free_ports(gpio); |
| 809 | iounmap(gpio->base); | ||
| 810 | release_mem_region(gpio->memres->start, | ||
| 811 | resource_size(gpio->memres)); | ||
| 812 | clk_disable_unprepare(gpio->clk); | 822 | clk_disable_unprepare(gpio->clk); |
| 813 | clk_put(gpio->clk); | ||
| 814 | platform_set_drvdata(pdev, NULL); | 823 | platform_set_drvdata(pdev, NULL); |
| 815 | kfree(gpio); | ||
| 816 | return 0; | 824 | return 0; |
| 817 | } | 825 | } |
| 818 | 826 | ||
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c index 21362f48d370..6ff665209a4c 100644 --- a/drivers/pinctrl/pinctrl-exynos.c +++ b/drivers/pinctrl/pinctrl-exynos.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | /* list of external wakeup controllers supported */ | 36 | /* list of external wakeup controllers supported */ |
| 37 | static const struct of_device_id exynos_wkup_irq_ids[] = { | 37 | static const struct of_device_id exynos_wkup_irq_ids[] = { |
| 38 | { .compatible = "samsung,exynos4210-wakeup-eint", }, | 38 | { .compatible = "samsung,exynos4210-wakeup-eint", }, |
| 39 | { } | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) | 42 | static void exynos_gpio_irq_unmask(struct irq_data *irqd) |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 9ecacf3d0a75..a3905e58d1b3 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
| @@ -32,10 +32,10 @@ | |||
| 32 | #define SIRFSOC_NUM_PADS 622 | 32 | #define SIRFSOC_NUM_PADS 622 |
| 33 | #define SIRFSOC_RSC_PIN_MUX 0x4 | 33 | #define SIRFSOC_RSC_PIN_MUX 0x4 |
| 34 | 34 | ||
| 35 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) | 35 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) |
| 36 | #define SIRFSOC_GPIO_PAD_EN_CLR(g) ((g)*0x100 + 0x90) | ||
| 36 | #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) | 37 | #define SIRFSOC_GPIO_CTRL(g, i) ((g)*0x100 + (i)*4) |
| 37 | #define SIRFSOC_GPIO_DSP_EN0 (0x80) | 38 | #define SIRFSOC_GPIO_DSP_EN0 (0x80) |
| 38 | #define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) | ||
| 39 | #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) | 39 | #define SIRFSOC_GPIO_INT_STATUS(g) ((g)*0x100 + 0x8C) |
| 40 | 40 | ||
| 41 | #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 | 41 | #define SIRFSOC_GPIO_CTL_INTR_LOW_MASK 0x1 |
| @@ -60,6 +60,7 @@ struct sirfsoc_gpio_bank { | |||
| 60 | int id; | 60 | int id; |
| 61 | int parent_irq; | 61 | int parent_irq; |
| 62 | spinlock_t lock; | 62 | spinlock_t lock; |
| 63 | bool is_marco; /* for marco, some registers are different with prima2 */ | ||
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; | 66 | static struct sirfsoc_gpio_bank sgpio_bank[SIRFSOC_GPIO_NO_OF_BANKS]; |
| @@ -191,6 +192,7 @@ struct sirfsoc_pmx { | |||
| 191 | struct pinctrl_dev *pmx; | 192 | struct pinctrl_dev *pmx; |
| 192 | void __iomem *gpio_virtbase; | 193 | void __iomem *gpio_virtbase; |
| 193 | void __iomem *rsc_virtbase; | 194 | void __iomem *rsc_virtbase; |
| 195 | bool is_marco; | ||
| 194 | }; | 196 | }; |
| 195 | 197 | ||
| 196 | /* SIRFSOC_GPIO_PAD_EN set */ | 198 | /* SIRFSOC_GPIO_PAD_EN set */ |
| @@ -1088,12 +1090,21 @@ static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector | |||
| 1088 | 1090 | ||
| 1089 | for (i = 0; i < mux->muxmask_counts; i++) { | 1091 | for (i = 0; i < mux->muxmask_counts; i++) { |
| 1090 | u32 muxval; | 1092 | u32 muxval; |
| 1091 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | 1093 | if (!spmx->is_marco) { |
| 1092 | if (enable) | 1094 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); |
| 1093 | muxval = muxval & ~mask[i].mask; | 1095 | if (enable) |
| 1094 | else | 1096 | muxval = muxval & ~mask[i].mask; |
| 1095 | muxval = muxval | mask[i].mask; | 1097 | else |
| 1096 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | 1098 | muxval = muxval | mask[i].mask; |
| 1099 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); | ||
| 1100 | } else { | ||
| 1101 | if (enable) | ||
| 1102 | writel(mask[i].mask, spmx->gpio_virtbase + | ||
| 1103 | SIRFSOC_GPIO_PAD_EN_CLR(mask[i].group)); | ||
| 1104 | else | ||
| 1105 | writel(mask[i].mask, spmx->gpio_virtbase + | ||
| 1106 | SIRFSOC_GPIO_PAD_EN(mask[i].group)); | ||
| 1107 | } | ||
| 1097 | } | 1108 | } |
| 1098 | 1109 | ||
| 1099 | if (mux->funcmask && enable) { | 1110 | if (mux->funcmask && enable) { |
| @@ -1158,9 +1169,14 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, | |||
| 1158 | 1169 | ||
| 1159 | spmx = pinctrl_dev_get_drvdata(pmxdev); | 1170 | spmx = pinctrl_dev_get_drvdata(pmxdev); |
| 1160 | 1171 | ||
| 1161 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | 1172 | if (!spmx->is_marco) { |
| 1162 | muxval = muxval | (1 << (offset - range->pin_base)); | 1173 | muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); |
| 1163 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | 1174 | muxval = muxval | (1 << (offset - range->pin_base)); |
| 1175 | writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); | ||
| 1176 | } else { | ||
| 1177 | writel(1 << (offset - range->pin_base), spmx->gpio_virtbase + | ||
| 1178 | SIRFSOC_GPIO_PAD_EN(group)); | ||
| 1179 | } | ||
| 1164 | 1180 | ||
| 1165 | return 0; | 1181 | return 0; |
| 1166 | } | 1182 | } |
| @@ -1218,6 +1234,7 @@ static void __iomem *sirfsoc_rsc_of_iomap(void) | |||
| 1218 | { | 1234 | { |
| 1219 | const struct of_device_id rsc_ids[] = { | 1235 | const struct of_device_id rsc_ids[] = { |
| 1220 | { .compatible = "sirf,prima2-rsc" }, | 1236 | { .compatible = "sirf,prima2-rsc" }, |
| 1237 | { .compatible = "sirf,marco-rsc" }, | ||
| 1221 | {} | 1238 | {} |
| 1222 | }; | 1239 | }; |
| 1223 | struct device_node *np; | 1240 | struct device_node *np; |
| @@ -1259,6 +1276,9 @@ static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) | |||
| 1259 | goto out_no_rsc_remap; | 1276 | goto out_no_rsc_remap; |
| 1260 | } | 1277 | } |
| 1261 | 1278 | ||
| 1279 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | ||
| 1280 | spmx->is_marco = 1; | ||
| 1281 | |||
| 1262 | /* Now register the pin controller and all pins it handles */ | 1282 | /* Now register the pin controller and all pins it handles */ |
| 1263 | spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); | 1283 | spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); |
| 1264 | if (!spmx->pmx) { | 1284 | if (!spmx->pmx) { |
| @@ -1287,6 +1307,7 @@ out_no_gpio_remap: | |||
| 1287 | 1307 | ||
| 1288 | static const struct of_device_id pinmux_ids[] __devinitconst = { | 1308 | static const struct of_device_id pinmux_ids[] __devinitconst = { |
| 1289 | { .compatible = "sirf,prima2-pinctrl" }, | 1309 | { .compatible = "sirf,prima2-pinctrl" }, |
| 1310 | { .compatible = "sirf,marco-pinctrl" }, | ||
| 1290 | {} | 1311 | {} |
| 1291 | }; | 1312 | }; |
| 1292 | 1313 | ||
| @@ -1621,8 +1642,8 @@ static void sirfsoc_gpio_set_value(struct gpio_chip *chip, unsigned offset, | |||
| 1621 | spin_unlock_irqrestore(&bank->lock, flags); | 1642 | spin_unlock_irqrestore(&bank->lock, flags); |
| 1622 | } | 1643 | } |
| 1623 | 1644 | ||
| 1624 | int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, | 1645 | static int sirfsoc_gpio_irq_map(struct irq_domain *d, unsigned int irq, |
| 1625 | irq_hw_number_t hwirq) | 1646 | irq_hw_number_t hwirq) |
| 1626 | { | 1647 | { |
| 1627 | struct sirfsoc_gpio_bank *bank = d->host_data; | 1648 | struct sirfsoc_gpio_bank *bank = d->host_data; |
| 1628 | 1649 | ||
| @@ -1648,6 +1669,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
| 1648 | struct sirfsoc_gpio_bank *bank; | 1669 | struct sirfsoc_gpio_bank *bank; |
| 1649 | void *regs; | 1670 | void *regs; |
| 1650 | struct platform_device *pdev; | 1671 | struct platform_device *pdev; |
| 1672 | bool is_marco = false; | ||
| 1651 | 1673 | ||
| 1652 | pdev = of_find_device_by_node(np); | 1674 | pdev = of_find_device_by_node(np); |
| 1653 | if (!pdev) | 1675 | if (!pdev) |
| @@ -1657,6 +1679,9 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
| 1657 | if (!regs) | 1679 | if (!regs) |
| 1658 | return -ENOMEM; | 1680 | return -ENOMEM; |
| 1659 | 1681 | ||
| 1682 | if (of_device_is_compatible(np, "sirf,marco-pinctrl")) | ||
| 1683 | is_marco = 1; | ||
| 1684 | |||
| 1660 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { | 1685 | for (i = 0; i < SIRFSOC_GPIO_NO_OF_BANKS; i++) { |
| 1661 | bank = &sgpio_bank[i]; | 1686 | bank = &sgpio_bank[i]; |
| 1662 | spin_lock_init(&bank->lock); | 1687 | spin_lock_init(&bank->lock); |
| @@ -1673,6 +1698,7 @@ static int __devinit sirfsoc_gpio_probe(struct device_node *np) | |||
| 1673 | bank->chip.gc.of_node = np; | 1698 | bank->chip.gc.of_node = np; |
| 1674 | bank->chip.regs = regs; | 1699 | bank->chip.regs = regs; |
| 1675 | bank->id = i; | 1700 | bank->id = i; |
| 1701 | bank->is_marco = is_marco; | ||
| 1676 | bank->parent_irq = platform_get_irq(pdev, i); | 1702 | bank->parent_irq = platform_get_irq(pdev, i); |
| 1677 | if (bank->parent_irq < 0) { | 1703 | if (bank->parent_irq < 0) { |
| 1678 | err = bank->parent_irq; | 1704 | err = bank->parent_irq; |
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 309f5b9a70ec..d756cce588fd 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c | |||
| @@ -663,8 +663,6 @@ static const struct pinctrl_pin_desc u300_pads[] = { | |||
| 663 | struct u300_pmx { | 663 | struct u300_pmx { |
| 664 | struct device *dev; | 664 | struct device *dev; |
| 665 | struct pinctrl_dev *pctl; | 665 | struct pinctrl_dev *pctl; |
| 666 | u32 phybase; | ||
| 667 | u32 physize; | ||
| 668 | void __iomem *virtbase; | 666 | void __iomem *virtbase; |
| 669 | }; | 667 | }; |
| 670 | 668 | ||
| @@ -1054,9 +1052,8 @@ static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin) | |||
| 1054 | return NULL; | 1052 | return NULL; |
| 1055 | } | 1053 | } |
| 1056 | 1054 | ||
| 1057 | int u300_pin_config_get(struct pinctrl_dev *pctldev, | 1055 | static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, |
| 1058 | unsigned pin, | 1056 | unsigned long *config) |
| 1059 | unsigned long *config) | ||
| 1060 | { | 1057 | { |
| 1061 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); | 1058 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); |
| 1062 | 1059 | ||
| @@ -1069,9 +1066,8 @@ int u300_pin_config_get(struct pinctrl_dev *pctldev, | |||
| 1069 | config); | 1066 | config); |
| 1070 | } | 1067 | } |
| 1071 | 1068 | ||
| 1072 | int u300_pin_config_set(struct pinctrl_dev *pctldev, | 1069 | static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, |
| 1073 | unsigned pin, | 1070 | unsigned long config) |
| 1074 | unsigned long config) | ||
| 1075 | { | 1071 | { |
| 1076 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); | 1072 | struct pinctrl_gpio_range *range = u300_match_gpio_range(pin); |
| 1077 | int ret; | 1073 | int ret; |
| @@ -1110,7 +1106,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
| 1110 | struct u300_pmx *upmx; | 1106 | struct u300_pmx *upmx; |
| 1111 | struct resource *res; | 1107 | struct resource *res; |
| 1112 | struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); | 1108 | struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); |
| 1113 | int ret; | ||
| 1114 | int i; | 1109 | int i; |
| 1115 | 1110 | ||
| 1116 | /* Create state holders etc for this driver */ | 1111 | /* Create state holders etc for this driver */ |
| @@ -1123,26 +1118,15 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
| 1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1118 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1124 | if (!res) | 1119 | if (!res) |
| 1125 | return -ENOENT; | 1120 | return -ENOENT; |
| 1126 | upmx->phybase = res->start; | ||
| 1127 | upmx->physize = resource_size(res); | ||
| 1128 | |||
| 1129 | if (request_mem_region(upmx->phybase, upmx->physize, | ||
| 1130 | DRIVER_NAME) == NULL) { | ||
| 1131 | ret = -ENOMEM; | ||
| 1132 | goto out_no_memregion; | ||
| 1133 | } | ||
| 1134 | 1121 | ||
| 1135 | upmx->virtbase = ioremap(upmx->phybase, upmx->physize); | 1122 | upmx->virtbase = devm_request_and_ioremap(&pdev->dev, res); |
| 1136 | if (!upmx->virtbase) { | 1123 | if (!upmx->virtbase) |
| 1137 | ret = -ENOMEM; | 1124 | return -ENOMEM; |
| 1138 | goto out_no_remap; | ||
| 1139 | } | ||
| 1140 | 1125 | ||
| 1141 | upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); | 1126 | upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); |
| 1142 | if (!upmx->pctl) { | 1127 | if (!upmx->pctl) { |
| 1143 | dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); | 1128 | dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); |
| 1144 | ret = -EINVAL; | 1129 | return -EINVAL; |
| 1145 | goto out_no_pmx; | ||
| 1146 | } | 1130 | } |
| 1147 | 1131 | ||
| 1148 | /* We will handle a range of GPIO pins */ | 1132 | /* We will handle a range of GPIO pins */ |
| @@ -1156,14 +1140,6 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
| 1156 | dev_info(&pdev->dev, "initialized U300 pin control driver\n"); | 1140 | dev_info(&pdev->dev, "initialized U300 pin control driver\n"); |
| 1157 | 1141 | ||
| 1158 | return 0; | 1142 | return 0; |
| 1159 | |||
| 1160 | out_no_pmx: | ||
| 1161 | iounmap(upmx->virtbase); | ||
| 1162 | out_no_remap: | ||
| 1163 | platform_set_drvdata(pdev, NULL); | ||
| 1164 | out_no_memregion: | ||
| 1165 | release_mem_region(upmx->phybase, upmx->physize); | ||
| 1166 | return ret; | ||
| 1167 | } | 1143 | } |
| 1168 | 1144 | ||
| 1169 | static int __devexit u300_pmx_remove(struct platform_device *pdev) | 1145 | static int __devexit u300_pmx_remove(struct platform_device *pdev) |
| @@ -1171,8 +1147,6 @@ static int __devexit u300_pmx_remove(struct platform_device *pdev) | |||
| 1171 | struct u300_pmx *upmx = platform_get_drvdata(pdev); | 1147 | struct u300_pmx *upmx = platform_get_drvdata(pdev); |
| 1172 | 1148 | ||
| 1173 | pinctrl_unregister(upmx->pctl); | 1149 | pinctrl_unregister(upmx->pctl); |
| 1174 | iounmap(upmx->virtbase); | ||
| 1175 | release_mem_region(upmx->phybase, upmx->physize); | ||
| 1176 | platform_set_drvdata(pdev, NULL); | 1150 | platform_set_drvdata(pdev, NULL); |
| 1177 | 1151 | ||
| 1178 | return 0; | 1152 | return 0; |
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 9301a7a95eff..0ef01ee2835f 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
| @@ -314,14 +314,11 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, | |||
| 314 | { | 314 | { |
| 315 | struct pinctrl_dev *pctldev = setting->pctldev; | 315 | struct pinctrl_dev *pctldev = setting->pctldev; |
| 316 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; | 316 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; |
| 317 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
| 318 | char const * const *groups; | 317 | char const * const *groups; |
| 319 | unsigned num_groups; | 318 | unsigned num_groups; |
| 320 | int ret; | 319 | int ret; |
| 321 | const char *group; | 320 | const char *group; |
| 322 | int i; | 321 | int i; |
| 323 | const unsigned *pins; | ||
| 324 | unsigned num_pins; | ||
| 325 | 322 | ||
| 326 | if (!pmxops) { | 323 | if (!pmxops) { |
| 327 | dev_err(pctldev->dev, "does not support mux function\n"); | 324 | dev_err(pctldev->dev, "does not support mux function\n"); |
| @@ -376,53 +373,12 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, | |||
| 376 | } | 373 | } |
| 377 | setting->data.mux.group = ret; | 374 | setting->data.mux.group = ret; |
| 378 | 375 | ||
| 379 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, | ||
| 380 | &num_pins); | ||
| 381 | if (ret) { | ||
| 382 | dev_err(pctldev->dev, | ||
| 383 | "could not get pins for device %s group selector %d\n", | ||
| 384 | pinctrl_dev_get_name(pctldev), setting->data.mux.group); | ||
| 385 | return -ENODEV; | ||
| 386 | } | ||
| 387 | |||
| 388 | /* Try to allocate all pins in this group, one by one */ | ||
| 389 | for (i = 0; i < num_pins; i++) { | ||
| 390 | ret = pin_request(pctldev, pins[i], map->dev_name, NULL); | ||
| 391 | if (ret) { | ||
| 392 | dev_err(pctldev->dev, | ||
| 393 | "could not request pin %d on device %s\n", | ||
| 394 | pins[i], pinctrl_dev_get_name(pctldev)); | ||
| 395 | /* On error release all taken pins */ | ||
| 396 | i--; /* this pin just failed */ | ||
| 397 | for (; i >= 0; i--) | ||
| 398 | pin_free(pctldev, pins[i], NULL); | ||
| 399 | return -ENODEV; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | return 0; | 376 | return 0; |
| 404 | } | 377 | } |
| 405 | 378 | ||
| 406 | void pinmux_free_setting(struct pinctrl_setting const *setting) | 379 | void pinmux_free_setting(struct pinctrl_setting const *setting) |
| 407 | { | 380 | { |
| 408 | struct pinctrl_dev *pctldev = setting->pctldev; | 381 | /* This function is currently unused */ |
| 409 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
| 410 | const unsigned *pins; | ||
| 411 | unsigned num_pins; | ||
| 412 | int ret; | ||
| 413 | int i; | ||
| 414 | |||
| 415 | ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, | ||
| 416 | &pins, &num_pins); | ||
| 417 | if (ret) { | ||
| 418 | dev_err(pctldev->dev, | ||
| 419 | "could not get pins for device %s group selector %d\n", | ||
| 420 | pinctrl_dev_get_name(pctldev), setting->data.mux.group); | ||
| 421 | return; | ||
| 422 | } | ||
| 423 | |||
| 424 | for (i = 0; i < num_pins; i++) | ||
| 425 | pin_free(pctldev, pins[i], NULL); | ||
| 426 | } | 382 | } |
| 427 | 383 | ||
| 428 | int pinmux_enable_setting(struct pinctrl_setting const *setting) | 384 | int pinmux_enable_setting(struct pinctrl_setting const *setting) |
| @@ -446,6 +402,22 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) | |||
| 446 | num_pins = 0; | 402 | num_pins = 0; |
| 447 | } | 403 | } |
| 448 | 404 | ||
| 405 | /* Try to allocate all pins in this group, one by one */ | ||
| 406 | for (i = 0; i < num_pins; i++) { | ||
| 407 | ret = pin_request(pctldev, pins[i], setting->dev_name, NULL); | ||
| 408 | if (ret) { | ||
| 409 | dev_err(pctldev->dev, | ||
| 410 | "could not request pin %d on device %s\n", | ||
| 411 | pins[i], pinctrl_dev_get_name(pctldev)); | ||
| 412 | /* On error release all taken pins */ | ||
| 413 | i--; /* this pin just failed */ | ||
| 414 | for (; i >= 0; i--) | ||
| 415 | pin_free(pctldev, pins[i], NULL); | ||
| 416 | return -ENODEV; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | |||
| 420 | /* Now that we have acquired the pins, encode the mux setting */ | ||
| 449 | for (i = 0; i < num_pins; i++) { | 421 | for (i = 0; i < num_pins; i++) { |
| 450 | desc = pin_desc_get(pctldev, pins[i]); | 422 | desc = pin_desc_get(pctldev, pins[i]); |
| 451 | if (desc == NULL) { | 423 | if (desc == NULL) { |
| @@ -482,6 +454,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) | |||
| 482 | num_pins = 0; | 454 | num_pins = 0; |
| 483 | } | 455 | } |
| 484 | 456 | ||
| 457 | /* Flag the descs that no setting is active */ | ||
| 485 | for (i = 0; i < num_pins; i++) { | 458 | for (i = 0; i < num_pins; i++) { |
| 486 | desc = pin_desc_get(pctldev, pins[i]); | 459 | desc = pin_desc_get(pctldev, pins[i]); |
| 487 | if (desc == NULL) { | 460 | if (desc == NULL) { |
| @@ -493,6 +466,10 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) | |||
| 493 | desc->mux_setting = NULL; | 466 | desc->mux_setting = NULL; |
| 494 | } | 467 | } |
| 495 | 468 | ||
| 469 | /* And release the pins */ | ||
| 470 | for (i = 0; i < num_pins; i++) | ||
| 471 | pin_free(pctldev, pins[i], NULL); | ||
| 472 | |||
| 496 | if (ops->disable) | 473 | if (ops->disable) |
| 497 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); | 474 | ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); |
| 498 | } | 475 | } |
diff --git a/drivers/pinctrl/spear/Kconfig b/drivers/pinctrl/spear/Kconfig index 91558791e766..04d93e602674 100644 --- a/drivers/pinctrl/spear/Kconfig +++ b/drivers/pinctrl/spear/Kconfig | |||
| @@ -25,20 +25,31 @@ config PINCTRL_SPEAR310 | |||
| 25 | bool "ST Microelectronics SPEAr310 SoC pin controller driver" | 25 | bool "ST Microelectronics SPEAr310 SoC pin controller driver" |
| 26 | depends on MACH_SPEAR310 | 26 | depends on MACH_SPEAR310 |
| 27 | select PINCTRL_SPEAR3XX | 27 | select PINCTRL_SPEAR3XX |
| 28 | select PINCTRL_SPEAR_PLGPIO | ||
| 28 | 29 | ||
| 29 | config PINCTRL_SPEAR320 | 30 | config PINCTRL_SPEAR320 |
| 30 | bool "ST Microelectronics SPEAr320 SoC pin controller driver" | 31 | bool "ST Microelectronics SPEAr320 SoC pin controller driver" |
| 31 | depends on MACH_SPEAR320 | 32 | depends on MACH_SPEAR320 |
| 32 | select PINCTRL_SPEAR3XX | 33 | select PINCTRL_SPEAR3XX |
| 34 | select PINCTRL_SPEAR_PLGPIO | ||
| 33 | 35 | ||
| 34 | config PINCTRL_SPEAR1310 | 36 | config PINCTRL_SPEAR1310 |
| 35 | bool "ST Microelectronics SPEAr1310 SoC pin controller driver" | 37 | bool "ST Microelectronics SPEAr1310 SoC pin controller driver" |
| 36 | depends on MACH_SPEAR1310 | 38 | depends on MACH_SPEAR1310 |
| 37 | select PINCTRL_SPEAR | 39 | select PINCTRL_SPEAR |
| 40 | select PINCTRL_SPEAR_PLGPIO | ||
| 38 | 41 | ||
| 39 | config PINCTRL_SPEAR1340 | 42 | config PINCTRL_SPEAR1340 |
| 40 | bool "ST Microelectronics SPEAr1340 SoC pin controller driver" | 43 | bool "ST Microelectronics SPEAr1340 SoC pin controller driver" |
| 41 | depends on MACH_SPEAR1340 | 44 | depends on MACH_SPEAR1340 |
| 42 | select PINCTRL_SPEAR | 45 | select PINCTRL_SPEAR |
| 46 | select PINCTRL_SPEAR_PLGPIO | ||
| 47 | |||
| 48 | config PINCTRL_SPEAR_PLGPIO | ||
| 49 | bool "SPEAr SoC PLGPIO Controller" | ||
| 50 | depends on GPIOLIB && PINCTRL_SPEAR | ||
| 51 | help | ||
| 52 | Say yes here to support PLGPIO controller on ST Microelectronics SPEAr | ||
| 53 | SoCs. | ||
| 43 | 54 | ||
| 44 | endif | 55 | endif |
diff --git a/drivers/pinctrl/spear/Makefile b/drivers/pinctrl/spear/Makefile index b28a7ba22443..0e400ebeb8ff 100644 --- a/drivers/pinctrl/spear/Makefile +++ b/drivers/pinctrl/spear/Makefile | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | # SPEAr pinmux support | 1 | # SPEAr pinmux support |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_PINCTRL_SPEAR_PLGPIO) += pinctrl-plgpio.o | ||
| 3 | obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o | 4 | obj-$(CONFIG_PINCTRL_SPEAR) += pinctrl-spear.o |
| 4 | obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o | 5 | obj-$(CONFIG_PINCTRL_SPEAR3XX) += pinctrl-spear3xx.o |
| 5 | obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o | 6 | obj-$(CONFIG_PINCTRL_SPEAR300) += pinctrl-spear300.o |
diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c new file mode 100644 index 000000000000..1044ad3f3c86 --- /dev/null +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c | |||
| @@ -0,0 +1,746 @@ | |||
| 1 | /* | ||
| 2 | * SPEAr platform PLGPIO driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 ST Microelectronics | ||
| 5 | * Viresh Kumar <viresh.kumar@linaro.org> | ||
| 6 | * | ||
| 7 | * This file is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2. This program is licensed "as is" without any | ||
| 9 | * warranty of any kind, whether express or implied. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/clk.h> | ||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/gpio.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/irq.h> | ||
| 17 | #include <linux/irqdomain.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/pinctrl/consumer.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/pm.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <asm/mach/irq.h> | ||
| 24 | |||
| 25 | #define MAX_GPIO_PER_REG 32 | ||
| 26 | #define PIN_OFFSET(pin) (pin % MAX_GPIO_PER_REG) | ||
| 27 | #define REG_OFFSET(base, reg, pin) (base + reg + (pin / MAX_GPIO_PER_REG) \ | ||
| 28 | * sizeof(int *)) | ||
| 29 | |||
| 30 | /* | ||
| 31 | * plgpio pins in all machines are not one to one mapped, bitwise with registers | ||
| 32 | * bits. These set of macros define register masks for which below functions | ||
| 33 | * (pin_to_offset and offset_to_pin) are required to be called. | ||
| 34 | */ | ||
| 35 | #define PTO_ENB_REG 0x001 | ||
| 36 | #define PTO_WDATA_REG 0x002 | ||
| 37 | #define PTO_DIR_REG 0x004 | ||
| 38 | #define PTO_IE_REG 0x008 | ||
| 39 | #define PTO_RDATA_REG 0x010 | ||
| 40 | #define PTO_MIS_REG 0x020 | ||
| 41 | |||
| 42 | struct plgpio_regs { | ||
| 43 | u32 enb; /* enable register */ | ||
| 44 | u32 wdata; /* write data register */ | ||
| 45 | u32 dir; /* direction set register */ | ||
| 46 | u32 rdata; /* read data register */ | ||
| 47 | u32 ie; /* interrupt enable register */ | ||
| 48 | u32 mis; /* mask interrupt status register */ | ||
| 49 | u32 eit; /* edge interrupt type */ | ||
| 50 | }; | ||
| 51 | |||
| 52 | /* | ||
| 53 | * struct plgpio: plgpio driver specific structure | ||
| 54 | * | ||
| 55 | * lock: lock for guarding gpio registers | ||
| 56 | * base: base address of plgpio block | ||
| 57 | * irq_base: irq number of plgpio0 | ||
| 58 | * chip: gpio framework specific chip information structure | ||
| 59 | * p2o: function ptr for pin to offset conversion. This is required only for | ||
| 60 | * machines where mapping b/w pin and offset is not 1-to-1. | ||
| 61 | * o2p: function ptr for offset to pin conversion. This is required only for | ||
| 62 | * machines where mapping b/w pin and offset is not 1-to-1. | ||
| 63 | * p2o_regs: mask of registers for which p2o and o2p are applicable | ||
| 64 | * regs: register offsets | ||
| 65 | * csave_regs: context save registers for standby/sleep/hibernate cases | ||
| 66 | */ | ||
| 67 | struct plgpio { | ||
| 68 | spinlock_t lock; | ||
| 69 | void __iomem *base; | ||
| 70 | struct clk *clk; | ||
| 71 | unsigned irq_base; | ||
| 72 | struct irq_domain *irq_domain; | ||
| 73 | struct gpio_chip chip; | ||
| 74 | int (*p2o)(int pin); /* pin_to_offset */ | ||
| 75 | int (*o2p)(int offset); /* offset_to_pin */ | ||
| 76 | u32 p2o_regs; | ||
| 77 | struct plgpio_regs regs; | ||
| 78 | #ifdef CONFIG_PM | ||
| 79 | struct plgpio_regs *csave_regs; | ||
| 80 | #endif | ||
| 81 | }; | ||
| 82 | |||
| 83 | /* register manipulation inline functions */ | ||
| 84 | static inline u32 is_plgpio_set(void __iomem *base, u32 pin, u32 reg) | ||
| 85 | { | ||
| 86 | u32 offset = PIN_OFFSET(pin); | ||
| 87 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
| 88 | u32 val = readl_relaxed(reg_off); | ||
| 89 | |||
| 90 | return !!(val & (1 << offset)); | ||
| 91 | } | ||
| 92 | |||
| 93 | static inline void plgpio_reg_set(void __iomem *base, u32 pin, u32 reg) | ||
| 94 | { | ||
| 95 | u32 offset = PIN_OFFSET(pin); | ||
| 96 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
| 97 | u32 val = readl_relaxed(reg_off); | ||
| 98 | |||
| 99 | writel_relaxed(val | (1 << offset), reg_off); | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline void plgpio_reg_reset(void __iomem *base, u32 pin, u32 reg) | ||
| 103 | { | ||
| 104 | u32 offset = PIN_OFFSET(pin); | ||
| 105 | void __iomem *reg_off = REG_OFFSET(base, reg, pin); | ||
| 106 | u32 val = readl_relaxed(reg_off); | ||
| 107 | |||
| 108 | writel_relaxed(val & ~(1 << offset), reg_off); | ||
| 109 | } | ||
| 110 | |||
| 111 | /* gpio framework specific routines */ | ||
| 112 | static int plgpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
| 113 | { | ||
| 114 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 115 | unsigned long flags; | ||
| 116 | |||
| 117 | /* get correct offset for "offset" pin */ | ||
| 118 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_DIR_REG)) { | ||
| 119 | offset = plgpio->p2o(offset); | ||
| 120 | if (offset == -1) | ||
| 121 | return -EINVAL; | ||
| 122 | } | ||
| 123 | |||
| 124 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 125 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.dir); | ||
| 126 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 127 | |||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | |||
| 131 | static int plgpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
| 132 | int value) | ||
| 133 | { | ||
| 134 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 135 | unsigned long flags; | ||
| 136 | unsigned dir_offset = offset, wdata_offset = offset, tmp; | ||
| 137 | |||
| 138 | /* get correct offset for "offset" pin */ | ||
| 139 | if (plgpio->p2o && (plgpio->p2o_regs & (PTO_DIR_REG | PTO_WDATA_REG))) { | ||
| 140 | tmp = plgpio->p2o(offset); | ||
| 141 | if (tmp == -1) | ||
| 142 | return -EINVAL; | ||
| 143 | |||
| 144 | if (plgpio->p2o_regs & PTO_DIR_REG) | ||
| 145 | dir_offset = tmp; | ||
| 146 | if (plgpio->p2o_regs & PTO_WDATA_REG) | ||
| 147 | wdata_offset = tmp; | ||
| 148 | } | ||
| 149 | |||
| 150 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 151 | if (value) | ||
| 152 | plgpio_reg_set(plgpio->base, wdata_offset, | ||
| 153 | plgpio->regs.wdata); | ||
| 154 | else | ||
| 155 | plgpio_reg_reset(plgpio->base, wdata_offset, | ||
| 156 | plgpio->regs.wdata); | ||
| 157 | |||
| 158 | plgpio_reg_reset(plgpio->base, dir_offset, plgpio->regs.dir); | ||
| 159 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int plgpio_get_value(struct gpio_chip *chip, unsigned offset) | ||
| 165 | { | ||
| 166 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 167 | |||
| 168 | if (offset >= chip->ngpio) | ||
| 169 | return -EINVAL; | ||
| 170 | |||
| 171 | /* get correct offset for "offset" pin */ | ||
| 172 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_RDATA_REG)) { | ||
| 173 | offset = plgpio->p2o(offset); | ||
| 174 | if (offset == -1) | ||
| 175 | return -EINVAL; | ||
| 176 | } | ||
| 177 | |||
| 178 | return is_plgpio_set(plgpio->base, offset, plgpio->regs.rdata); | ||
| 179 | } | ||
| 180 | |||
| 181 | static void plgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) | ||
| 182 | { | ||
| 183 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 184 | |||
| 185 | if (offset >= chip->ngpio) | ||
| 186 | return; | ||
| 187 | |||
| 188 | /* get correct offset for "offset" pin */ | ||
| 189 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_WDATA_REG)) { | ||
| 190 | offset = plgpio->p2o(offset); | ||
| 191 | if (offset == -1) | ||
| 192 | return; | ||
| 193 | } | ||
| 194 | |||
| 195 | if (value) | ||
| 196 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.wdata); | ||
| 197 | else | ||
| 198 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.wdata); | ||
| 199 | } | ||
| 200 | |||
| 201 | static int plgpio_request(struct gpio_chip *chip, unsigned offset) | ||
| 202 | { | ||
| 203 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 204 | int gpio = chip->base + offset; | ||
| 205 | unsigned long flags; | ||
| 206 | int ret = 0; | ||
| 207 | |||
| 208 | if (offset >= chip->ngpio) | ||
| 209 | return -EINVAL; | ||
| 210 | |||
| 211 | ret = pinctrl_request_gpio(gpio); | ||
| 212 | if (ret) | ||
| 213 | return ret; | ||
| 214 | |||
| 215 | if (!IS_ERR(plgpio->clk)) { | ||
| 216 | ret = clk_prepare_enable(plgpio->clk); | ||
| 217 | if (ret) | ||
| 218 | goto err0; | ||
| 219 | } | ||
| 220 | |||
| 221 | if (plgpio->regs.enb == -1) | ||
| 222 | return 0; | ||
| 223 | |||
| 224 | /* | ||
| 225 | * put gpio in IN mode before enabling it. This make enabling gpio safe | ||
| 226 | */ | ||
| 227 | ret = plgpio_direction_input(chip, offset); | ||
| 228 | if (ret) | ||
| 229 | goto err1; | ||
| 230 | |||
| 231 | /* get correct offset for "offset" pin */ | ||
| 232 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { | ||
| 233 | offset = plgpio->p2o(offset); | ||
| 234 | if (offset == -1) { | ||
| 235 | ret = -EINVAL; | ||
| 236 | goto err1; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 241 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.enb); | ||
| 242 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 243 | return 0; | ||
| 244 | |||
| 245 | err1: | ||
| 246 | clk_disable_unprepare(plgpio->clk); | ||
| 247 | err0: | ||
| 248 | pinctrl_free_gpio(gpio); | ||
| 249 | return ret; | ||
| 250 | } | ||
| 251 | |||
| 252 | static void plgpio_free(struct gpio_chip *chip, unsigned offset) | ||
| 253 | { | ||
| 254 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 255 | int gpio = chip->base + offset; | ||
| 256 | unsigned long flags; | ||
| 257 | |||
| 258 | if (offset >= chip->ngpio) | ||
| 259 | return; | ||
| 260 | |||
| 261 | if (plgpio->regs.enb == -1) | ||
| 262 | goto disable_clk; | ||
| 263 | |||
| 264 | /* get correct offset for "offset" pin */ | ||
| 265 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_ENB_REG)) { | ||
| 266 | offset = plgpio->p2o(offset); | ||
| 267 | if (offset == -1) | ||
| 268 | return; | ||
| 269 | } | ||
| 270 | |||
| 271 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 272 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.enb); | ||
| 273 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 274 | |||
| 275 | disable_clk: | ||
| 276 | if (!IS_ERR(plgpio->clk)) | ||
| 277 | clk_disable_unprepare(plgpio->clk); | ||
| 278 | |||
| 279 | pinctrl_free_gpio(gpio); | ||
| 280 | } | ||
| 281 | |||
| 282 | static int plgpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
| 283 | { | ||
| 284 | struct plgpio *plgpio = container_of(chip, struct plgpio, chip); | ||
| 285 | |||
| 286 | if (plgpio->irq_base < 0) | ||
| 287 | return -EINVAL; | ||
| 288 | |||
| 289 | return irq_find_mapping(plgpio->irq_domain, offset); | ||
| 290 | } | ||
| 291 | |||
| 292 | /* PLGPIO IRQ */ | ||
| 293 | static void plgpio_irq_disable(struct irq_data *d) | ||
| 294 | { | ||
| 295 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
| 296 | int offset = d->irq - plgpio->irq_base; | ||
| 297 | unsigned long flags; | ||
| 298 | |||
| 299 | /* get correct offset for "offset" pin */ | ||
| 300 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { | ||
| 301 | offset = plgpio->p2o(offset); | ||
| 302 | if (offset == -1) | ||
| 303 | return; | ||
| 304 | } | ||
| 305 | |||
| 306 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 307 | plgpio_reg_set(plgpio->base, offset, plgpio->regs.ie); | ||
| 308 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 309 | } | ||
| 310 | |||
| 311 | static void plgpio_irq_enable(struct irq_data *d) | ||
| 312 | { | ||
| 313 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
| 314 | int offset = d->irq - plgpio->irq_base; | ||
| 315 | unsigned long flags; | ||
| 316 | |||
| 317 | /* get correct offset for "offset" pin */ | ||
| 318 | if (plgpio->p2o && (plgpio->p2o_regs & PTO_IE_REG)) { | ||
| 319 | offset = plgpio->p2o(offset); | ||
| 320 | if (offset == -1) | ||
| 321 | return; | ||
| 322 | } | ||
| 323 | |||
| 324 | spin_lock_irqsave(&plgpio->lock, flags); | ||
| 325 | plgpio_reg_reset(plgpio->base, offset, plgpio->regs.ie); | ||
| 326 | spin_unlock_irqrestore(&plgpio->lock, flags); | ||
| 327 | } | ||
| 328 | |||
| 329 | static int plgpio_irq_set_type(struct irq_data *d, unsigned trigger) | ||
| 330 | { | ||
| 331 | struct plgpio *plgpio = irq_data_get_irq_chip_data(d); | ||
| 332 | int offset = d->irq - plgpio->irq_base; | ||
| 333 | void __iomem *reg_off; | ||
| 334 | unsigned int supported_type = 0, val; | ||
| 335 | |||
| 336 | if (offset >= plgpio->chip.ngpio) | ||
| 337 | return -EINVAL; | ||
| 338 | |||
| 339 | if (plgpio->regs.eit == -1) | ||
| 340 | supported_type = IRQ_TYPE_LEVEL_HIGH; | ||
| 341 | else | ||
| 342 | supported_type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | ||
| 343 | |||
| 344 | if (!(trigger & supported_type)) | ||
| 345 | return -EINVAL; | ||
| 346 | |||
| 347 | if (plgpio->regs.eit == -1) | ||
| 348 | return 0; | ||
| 349 | |||
| 350 | reg_off = REG_OFFSET(plgpio->base, plgpio->regs.eit, offset); | ||
| 351 | val = readl_relaxed(reg_off); | ||
| 352 | |||
| 353 | offset = PIN_OFFSET(offset); | ||
| 354 | if (trigger & IRQ_TYPE_EDGE_RISING) | ||
| 355 | writel_relaxed(val | (1 << offset), reg_off); | ||
| 356 | else | ||
| 357 | writel_relaxed(val & ~(1 << offset), reg_off); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static struct irq_chip plgpio_irqchip = { | ||
| 363 | .name = "PLGPIO", | ||
| 364 | .irq_enable = plgpio_irq_enable, | ||
| 365 | .irq_disable = plgpio_irq_disable, | ||
| 366 | .irq_set_type = plgpio_irq_set_type, | ||
| 367 | }; | ||
| 368 | |||
| 369 | static void plgpio_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 370 | { | ||
| 371 | struct plgpio *plgpio = irq_get_handler_data(irq); | ||
| 372 | struct irq_chip *irqchip = irq_desc_get_chip(desc); | ||
| 373 | int regs_count, count, pin, offset, i = 0; | ||
| 374 | unsigned long pending; | ||
| 375 | |||
| 376 | count = plgpio->chip.ngpio; | ||
| 377 | regs_count = DIV_ROUND_UP(count, MAX_GPIO_PER_REG); | ||
| 378 | |||
| 379 | chained_irq_enter(irqchip, desc); | ||
| 380 | /* check all plgpio MIS registers for a possible interrupt */ | ||
| 381 | for (; i < regs_count; i++) { | ||
| 382 | pending = readl_relaxed(plgpio->base + plgpio->regs.mis + | ||
| 383 | i * sizeof(int *)); | ||
| 384 | if (!pending) | ||
| 385 | continue; | ||
| 386 | |||
| 387 | /* clear interrupts */ | ||
| 388 | writel_relaxed(~pending, plgpio->base + plgpio->regs.mis + | ||
| 389 | i * sizeof(int *)); | ||
| 390 | /* | ||
| 391 | * clear extra bits in last register having gpios < MAX/REG | ||
| 392 | * ex: Suppose there are max 102 plgpios. then last register | ||
| 393 | * must have only (102 - MAX_GPIO_PER_REG * 3) = 6 relevant bits | ||
| 394 | * so, we must not take other 28 bits into consideration for | ||
| 395 | * checking interrupt. so clear those bits. | ||
| 396 | */ | ||
| 397 | count = count - i * MAX_GPIO_PER_REG; | ||
| 398 | if (count < MAX_GPIO_PER_REG) | ||
| 399 | pending &= (1 << count) - 1; | ||
| 400 | |||
| 401 | for_each_set_bit(offset, &pending, MAX_GPIO_PER_REG) { | ||
| 402 | /* get correct pin for "offset" */ | ||
| 403 | if (plgpio->o2p && (plgpio->p2o_regs & PTO_MIS_REG)) { | ||
| 404 | pin = plgpio->o2p(offset); | ||
| 405 | if (pin == -1) | ||
| 406 | continue; | ||
| 407 | } else | ||
| 408 | pin = offset; | ||
| 409 | |||
| 410 | /* get correct irq line number */ | ||
| 411 | pin = i * MAX_GPIO_PER_REG + pin; | ||
| 412 | generic_handle_irq(plgpio_to_irq(&plgpio->chip, pin)); | ||
| 413 | } | ||
| 414 | } | ||
| 415 | chained_irq_exit(irqchip, desc); | ||
| 416 | } | ||
| 417 | |||
| 418 | /* | ||
| 419 | * pin to offset and offset to pin converter functions | ||
| 420 | * | ||
| 421 | * In spear310 there is inconsistency among bit positions in plgpio regiseters, | ||
| 422 | * for different plgpio pins. For example: for pin 27, bit offset is 23, pin | ||
| 423 | * 28-33 are not supported, pin 95 has offset bit 95, bit 100 has offset bit 1 | ||
| 424 | */ | ||
| 425 | static int spear310_p2o(int pin) | ||
| 426 | { | ||
| 427 | int offset = pin; | ||
| 428 | |||
| 429 | if (pin <= 27) | ||
| 430 | offset += 4; | ||
| 431 | else if (pin <= 33) | ||
| 432 | offset = -1; | ||
| 433 | else if (pin <= 97) | ||
| 434 | offset -= 2; | ||
| 435 | else if (pin <= 101) | ||
| 436 | offset = 101 - pin; | ||
| 437 | else | ||
| 438 | offset = -1; | ||
| 439 | |||
| 440 | return offset; | ||
| 441 | } | ||
| 442 | |||
| 443 | int spear310_o2p(int offset) | ||
| 444 | { | ||
| 445 | if (offset <= 3) | ||
| 446 | return 101 - offset; | ||
| 447 | else if (offset <= 31) | ||
| 448 | return offset - 4; | ||
| 449 | else | ||
| 450 | return offset + 2; | ||
| 451 | } | ||
| 452 | |||
| 453 | static int __devinit plgpio_probe_dt(struct platform_device *pdev, | ||
| 454 | struct plgpio *plgpio) | ||
| 455 | { | ||
| 456 | struct device_node *np = pdev->dev.of_node; | ||
| 457 | int ret = -EINVAL; | ||
| 458 | u32 val; | ||
| 459 | |||
| 460 | if (of_machine_is_compatible("st,spear310")) { | ||
| 461 | plgpio->p2o = spear310_p2o; | ||
| 462 | plgpio->o2p = spear310_o2p; | ||
| 463 | plgpio->p2o_regs = PTO_WDATA_REG | PTO_DIR_REG | PTO_IE_REG | | ||
| 464 | PTO_RDATA_REG | PTO_MIS_REG; | ||
| 465 | } | ||
| 466 | |||
| 467 | if (!of_property_read_u32(np, "st-plgpio,ngpio", &val)) { | ||
| 468 | plgpio->chip.ngpio = val; | ||
| 469 | } else { | ||
| 470 | dev_err(&pdev->dev, "DT: Invalid ngpio field\n"); | ||
| 471 | goto end; | ||
| 472 | } | ||
| 473 | |||
| 474 | if (!of_property_read_u32(np, "st-plgpio,enb-reg", &val)) | ||
| 475 | plgpio->regs.enb = val; | ||
| 476 | else | ||
| 477 | plgpio->regs.enb = -1; | ||
| 478 | |||
| 479 | if (!of_property_read_u32(np, "st-plgpio,wdata-reg", &val)) { | ||
| 480 | plgpio->regs.wdata = val; | ||
| 481 | } else { | ||
| 482 | dev_err(&pdev->dev, "DT: Invalid wdata reg\n"); | ||
| 483 | goto end; | ||
| 484 | } | ||
| 485 | |||
| 486 | if (!of_property_read_u32(np, "st-plgpio,dir-reg", &val)) { | ||
| 487 | plgpio->regs.dir = val; | ||
| 488 | } else { | ||
| 489 | dev_err(&pdev->dev, "DT: Invalid dir reg\n"); | ||
| 490 | goto end; | ||
| 491 | } | ||
| 492 | |||
| 493 | if (!of_property_read_u32(np, "st-plgpio,ie-reg", &val)) { | ||
| 494 | plgpio->regs.ie = val; | ||
| 495 | } else { | ||
| 496 | dev_err(&pdev->dev, "DT: Invalid ie reg\n"); | ||
| 497 | goto end; | ||
| 498 | } | ||
| 499 | |||
| 500 | if (!of_property_read_u32(np, "st-plgpio,rdata-reg", &val)) { | ||
| 501 | plgpio->regs.rdata = val; | ||
| 502 | } else { | ||
| 503 | dev_err(&pdev->dev, "DT: Invalid rdata reg\n"); | ||
| 504 | goto end; | ||
| 505 | } | ||
| 506 | |||
| 507 | if (!of_property_read_u32(np, "st-plgpio,mis-reg", &val)) { | ||
| 508 | plgpio->regs.mis = val; | ||
| 509 | } else { | ||
| 510 | dev_err(&pdev->dev, "DT: Invalid mis reg\n"); | ||
| 511 | goto end; | ||
| 512 | } | ||
| 513 | |||
| 514 | if (!of_property_read_u32(np, "st-plgpio,eit-reg", &val)) | ||
| 515 | plgpio->regs.eit = val; | ||
| 516 | else | ||
| 517 | plgpio->regs.eit = -1; | ||
| 518 | |||
| 519 | return 0; | ||
| 520 | |||
| 521 | end: | ||
| 522 | return ret; | ||
| 523 | } | ||
| 524 | static int __devinit plgpio_probe(struct platform_device *pdev) | ||
| 525 | { | ||
| 526 | struct device_node *np = pdev->dev.of_node; | ||
| 527 | struct plgpio *plgpio; | ||
| 528 | struct resource *res; | ||
| 529 | int ret, irq, i; | ||
| 530 | |||
| 531 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 532 | if (!res) { | ||
| 533 | dev_err(&pdev->dev, "invalid IORESOURCE_MEM\n"); | ||
| 534 | return -EBUSY; | ||
| 535 | } | ||
| 536 | |||
| 537 | plgpio = devm_kzalloc(&pdev->dev, sizeof(*plgpio), GFP_KERNEL); | ||
| 538 | if (!plgpio) { | ||
| 539 | dev_err(&pdev->dev, "memory allocation fail\n"); | ||
| 540 | return -ENOMEM; | ||
| 541 | } | ||
| 542 | |||
| 543 | plgpio->base = devm_request_and_ioremap(&pdev->dev, res); | ||
| 544 | if (!plgpio->base) { | ||
| 545 | dev_err(&pdev->dev, "request and ioremap fail\n"); | ||
| 546 | return -ENOMEM; | ||
| 547 | } | ||
| 548 | |||
| 549 | ret = plgpio_probe_dt(pdev, plgpio); | ||
| 550 | if (ret) { | ||
| 551 | dev_err(&pdev->dev, "DT probe failed\n"); | ||
| 552 | return ret; | ||
| 553 | } | ||
| 554 | |||
| 555 | plgpio->clk = devm_clk_get(&pdev->dev, NULL); | ||
| 556 | if (IS_ERR(plgpio->clk)) | ||
| 557 | dev_warn(&pdev->dev, "clk_get() failed, work without it\n"); | ||
| 558 | |||
| 559 | #ifdef CONFIG_PM | ||
| 560 | plgpio->csave_regs = devm_kzalloc(&pdev->dev, | ||
| 561 | sizeof(*plgpio->csave_regs) * | ||
| 562 | DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG), | ||
| 563 | GFP_KERNEL); | ||
| 564 | if (!plgpio->csave_regs) { | ||
| 565 | dev_err(&pdev->dev, "csave registers memory allocation fail\n"); | ||
| 566 | return -ENOMEM; | ||
| 567 | } | ||
| 568 | #endif | ||
| 569 | |||
| 570 | platform_set_drvdata(pdev, plgpio); | ||
| 571 | spin_lock_init(&plgpio->lock); | ||
| 572 | |||
| 573 | plgpio->irq_base = -1; | ||
| 574 | plgpio->chip.base = -1; | ||
| 575 | plgpio->chip.request = plgpio_request; | ||
| 576 | plgpio->chip.free = plgpio_free; | ||
| 577 | plgpio->chip.direction_input = plgpio_direction_input; | ||
| 578 | plgpio->chip.direction_output = plgpio_direction_output; | ||
| 579 | plgpio->chip.get = plgpio_get_value; | ||
| 580 | plgpio->chip.set = plgpio_set_value; | ||
| 581 | plgpio->chip.to_irq = plgpio_to_irq; | ||
| 582 | plgpio->chip.label = dev_name(&pdev->dev); | ||
| 583 | plgpio->chip.dev = &pdev->dev; | ||
| 584 | plgpio->chip.owner = THIS_MODULE; | ||
| 585 | |||
| 586 | ret = gpiochip_add(&plgpio->chip); | ||
| 587 | if (ret) { | ||
| 588 | dev_err(&pdev->dev, "unable to add gpio chip\n"); | ||
| 589 | return ret; | ||
| 590 | } | ||
| 591 | |||
| 592 | irq = platform_get_irq(pdev, 0); | ||
| 593 | if (irq < 0) { | ||
| 594 | dev_info(&pdev->dev, "irqs not supported\n"); | ||
| 595 | return 0; | ||
| 596 | } | ||
| 597 | |||
| 598 | plgpio->irq_base = irq_alloc_descs(-1, 0, plgpio->chip.ngpio, 0); | ||
| 599 | if (IS_ERR_VALUE(plgpio->irq_base)) { | ||
| 600 | /* we would not support irq for gpio */ | ||
| 601 | dev_warn(&pdev->dev, "couldn't allocate irq base\n"); | ||
| 602 | return 0; | ||
| 603 | } | ||
| 604 | |||
| 605 | plgpio->irq_domain = irq_domain_add_legacy(np, plgpio->chip.ngpio, | ||
| 606 | plgpio->irq_base, 0, &irq_domain_simple_ops, NULL); | ||
| 607 | if (WARN_ON(!plgpio->irq_domain)) { | ||
| 608 | dev_err(&pdev->dev, "irq domain init failed\n"); | ||
| 609 | irq_free_descs(plgpio->irq_base, plgpio->chip.ngpio); | ||
| 610 | ret = -ENXIO; | ||
| 611 | goto remove_gpiochip; | ||
| 612 | } | ||
| 613 | |||
| 614 | irq_set_chained_handler(irq, plgpio_irq_handler); | ||
| 615 | for (i = 0; i < plgpio->chip.ngpio; i++) { | ||
| 616 | irq_set_chip_and_handler(i + plgpio->irq_base, &plgpio_irqchip, | ||
| 617 | handle_simple_irq); | ||
| 618 | set_irq_flags(i + plgpio->irq_base, IRQF_VALID); | ||
| 619 | irq_set_chip_data(i + plgpio->irq_base, plgpio); | ||
| 620 | } | ||
| 621 | |||
| 622 | irq_set_handler_data(irq, plgpio); | ||
| 623 | dev_info(&pdev->dev, "PLGPIO registered with IRQs\n"); | ||
| 624 | |||
| 625 | return 0; | ||
| 626 | |||
| 627 | remove_gpiochip: | ||
| 628 | dev_info(&pdev->dev, "Remove gpiochip\n"); | ||
| 629 | if (gpiochip_remove(&plgpio->chip)) | ||
| 630 | dev_err(&pdev->dev, "unable to remove gpiochip\n"); | ||
| 631 | |||
| 632 | return ret; | ||
| 633 | } | ||
| 634 | |||
| 635 | #ifdef CONFIG_PM | ||
| 636 | static int plgpio_suspend(struct device *dev) | ||
| 637 | { | ||
| 638 | struct plgpio *plgpio = dev_get_drvdata(dev); | ||
| 639 | int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); | ||
| 640 | void __iomem *off; | ||
| 641 | |||
| 642 | for (i = 0; i < reg_count; i++) { | ||
| 643 | off = plgpio->base + i * sizeof(int *); | ||
| 644 | |||
| 645 | if (plgpio->regs.enb != -1) | ||
| 646 | plgpio->csave_regs[i].enb = | ||
| 647 | readl_relaxed(plgpio->regs.enb + off); | ||
| 648 | if (plgpio->regs.eit != -1) | ||
| 649 | plgpio->csave_regs[i].eit = | ||
| 650 | readl_relaxed(plgpio->regs.eit + off); | ||
| 651 | plgpio->csave_regs[i].wdata = readl_relaxed(plgpio->regs.wdata + | ||
| 652 | off); | ||
| 653 | plgpio->csave_regs[i].dir = readl_relaxed(plgpio->regs.dir + | ||
| 654 | off); | ||
| 655 | plgpio->csave_regs[i].ie = readl_relaxed(plgpio->regs.ie + off); | ||
| 656 | } | ||
| 657 | |||
| 658 | return 0; | ||
| 659 | } | ||
| 660 | |||
| 661 | /* | ||
| 662 | * This is used to correct the values in end registers. End registers contain | ||
| 663 | * extra bits that might be used for other purpose in platform. So, we shouldn't | ||
| 664 | * overwrite these bits. This macro, reads given register again, preserves other | ||
| 665 | * bit values (non-plgpio bits), and retain captured value (plgpio bits). | ||
| 666 | */ | ||
| 667 | #define plgpio_prepare_reg(__reg, _off, _mask, _tmp) \ | ||
| 668 | { \ | ||
| 669 | _tmp = readl_relaxed(plgpio->regs.__reg + _off); \ | ||
| 670 | _tmp &= ~_mask; \ | ||
| 671 | plgpio->csave_regs[i].__reg = \ | ||
| 672 | _tmp | (plgpio->csave_regs[i].__reg & _mask); \ | ||
| 673 | } | ||
| 674 | |||
| 675 | static int plgpio_resume(struct device *dev) | ||
| 676 | { | ||
| 677 | struct plgpio *plgpio = dev_get_drvdata(dev); | ||
| 678 | int i, reg_count = DIV_ROUND_UP(plgpio->chip.ngpio, MAX_GPIO_PER_REG); | ||
| 679 | void __iomem *off; | ||
| 680 | u32 mask, tmp; | ||
| 681 | |||
| 682 | for (i = 0; i < reg_count; i++) { | ||
| 683 | off = plgpio->base + i * sizeof(int *); | ||
| 684 | |||
| 685 | if (i == reg_count - 1) { | ||
| 686 | mask = (1 << (plgpio->chip.ngpio - i * | ||
| 687 | MAX_GPIO_PER_REG)) - 1; | ||
| 688 | |||
| 689 | if (plgpio->regs.enb != -1) | ||
| 690 | plgpio_prepare_reg(enb, off, mask, tmp); | ||
| 691 | |||
| 692 | if (plgpio->regs.eit != -1) | ||
| 693 | plgpio_prepare_reg(eit, off, mask, tmp); | ||
| 694 | |||
| 695 | plgpio_prepare_reg(wdata, off, mask, tmp); | ||
| 696 | plgpio_prepare_reg(dir, off, mask, tmp); | ||
| 697 | plgpio_prepare_reg(ie, off, mask, tmp); | ||
| 698 | } | ||
| 699 | |||
| 700 | writel_relaxed(plgpio->csave_regs[i].wdata, plgpio->regs.wdata + | ||
| 701 | off); | ||
| 702 | writel_relaxed(plgpio->csave_regs[i].dir, plgpio->regs.dir + | ||
| 703 | off); | ||
| 704 | |||
| 705 | if (plgpio->regs.eit != -1) | ||
| 706 | writel_relaxed(plgpio->csave_regs[i].eit, | ||
| 707 | plgpio->regs.eit + off); | ||
| 708 | |||
| 709 | writel_relaxed(plgpio->csave_regs[i].ie, plgpio->regs.ie + off); | ||
| 710 | |||
| 711 | if (plgpio->regs.enb != -1) | ||
| 712 | writel_relaxed(plgpio->csave_regs[i].enb, | ||
| 713 | plgpio->regs.enb + off); | ||
| 714 | } | ||
| 715 | |||
| 716 | return 0; | ||
| 717 | } | ||
| 718 | #endif | ||
| 719 | |||
| 720 | static SIMPLE_DEV_PM_OPS(plgpio_dev_pm_ops, plgpio_suspend, plgpio_resume); | ||
| 721 | |||
| 722 | static const struct of_device_id plgpio_of_match[] = { | ||
| 723 | { .compatible = "st,spear-plgpio" }, | ||
| 724 | {} | ||
| 725 | }; | ||
| 726 | MODULE_DEVICE_TABLE(of, plgpio_of_match); | ||
| 727 | |||
| 728 | static struct platform_driver plgpio_driver = { | ||
| 729 | .probe = plgpio_probe, | ||
| 730 | .driver = { | ||
| 731 | .owner = THIS_MODULE, | ||
| 732 | .name = "spear-plgpio", | ||
| 733 | .pm = &plgpio_dev_pm_ops, | ||
| 734 | .of_match_table = of_match_ptr(plgpio_of_match), | ||
| 735 | }, | ||
| 736 | }; | ||
| 737 | |||
| 738 | static int __init plgpio_init(void) | ||
| 739 | { | ||
| 740 | return platform_driver_register(&plgpio_driver); | ||
| 741 | } | ||
| 742 | subsys_initcall(plgpio_init); | ||
| 743 | |||
| 744 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.org>"); | ||
| 745 | MODULE_DESCRIPTION("ST Microlectronics SPEAr PLGPIO driver"); | ||
| 746 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index b1fd6ee33c6c..cbca6dc66eb7 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 20 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
| 21 | #include <linux/of_gpio.h> | ||
| 21 | #include <linux/pinctrl/machine.h> | 22 | #include <linux/pinctrl/machine.h> |
| 22 | #include <linux/pinctrl/pinctrl.h> | 23 | #include <linux/pinctrl/pinctrl.h> |
| 23 | #include <linux/pinctrl/pinmux.h> | 24 | #include <linux/pinctrl/pinmux.h> |
| @@ -38,6 +39,28 @@ static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg) | |||
| 38 | writel_relaxed(val, pmx->vbase + reg); | 39 | writel_relaxed(val, pmx->vbase + reg); |
| 39 | } | 40 | } |
| 40 | 41 | ||
| 42 | static void muxregs_endisable(struct spear_pmx *pmx, | ||
| 43 | struct spear_muxreg *muxregs, u8 count, bool enable) | ||
| 44 | { | ||
| 45 | struct spear_muxreg *muxreg; | ||
| 46 | u32 val, temp, j; | ||
| 47 | |||
| 48 | for (j = 0; j < count; j++) { | ||
| 49 | muxreg = &muxregs[j]; | ||
| 50 | |||
| 51 | val = pmx_readl(pmx, muxreg->reg); | ||
| 52 | val &= ~muxreg->mask; | ||
| 53 | |||
| 54 | if (enable) | ||
| 55 | temp = muxreg->val; | ||
| 56 | else | ||
| 57 | temp = ~muxreg->val; | ||
| 58 | |||
| 59 | val |= muxreg->mask & temp; | ||
| 60 | pmx_writel(pmx, val, muxreg->reg); | ||
| 61 | } | ||
| 62 | } | ||
| 63 | |||
| 41 | static int set_mode(struct spear_pmx *pmx, int mode) | 64 | static int set_mode(struct spear_pmx *pmx, int mode) |
| 42 | { | 65 | { |
| 43 | struct spear_pmx_mode *pmx_mode = NULL; | 66 | struct spear_pmx_mode *pmx_mode = NULL; |
| @@ -70,6 +93,17 @@ static int set_mode(struct spear_pmx *pmx, int mode) | |||
| 70 | return 0; | 93 | return 0; |
| 71 | } | 94 | } |
| 72 | 95 | ||
| 96 | void __devinit | ||
| 97 | pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, | ||
| 98 | unsigned count, u16 reg) | ||
| 99 | { | ||
| 100 | int i = 0, j = 0; | ||
| 101 | |||
| 102 | for (; i < count; i++) | ||
| 103 | for (; j < gpio_pingroup[i].nmuxregs; j++) | ||
| 104 | gpio_pingroup[i].muxregs[j].reg = reg; | ||
| 105 | } | ||
| 106 | |||
| 73 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) | 107 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg) |
| 74 | { | 108 | { |
| 75 | struct spear_pingroup *pgroup; | 109 | struct spear_pingroup *pgroup; |
| @@ -216,9 +250,7 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
| 216 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); | 250 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); |
| 217 | const struct spear_pingroup *pgroup; | 251 | const struct spear_pingroup *pgroup; |
| 218 | const struct spear_modemux *modemux; | 252 | const struct spear_modemux *modemux; |
| 219 | struct spear_muxreg *muxreg; | 253 | int i; |
| 220 | u32 val, temp; | ||
| 221 | int i, j; | ||
| 222 | bool found = false; | 254 | bool found = false; |
| 223 | 255 | ||
| 224 | pgroup = pmx->machdata->groups[group]; | 256 | pgroup = pmx->machdata->groups[group]; |
| @@ -233,20 +265,8 @@ static int spear_pinctrl_endisable(struct pinctrl_dev *pctldev, | |||
| 233 | } | 265 | } |
| 234 | 266 | ||
| 235 | found = true; | 267 | found = true; |
| 236 | for (j = 0; j < modemux->nmuxregs; j++) { | 268 | muxregs_endisable(pmx, modemux->muxregs, modemux->nmuxregs, |
| 237 | muxreg = &modemux->muxregs[j]; | 269 | enable); |
| 238 | |||
| 239 | val = pmx_readl(pmx, muxreg->reg); | ||
| 240 | val &= ~muxreg->mask; | ||
| 241 | |||
| 242 | if (enable) | ||
| 243 | temp = muxreg->val; | ||
| 244 | else | ||
| 245 | temp = ~muxreg->val; | ||
| 246 | |||
| 247 | val |= muxreg->mask & temp; | ||
| 248 | pmx_writel(pmx, val, muxreg->reg); | ||
| 249 | } | ||
| 250 | } | 270 | } |
| 251 | 271 | ||
| 252 | if (!found) { | 272 | if (!found) { |
| @@ -270,12 +290,65 @@ static void spear_pinctrl_disable(struct pinctrl_dev *pctldev, | |||
| 270 | spear_pinctrl_endisable(pctldev, function, group, false); | 290 | spear_pinctrl_endisable(pctldev, function, group, false); |
| 271 | } | 291 | } |
| 272 | 292 | ||
| 293 | /* gpio with pinmux */ | ||
| 294 | static struct spear_gpio_pingroup *get_gpio_pingroup(struct spear_pmx *pmx, | ||
| 295 | unsigned pin) | ||
| 296 | { | ||
| 297 | struct spear_gpio_pingroup *gpio_pingroup; | ||
| 298 | int i = 0, j; | ||
| 299 | |||
| 300 | if (!pmx->machdata->gpio_pingroups) | ||
| 301 | return NULL; | ||
| 302 | |||
| 303 | for (; i < pmx->machdata->ngpio_pingroups; i++) { | ||
| 304 | gpio_pingroup = &pmx->machdata->gpio_pingroups[i]; | ||
| 305 | |||
| 306 | for (j = 0; j < gpio_pingroup->npins; j++) { | ||
| 307 | if (gpio_pingroup->pins[j] == pin) | ||
| 308 | return gpio_pingroup; | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | return ERR_PTR(-EINVAL); | ||
| 313 | } | ||
| 314 | |||
| 315 | static int gpio_request_endisable(struct pinctrl_dev *pctldev, | ||
| 316 | struct pinctrl_gpio_range *range, unsigned offset, bool enable) | ||
| 317 | { | ||
| 318 | struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); | ||
| 319 | struct spear_gpio_pingroup *gpio_pingroup; | ||
| 320 | |||
| 321 | gpio_pingroup = get_gpio_pingroup(pmx, offset); | ||
| 322 | if (IS_ERR(gpio_pingroup)) | ||
| 323 | return PTR_ERR(gpio_pingroup); | ||
| 324 | |||
| 325 | if (gpio_pingroup) | ||
| 326 | muxregs_endisable(pmx, gpio_pingroup->muxregs, | ||
| 327 | gpio_pingroup->nmuxregs, enable); | ||
| 328 | |||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static int gpio_request_enable(struct pinctrl_dev *pctldev, | ||
| 333 | struct pinctrl_gpio_range *range, unsigned offset) | ||
| 334 | { | ||
| 335 | return gpio_request_endisable(pctldev, range, offset, true); | ||
| 336 | } | ||
| 337 | |||
| 338 | static void gpio_disable_free(struct pinctrl_dev *pctldev, | ||
| 339 | struct pinctrl_gpio_range *range, unsigned offset) | ||
| 340 | { | ||
| 341 | gpio_request_endisable(pctldev, range, offset, false); | ||
| 342 | } | ||
| 343 | |||
| 273 | static struct pinmux_ops spear_pinmux_ops = { | 344 | static struct pinmux_ops spear_pinmux_ops = { |
| 274 | .get_functions_count = spear_pinctrl_get_funcs_count, | 345 | .get_functions_count = spear_pinctrl_get_funcs_count, |
| 275 | .get_function_name = spear_pinctrl_get_func_name, | 346 | .get_function_name = spear_pinctrl_get_func_name, |
| 276 | .get_function_groups = spear_pinctrl_get_func_groups, | 347 | .get_function_groups = spear_pinctrl_get_func_groups, |
| 277 | .enable = spear_pinctrl_enable, | 348 | .enable = spear_pinctrl_enable, |
| 278 | .disable = spear_pinctrl_disable, | 349 | .disable = spear_pinctrl_disable, |
| 350 | .gpio_request_enable = gpio_request_enable, | ||
| 351 | .gpio_disable_free = gpio_disable_free, | ||
| 279 | }; | 352 | }; |
| 280 | 353 | ||
| 281 | static struct pinctrl_desc spear_pinctrl_desc = { | 354 | static struct pinctrl_desc spear_pinctrl_desc = { |
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index d950eb78d939..94f142c10c19 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #ifndef __PINMUX_SPEAR_H__ | 12 | #ifndef __PINMUX_SPEAR_H__ |
| 13 | #define __PINMUX_SPEAR_H__ | 13 | #define __PINMUX_SPEAR_H__ |
| 14 | 14 | ||
| 15 | #include <linux/gpio.h> | ||
| 15 | #include <linux/pinctrl/pinctrl.h> | 16 | #include <linux/pinctrl/pinctrl.h> |
| 16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 17 | 18 | ||
| @@ -46,6 +47,44 @@ struct spear_muxreg { | |||
| 46 | u32 val; | 47 | u32 val; |
| 47 | }; | 48 | }; |
| 48 | 49 | ||
| 50 | struct spear_gpio_pingroup { | ||
| 51 | const unsigned *pins; | ||
| 52 | unsigned npins; | ||
| 53 | struct spear_muxreg *muxregs; | ||
| 54 | u8 nmuxregs; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* ste: set to enable */ | ||
| 58 | #define DEFINE_MUXREG(__pins, __muxreg, __mask, __ste) \ | ||
| 59 | static struct spear_muxreg __pins##_muxregs[] = { \ | ||
| 60 | { \ | ||
| 61 | .reg = __muxreg, \ | ||
| 62 | .mask = __mask, \ | ||
| 63 | .val = __ste ? __mask : 0, \ | ||
| 64 | }, \ | ||
| 65 | } | ||
| 66 | |||
| 67 | #define DEFINE_2_MUXREG(__pins, __muxreg1, __muxreg2, __mask, __ste1, __ste2) \ | ||
| 68 | static struct spear_muxreg __pins##_muxregs[] = { \ | ||
| 69 | { \ | ||
| 70 | .reg = __muxreg1, \ | ||
| 71 | .mask = __mask, \ | ||
| 72 | .val = __ste1 ? __mask : 0, \ | ||
| 73 | }, { \ | ||
| 74 | .reg = __muxreg2, \ | ||
| 75 | .mask = __mask, \ | ||
| 76 | .val = __ste2 ? __mask : 0, \ | ||
| 77 | }, \ | ||
| 78 | } | ||
| 79 | |||
| 80 | #define GPIO_PINGROUP(__pins) \ | ||
| 81 | { \ | ||
| 82 | .pins = __pins, \ | ||
| 83 | .npins = ARRAY_SIZE(__pins), \ | ||
| 84 | .muxregs = __pins##_muxregs, \ | ||
| 85 | .nmuxregs = ARRAY_SIZE(__pins##_muxregs), \ | ||
| 86 | } | ||
| 87 | |||
| 49 | /** | 88 | /** |
| 50 | * struct spear_modemux - SPEAr mode mux configuration | 89 | * struct spear_modemux - SPEAr mode mux configuration |
| 51 | * @modes: mode ids supported by this group of muxregs | 90 | * @modes: mode ids supported by this group of muxregs |
| @@ -100,6 +139,8 @@ struct spear_function { | |||
| 100 | * @nfunctions: The numbmer of entries in @functions. | 139 | * @nfunctions: The numbmer of entries in @functions. |
| 101 | * @groups: An array describing all pin groups the pin SoC supports. | 140 | * @groups: An array describing all pin groups the pin SoC supports. |
| 102 | * @ngroups: The numbmer of entries in @groups. | 141 | * @ngroups: The numbmer of entries in @groups. |
| 142 | * @gpio_pingroups: gpio pingroups | ||
| 143 | * @ngpio_pingroups: gpio pingroups count | ||
| 103 | * | 144 | * |
| 104 | * @modes_supported: Does SoC support modes | 145 | * @modes_supported: Does SoC support modes |
| 105 | * @mode: mode configured from probe | 146 | * @mode: mode configured from probe |
| @@ -113,6 +154,8 @@ struct spear_pinctrl_machdata { | |||
| 113 | unsigned nfunctions; | 154 | unsigned nfunctions; |
| 114 | struct spear_pingroup **groups; | 155 | struct spear_pingroup **groups; |
| 115 | unsigned ngroups; | 156 | unsigned ngroups; |
| 157 | struct spear_gpio_pingroup *gpio_pingroups; | ||
| 158 | unsigned ngpio_pingroups; | ||
| 116 | 159 | ||
| 117 | bool modes_supported; | 160 | bool modes_supported; |
| 118 | u16 mode; | 161 | u16 mode; |
| @@ -136,6 +179,9 @@ struct spear_pmx { | |||
| 136 | 179 | ||
| 137 | /* exported routines */ | 180 | /* exported routines */ |
| 138 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); | 181 | void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); |
| 182 | void __devinit | ||
| 183 | pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, | ||
| 184 | unsigned count, u16 reg); | ||
| 139 | int __devinit spear_pinctrl_probe(struct platform_device *pdev, | 185 | int __devinit spear_pinctrl_probe(struct platform_device *pdev, |
| 140 | struct spear_pinctrl_machdata *machdata); | 186 | struct spear_pinctrl_machdata *machdata); |
| 141 | int __devexit spear_pinctrl_remove(struct platform_device *pdev); | 187 | int __devexit spear_pinctrl_remove(struct platform_device *pdev); |
diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index 0436fc7895d6..30134f727455 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c | |||
| @@ -2418,6 +2418,268 @@ static struct spear_function *spear1310_functions[] = { | |||
| 2418 | &gpt64_function, | 2418 | &gpt64_function, |
| 2419 | }; | 2419 | }; |
| 2420 | 2420 | ||
| 2421 | static const unsigned pin18[] = { 18, }; | ||
| 2422 | static const unsigned pin19[] = { 19, }; | ||
| 2423 | static const unsigned pin20[] = { 20, }; | ||
| 2424 | static const unsigned pin21[] = { 21, }; | ||
| 2425 | static const unsigned pin22[] = { 22, }; | ||
| 2426 | static const unsigned pin23[] = { 23, }; | ||
| 2427 | static const unsigned pin54[] = { 54, }; | ||
| 2428 | static const unsigned pin55[] = { 55, }; | ||
| 2429 | static const unsigned pin56[] = { 56, }; | ||
| 2430 | static const unsigned pin57[] = { 57, }; | ||
| 2431 | static const unsigned pin58[] = { 58, }; | ||
| 2432 | static const unsigned pin59[] = { 59, }; | ||
| 2433 | static const unsigned pin60[] = { 60, }; | ||
| 2434 | static const unsigned pin61[] = { 61, }; | ||
| 2435 | static const unsigned pin62[] = { 62, }; | ||
| 2436 | static const unsigned pin63[] = { 63, }; | ||
| 2437 | static const unsigned pin143[] = { 143, }; | ||
| 2438 | static const unsigned pin144[] = { 144, }; | ||
| 2439 | static const unsigned pin145[] = { 145, }; | ||
| 2440 | static const unsigned pin146[] = { 146, }; | ||
| 2441 | static const unsigned pin147[] = { 147, }; | ||
| 2442 | static const unsigned pin148[] = { 148, }; | ||
| 2443 | static const unsigned pin149[] = { 149, }; | ||
| 2444 | static const unsigned pin150[] = { 150, }; | ||
| 2445 | static const unsigned pin151[] = { 151, }; | ||
| 2446 | static const unsigned pin152[] = { 152, }; | ||
| 2447 | static const unsigned pin205[] = { 205, }; | ||
| 2448 | static const unsigned pin206[] = { 206, }; | ||
| 2449 | static const unsigned pin211[] = { 211, }; | ||
| 2450 | static const unsigned pin212[] = { 212, }; | ||
| 2451 | static const unsigned pin213[] = { 213, }; | ||
| 2452 | static const unsigned pin214[] = { 214, }; | ||
| 2453 | static const unsigned pin215[] = { 215, }; | ||
| 2454 | static const unsigned pin216[] = { 216, }; | ||
| 2455 | static const unsigned pin217[] = { 217, }; | ||
| 2456 | static const unsigned pin218[] = { 218, }; | ||
| 2457 | static const unsigned pin219[] = { 219, }; | ||
| 2458 | static const unsigned pin220[] = { 220, }; | ||
| 2459 | static const unsigned pin221[] = { 221, }; | ||
| 2460 | static const unsigned pin222[] = { 222, }; | ||
| 2461 | static const unsigned pin223[] = { 223, }; | ||
| 2462 | static const unsigned pin224[] = { 224, }; | ||
| 2463 | static const unsigned pin225[] = { 225, }; | ||
| 2464 | static const unsigned pin226[] = { 226, }; | ||
| 2465 | static const unsigned pin227[] = { 227, }; | ||
| 2466 | static const unsigned pin228[] = { 228, }; | ||
| 2467 | static const unsigned pin229[] = { 229, }; | ||
| 2468 | static const unsigned pin230[] = { 230, }; | ||
| 2469 | static const unsigned pin231[] = { 231, }; | ||
| 2470 | static const unsigned pin232[] = { 232, }; | ||
| 2471 | static const unsigned pin233[] = { 233, }; | ||
| 2472 | static const unsigned pin234[] = { 234, }; | ||
| 2473 | static const unsigned pin235[] = { 235, }; | ||
| 2474 | static const unsigned pin236[] = { 236, }; | ||
| 2475 | static const unsigned pin237[] = { 237, }; | ||
| 2476 | static const unsigned pin238[] = { 238, }; | ||
| 2477 | static const unsigned pin239[] = { 239, }; | ||
| 2478 | static const unsigned pin240[] = { 240, }; | ||
| 2479 | static const unsigned pin241[] = { 241, }; | ||
| 2480 | static const unsigned pin242[] = { 242, }; | ||
| 2481 | static const unsigned pin243[] = { 243, }; | ||
| 2482 | static const unsigned pin244[] = { 244, }; | ||
| 2483 | static const unsigned pin245[] = { 245, }; | ||
| 2484 | |||
| 2485 | static const unsigned pin_grp0[] = { 173, 174, }; | ||
| 2486 | static const unsigned pin_grp1[] = { 175, 185, 188, 197, 198, }; | ||
| 2487 | static const unsigned pin_grp2[] = { 176, 177, 178, 179, 184, 186, 187, 189, | ||
| 2488 | 190, 191, 192, }; | ||
| 2489 | static const unsigned pin_grp3[] = { 180, 181, 182, 183, 193, 194, 195, 196, }; | ||
| 2490 | static const unsigned pin_grp4[] = { 199, 200, }; | ||
| 2491 | static const unsigned pin_grp5[] = { 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, | ||
| 2492 | 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; | ||
| 2493 | static const unsigned pin_grp6[] = { 86, 87, 88, 89, 90, 91, 92, 93, }; | ||
| 2494 | static const unsigned pin_grp7[] = { 98, 99, }; | ||
| 2495 | static const unsigned pin_grp8[] = { 158, 159, 160, 161, 162, 163, 164, 165, | ||
| 2496 | 166, 167, 168, 169, 170, 171, 172, }; | ||
| 2497 | |||
| 2498 | /* Define muxreg arrays */ | ||
| 2499 | DEFINE_2_MUXREG(i2c0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2C0_MASK, 0, 1); | ||
| 2500 | DEFINE_2_MUXREG(ssp0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SSP0_MASK, 0, 1); | ||
| 2501 | DEFINE_2_MUXREG(ssp0_cs0_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS0_MASK, 0, 1); | ||
| 2502 | DEFINE_2_MUXREG(ssp0_cs1_2_pins, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_SSP0_CS1_2_MASK, 0, 1); | ||
| 2503 | DEFINE_2_MUXREG(i2s0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_I2S0_MASK, 0, 1); | ||
| 2504 | DEFINE_2_MUXREG(i2s1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_I2S1_MASK, 0, 1); | ||
| 2505 | DEFINE_2_MUXREG(clcd_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_CLCD1_MASK, 0, 1); | ||
| 2506 | DEFINE_2_MUXREG(clcd_high_res_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_CLCD2_MASK, 0, 1); | ||
| 2507 | DEFINE_2_MUXREG(pin18, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO15_MASK, 0, 1); | ||
| 2508 | DEFINE_2_MUXREG(pin19, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO14_MASK, 0, 1); | ||
| 2509 | DEFINE_2_MUXREG(pin20, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO13_MASK, 0, 1); | ||
| 2510 | DEFINE_2_MUXREG(pin21, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO12_MASK, 0, 1); | ||
| 2511 | DEFINE_2_MUXREG(pin22, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO11_MASK, 0, 1); | ||
| 2512 | DEFINE_2_MUXREG(pin23, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO10_MASK, 0, 1); | ||
| 2513 | DEFINE_2_MUXREG(pin143, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO00_MASK, 0, 1); | ||
| 2514 | DEFINE_2_MUXREG(pin144, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO01_MASK, 0, 1); | ||
| 2515 | DEFINE_2_MUXREG(pin145, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO02_MASK, 0, 1); | ||
| 2516 | DEFINE_2_MUXREG(pin146, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO03_MASK, 0, 1); | ||
| 2517 | DEFINE_2_MUXREG(pin147, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO04_MASK, 0, 1); | ||
| 2518 | DEFINE_2_MUXREG(pin148, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO05_MASK, 0, 1); | ||
| 2519 | DEFINE_2_MUXREG(pin149, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO06_MASK, 0, 1); | ||
| 2520 | DEFINE_2_MUXREG(pin150, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO07_MASK, 0, 1); | ||
| 2521 | DEFINE_2_MUXREG(pin151, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO08_MASK, 0, 1); | ||
| 2522 | DEFINE_2_MUXREG(pin152, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_EGPIO09_MASK, 0, 1); | ||
| 2523 | DEFINE_2_MUXREG(smi_2_chips_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_SMI_MASK, 0, 1); | ||
| 2524 | DEFINE_2_MUXREG(pin54, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS3_MASK, 0, 1); | ||
| 2525 | DEFINE_2_MUXREG(pin55, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_SMINCS2_MASK, 0, 1); | ||
| 2526 | DEFINE_2_MUXREG(pin56, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFRSTPWDWN3_MASK, 0, 1); | ||
| 2527 | DEFINE_2_MUXREG(pin57, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN2_MASK, 0, 1); | ||
| 2528 | DEFINE_2_MUXREG(pin58, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN1_MASK, 0, 1); | ||
| 2529 | DEFINE_2_MUXREG(pin59, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFRSTPWDWN0_MASK, 0, 1); | ||
| 2530 | DEFINE_2_MUXREG(pin60, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFWPRT3_MASK, 0, 1); | ||
| 2531 | DEFINE_2_MUXREG(pin61, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFCE3_MASK, 0, 1); | ||
| 2532 | DEFINE_2_MUXREG(pin62, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD25_MASK, 0, 1); | ||
| 2533 | DEFINE_2_MUXREG(pin63, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD24_MASK, 0, 1); | ||
| 2534 | DEFINE_2_MUXREG(pin_grp0, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICLK_MASK, 0, 1); | ||
| 2535 | DEFINE_2_MUXREG(pin_grp1, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIICOL_CRS_XFERER_MIITXCLK_MASK, 0, 1); | ||
| 2536 | DEFINE_2_MUXREG(pin_grp2, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_RXCLK_RDV_TXEN_D03_MASK, 0, 1); | ||
| 2537 | DEFINE_2_MUXREG(pin_grp3, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_GMIID47_MASK, 0, 1); | ||
| 2538 | DEFINE_2_MUXREG(pin_grp4, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MDC_MDIO_MASK, 0, 1); | ||
| 2539 | DEFINE_2_MUXREG(pin_grp5, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_NFAD23_MASK, 0, 1); | ||
| 2540 | DEFINE_2_MUXREG(pin_grp6, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_MCI_DATA8_15_MASK, 0, 1); | ||
| 2541 | DEFINE_2_MUXREG(pin_grp7, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NFCE2_MASK, 0, 1); | ||
| 2542 | DEFINE_2_MUXREG(pin_grp8, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND8_MASK, 0, 1); | ||
| 2543 | DEFINE_2_MUXREG(nand_16bit_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_NAND16BIT_1_MASK, 0, 1); | ||
| 2544 | DEFINE_2_MUXREG(pin205, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL1_MASK | PMX_NFCE1_MASK, 0, 1); | ||
| 2545 | DEFINE_2_MUXREG(pin206, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_COL0_MASK | PMX_NFCE2_MASK, 0, 1); | ||
| 2546 | DEFINE_2_MUXREG(pin211, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW1_MASK | PMX_NFWPRT1_MASK, 0, 1); | ||
| 2547 | DEFINE_2_MUXREG(pin212, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROW0_MASK | PMX_NFWPRT2_MASK, 0, 1); | ||
| 2548 | DEFINE_2_MUXREG(pin213, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA0_MASK, 0, 1); | ||
| 2549 | DEFINE_2_MUXREG(pin214, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA1_MASK, 0, 1); | ||
| 2550 | DEFINE_2_MUXREG(pin215, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA2_MASK, 0, 1); | ||
| 2551 | DEFINE_2_MUXREG(pin216, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA3_MASK, 0, 1); | ||
| 2552 | DEFINE_2_MUXREG(pin217, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_MCIDATA4_MASK, 0, 1); | ||
| 2553 | DEFINE_2_MUXREG(pin218, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA5_MASK, 0, 1); | ||
| 2554 | DEFINE_2_MUXREG(pin219, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA6_MASK, 0, 1); | ||
| 2555 | DEFINE_2_MUXREG(pin220, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA7_MASK, 0, 1); | ||
| 2556 | DEFINE_2_MUXREG(pin221, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA1SD_MASK, 0, 1); | ||
| 2557 | DEFINE_2_MUXREG(pin222, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA2SD_MASK, 0, 1); | ||
| 2558 | DEFINE_2_MUXREG(pin223, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATA3SD_MASK, 0, 1); | ||
| 2559 | DEFINE_2_MUXREG(pin224, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR0ALE_MASK, 0, 1); | ||
| 2560 | DEFINE_2_MUXREG(pin225, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR1CLECLK_MASK, 0, 1); | ||
| 2561 | DEFINE_2_MUXREG(pin226, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIADDR2_MASK, 0, 1); | ||
| 2562 | DEFINE_2_MUXREG(pin227, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICECF_MASK, 0, 1); | ||
| 2563 | DEFINE_2_MUXREG(pin228, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICEXD_MASK, 0, 1); | ||
| 2564 | DEFINE_2_MUXREG(pin229, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICESDMMC_MASK, 0, 1); | ||
| 2565 | DEFINE_2_MUXREG(pin230, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF1_MASK, 0, 1); | ||
| 2566 | DEFINE_2_MUXREG(pin231, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDCF2_MASK, 0, 1); | ||
| 2567 | DEFINE_2_MUXREG(pin232, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDXD_MASK, 0, 1); | ||
| 2568 | DEFINE_2_MUXREG(pin233, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICDSDMMC_MASK, 0, 1); | ||
| 2569 | DEFINE_2_MUXREG(pin234, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDATADIR_MASK, 0, 1); | ||
| 2570 | DEFINE_2_MUXREG(pin235, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMARQWP_MASK, 0, 1); | ||
| 2571 | DEFINE_2_MUXREG(pin236, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDRE_MASK, 0, 1); | ||
| 2572 | DEFINE_2_MUXREG(pin237, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIOWRWE_MASK, 0, 1); | ||
| 2573 | DEFINE_2_MUXREG(pin238, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIRESETCF_MASK, 0, 1); | ||
| 2574 | DEFINE_2_MUXREG(pin239, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS0CE_MASK, 0, 1); | ||
| 2575 | DEFINE_2_MUXREG(pin240, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICFINTR_MASK, 0, 1); | ||
| 2576 | DEFINE_2_MUXREG(pin241, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIIORDY_MASK, 0, 1); | ||
| 2577 | DEFINE_2_MUXREG(pin242, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCICS1_MASK, 0, 1); | ||
| 2578 | DEFINE_2_MUXREG(pin243, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCIDMAACK_MASK, 0, 1); | ||
| 2579 | DEFINE_2_MUXREG(pin244, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCISDCMD_MASK, 0, 1); | ||
| 2580 | DEFINE_2_MUXREG(pin245, PAD_FUNCTION_EN_2, PAD_DIRECTION_SEL_2, PMX_MCILEDS_MASK, 0, 1); | ||
| 2581 | DEFINE_2_MUXREG(keyboard_rowcol6_8_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_KBD_ROWCOL68_MASK, 0, 1); | ||
| 2582 | DEFINE_2_MUXREG(uart0_pins, PAD_FUNCTION_EN_0, PAD_DIRECTION_SEL_0, PMX_UART0_MASK, 0, 1); | ||
| 2583 | DEFINE_2_MUXREG(uart0_modem_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_UART0_MODEM_MASK, 0, 1); | ||
| 2584 | DEFINE_2_MUXREG(gpt0_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR0_MASK, 0, 1); | ||
| 2585 | DEFINE_2_MUXREG(gpt0_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT0_TMR1_MASK, 0, 1); | ||
| 2586 | DEFINE_2_MUXREG(gpt1_tmr0_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR0_MASK, 0, 1); | ||
| 2587 | DEFINE_2_MUXREG(gpt1_tmr1_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_GPT1_TMR1_MASK, 0, 1); | ||
| 2588 | DEFINE_2_MUXREG(touch_xy_pins, PAD_FUNCTION_EN_1, PAD_DIRECTION_SEL_1, PMX_TOUCH_XY_MASK, 0, 1); | ||
| 2589 | |||
| 2590 | static struct spear_gpio_pingroup spear1310_gpio_pingroup[] = { | ||
| 2591 | GPIO_PINGROUP(i2c0_pins), | ||
| 2592 | GPIO_PINGROUP(ssp0_pins), | ||
| 2593 | GPIO_PINGROUP(ssp0_cs0_pins), | ||
| 2594 | GPIO_PINGROUP(ssp0_cs1_2_pins), | ||
| 2595 | GPIO_PINGROUP(i2s0_pins), | ||
| 2596 | GPIO_PINGROUP(i2s1_pins), | ||
| 2597 | GPIO_PINGROUP(clcd_pins), | ||
| 2598 | GPIO_PINGROUP(clcd_high_res_pins), | ||
| 2599 | GPIO_PINGROUP(pin18), | ||
| 2600 | GPIO_PINGROUP(pin19), | ||
| 2601 | GPIO_PINGROUP(pin20), | ||
| 2602 | GPIO_PINGROUP(pin21), | ||
| 2603 | GPIO_PINGROUP(pin22), | ||
| 2604 | GPIO_PINGROUP(pin23), | ||
| 2605 | GPIO_PINGROUP(pin143), | ||
| 2606 | GPIO_PINGROUP(pin144), | ||
| 2607 | GPIO_PINGROUP(pin145), | ||
| 2608 | GPIO_PINGROUP(pin146), | ||
| 2609 | GPIO_PINGROUP(pin147), | ||
| 2610 | GPIO_PINGROUP(pin148), | ||
| 2611 | GPIO_PINGROUP(pin149), | ||
| 2612 | GPIO_PINGROUP(pin150), | ||
| 2613 | GPIO_PINGROUP(pin151), | ||
| 2614 | GPIO_PINGROUP(pin152), | ||
| 2615 | GPIO_PINGROUP(smi_2_chips_pins), | ||
| 2616 | GPIO_PINGROUP(pin54), | ||
| 2617 | GPIO_PINGROUP(pin55), | ||
| 2618 | GPIO_PINGROUP(pin56), | ||
| 2619 | GPIO_PINGROUP(pin57), | ||
| 2620 | GPIO_PINGROUP(pin58), | ||
| 2621 | GPIO_PINGROUP(pin59), | ||
| 2622 | GPIO_PINGROUP(pin60), | ||
| 2623 | GPIO_PINGROUP(pin61), | ||
| 2624 | GPIO_PINGROUP(pin62), | ||
| 2625 | GPIO_PINGROUP(pin63), | ||
| 2626 | GPIO_PINGROUP(pin_grp0), | ||
| 2627 | GPIO_PINGROUP(pin_grp1), | ||
| 2628 | GPIO_PINGROUP(pin_grp2), | ||
| 2629 | GPIO_PINGROUP(pin_grp3), | ||
| 2630 | GPIO_PINGROUP(pin_grp4), | ||
| 2631 | GPIO_PINGROUP(pin_grp5), | ||
| 2632 | GPIO_PINGROUP(pin_grp6), | ||
| 2633 | GPIO_PINGROUP(pin_grp7), | ||
| 2634 | GPIO_PINGROUP(pin_grp8), | ||
| 2635 | GPIO_PINGROUP(nand_16bit_pins), | ||
| 2636 | GPIO_PINGROUP(pin205), | ||
| 2637 | GPIO_PINGROUP(pin206), | ||
| 2638 | GPIO_PINGROUP(pin211), | ||
| 2639 | GPIO_PINGROUP(pin212), | ||
| 2640 | GPIO_PINGROUP(pin213), | ||
| 2641 | GPIO_PINGROUP(pin214), | ||
| 2642 | GPIO_PINGROUP(pin215), | ||
| 2643 | GPIO_PINGROUP(pin216), | ||
| 2644 | GPIO_PINGROUP(pin217), | ||
| 2645 | GPIO_PINGROUP(pin218), | ||
| 2646 | GPIO_PINGROUP(pin219), | ||
| 2647 | GPIO_PINGROUP(pin220), | ||
| 2648 | GPIO_PINGROUP(pin221), | ||
| 2649 | GPIO_PINGROUP(pin222), | ||
| 2650 | GPIO_PINGROUP(pin223), | ||
| 2651 | GPIO_PINGROUP(pin224), | ||
| 2652 | GPIO_PINGROUP(pin225), | ||
| 2653 | GPIO_PINGROUP(pin226), | ||
| 2654 | GPIO_PINGROUP(pin227), | ||
| 2655 | GPIO_PINGROUP(pin228), | ||
| 2656 | GPIO_PINGROUP(pin229), | ||
| 2657 | GPIO_PINGROUP(pin230), | ||
| 2658 | GPIO_PINGROUP(pin231), | ||
| 2659 | GPIO_PINGROUP(pin232), | ||
| 2660 | GPIO_PINGROUP(pin233), | ||
| 2661 | GPIO_PINGROUP(pin234), | ||
| 2662 | GPIO_PINGROUP(pin235), | ||
| 2663 | GPIO_PINGROUP(pin236), | ||
| 2664 | GPIO_PINGROUP(pin237), | ||
| 2665 | GPIO_PINGROUP(pin238), | ||
| 2666 | GPIO_PINGROUP(pin239), | ||
| 2667 | GPIO_PINGROUP(pin240), | ||
| 2668 | GPIO_PINGROUP(pin241), | ||
| 2669 | GPIO_PINGROUP(pin242), | ||
| 2670 | GPIO_PINGROUP(pin243), | ||
| 2671 | GPIO_PINGROUP(pin244), | ||
| 2672 | GPIO_PINGROUP(pin245), | ||
| 2673 | GPIO_PINGROUP(keyboard_rowcol6_8_pins), | ||
| 2674 | GPIO_PINGROUP(uart0_pins), | ||
| 2675 | GPIO_PINGROUP(uart0_modem_pins), | ||
| 2676 | GPIO_PINGROUP(gpt0_tmr0_pins), | ||
| 2677 | GPIO_PINGROUP(gpt0_tmr1_pins), | ||
| 2678 | GPIO_PINGROUP(gpt1_tmr0_pins), | ||
| 2679 | GPIO_PINGROUP(gpt1_tmr1_pins), | ||
| 2680 | GPIO_PINGROUP(touch_xy_pins), | ||
| 2681 | }; | ||
| 2682 | |||
| 2421 | static struct spear_pinctrl_machdata spear1310_machdata = { | 2683 | static struct spear_pinctrl_machdata spear1310_machdata = { |
| 2422 | .pins = spear1310_pins, | 2684 | .pins = spear1310_pins, |
| 2423 | .npins = ARRAY_SIZE(spear1310_pins), | 2685 | .npins = ARRAY_SIZE(spear1310_pins), |
| @@ -2425,6 +2687,8 @@ static struct spear_pinctrl_machdata spear1310_machdata = { | |||
| 2425 | .ngroups = ARRAY_SIZE(spear1310_pingroups), | 2687 | .ngroups = ARRAY_SIZE(spear1310_pingroups), |
| 2426 | .functions = spear1310_functions, | 2688 | .functions = spear1310_functions, |
| 2427 | .nfunctions = ARRAY_SIZE(spear1310_functions), | 2689 | .nfunctions = ARRAY_SIZE(spear1310_functions), |
| 2690 | .gpio_pingroups = spear1310_gpio_pingroup, | ||
| 2691 | .ngpio_pingroups = ARRAY_SIZE(spear1310_gpio_pingroup), | ||
| 2428 | .modes_supported = false, | 2692 | .modes_supported = false, |
| 2429 | }; | 2693 | }; |
| 2430 | 2694 | ||
diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 4dfc2849b172..9a491007f42d 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c | |||
| @@ -661,6 +661,8 @@ static int __devinit spear300_pinctrl_probe(struct platform_device *pdev) | |||
| 661 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); | 661 | spear3xx_machdata.ngroups = ARRAY_SIZE(spear300_pingroups); |
| 662 | spear3xx_machdata.functions = spear300_functions; | 662 | spear3xx_machdata.functions = spear300_functions; |
| 663 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); | 663 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear300_functions); |
| 664 | spear3xx_machdata.gpio_pingroups = NULL; | ||
| 665 | spear3xx_machdata.ngpio_pingroups = 0; | ||
| 664 | 666 | ||
| 665 | spear3xx_machdata.modes_supported = true; | 667 | spear3xx_machdata.modes_supported = true; |
| 666 | spear3xx_machdata.pmx_modes = spear300_pmx_modes; | 668 | spear3xx_machdata.pmx_modes = spear300_pmx_modes; |
diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 96883693fb7e..4d5dfe9c760a 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c | |||
| @@ -388,6 +388,8 @@ static int __devinit spear310_pinctrl_probe(struct platform_device *pdev) | |||
| 388 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); | 388 | spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions); |
| 389 | 389 | ||
| 390 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); | 390 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); |
| 391 | pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, | ||
| 392 | spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); | ||
| 391 | 393 | ||
| 392 | spear3xx_machdata.modes_supported = false; | 394 | spear3xx_machdata.modes_supported = false; |
| 393 | 395 | ||
diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index ca47b0e50780..c996e26e3b6c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c | |||
| @@ -3431,6 +3431,8 @@ static int __devinit spear320_pinctrl_probe(struct platform_device *pdev) | |||
| 3431 | spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); | 3431 | spear3xx_machdata.npmx_modes = ARRAY_SIZE(spear320_pmx_modes); |
| 3432 | 3432 | ||
| 3433 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); | 3433 | pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG); |
| 3434 | pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups, | ||
| 3435 | spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG); | ||
| 3434 | 3436 | ||
| 3435 | ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); | 3437 | ret = spear_pinctrl_probe(pdev, &spear3xx_machdata); |
| 3436 | if (ret) | 3438 | if (ret) |
diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 0242378f7cb8..12ee21af766b 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c | |||
| @@ -481,7 +481,44 @@ struct spear_function spear3xx_timer_2_3_function = { | |||
| 481 | .ngroups = ARRAY_SIZE(timer_2_3_grps), | 481 | .ngroups = ARRAY_SIZE(timer_2_3_grps), |
| 482 | }; | 482 | }; |
| 483 | 483 | ||
| 484 | /* Define muxreg arrays */ | ||
| 485 | DEFINE_MUXREG(firda_pins, 0, PMX_FIRDA_MASK, 0); | ||
| 486 | DEFINE_MUXREG(i2c_pins, 0, PMX_I2C_MASK, 0); | ||
| 487 | DEFINE_MUXREG(ssp_cs_pins, 0, PMX_SSP_CS_MASK, 0); | ||
| 488 | DEFINE_MUXREG(ssp_pins, 0, PMX_SSP_MASK, 0); | ||
| 489 | DEFINE_MUXREG(mii_pins, 0, PMX_MII_MASK, 0); | ||
| 490 | DEFINE_MUXREG(gpio0_pin0_pins, 0, PMX_GPIO_PIN0_MASK, 0); | ||
| 491 | DEFINE_MUXREG(gpio0_pin1_pins, 0, PMX_GPIO_PIN1_MASK, 0); | ||
| 492 | DEFINE_MUXREG(gpio0_pin2_pins, 0, PMX_GPIO_PIN2_MASK, 0); | ||
| 493 | DEFINE_MUXREG(gpio0_pin3_pins, 0, PMX_GPIO_PIN3_MASK, 0); | ||
| 494 | DEFINE_MUXREG(gpio0_pin4_pins, 0, PMX_GPIO_PIN4_MASK, 0); | ||
| 495 | DEFINE_MUXREG(gpio0_pin5_pins, 0, PMX_GPIO_PIN5_MASK, 0); | ||
| 496 | DEFINE_MUXREG(uart0_ext_pins, 0, PMX_UART0_MODEM_MASK, 0); | ||
| 497 | DEFINE_MUXREG(uart0_pins, 0, PMX_UART0_MASK, 0); | ||
| 498 | DEFINE_MUXREG(timer_0_1_pins, 0, PMX_TIMER_0_1_MASK, 0); | ||
| 499 | DEFINE_MUXREG(timer_2_3_pins, 0, PMX_TIMER_2_3_MASK, 0); | ||
| 500 | |||
| 501 | static struct spear_gpio_pingroup spear3xx_gpio_pingroup[] = { | ||
| 502 | GPIO_PINGROUP(firda_pins), | ||
| 503 | GPIO_PINGROUP(i2c_pins), | ||
| 504 | GPIO_PINGROUP(ssp_cs_pins), | ||
| 505 | GPIO_PINGROUP(ssp_pins), | ||
| 506 | GPIO_PINGROUP(mii_pins), | ||
| 507 | GPIO_PINGROUP(gpio0_pin0_pins), | ||
| 508 | GPIO_PINGROUP(gpio0_pin1_pins), | ||
| 509 | GPIO_PINGROUP(gpio0_pin2_pins), | ||
| 510 | GPIO_PINGROUP(gpio0_pin3_pins), | ||
| 511 | GPIO_PINGROUP(gpio0_pin4_pins), | ||
| 512 | GPIO_PINGROUP(gpio0_pin5_pins), | ||
| 513 | GPIO_PINGROUP(uart0_ext_pins), | ||
| 514 | GPIO_PINGROUP(uart0_pins), | ||
| 515 | GPIO_PINGROUP(timer_0_1_pins), | ||
| 516 | GPIO_PINGROUP(timer_2_3_pins), | ||
| 517 | }; | ||
| 518 | |||
| 484 | struct spear_pinctrl_machdata spear3xx_machdata = { | 519 | struct spear_pinctrl_machdata spear3xx_machdata = { |
| 485 | .pins = spear3xx_pins, | 520 | .pins = spear3xx_pins, |
| 486 | .npins = ARRAY_SIZE(spear3xx_pins), | 521 | .npins = ARRAY_SIZE(spear3xx_pins), |
| 522 | .gpio_pingroups = spear3xx_gpio_pingroup, | ||
| 523 | .ngpio_pingroups = ARRAY_SIZE(spear3xx_gpio_pingroup), | ||
| 487 | }; | 524 | }; |
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index a9432fc6b8ba..b6516f32280d 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
| 6 | #include <linux/errno.h> | 6 | #include <linux/errno.h> |
| 7 | #include <linux/of.h> | 7 | #include <linux/of.h> |
| 8 | #include <linux/pinctrl/pinctrl.h> | ||
| 8 | 9 | ||
| 9 | #ifdef CONFIG_GPIOLIB | 10 | #ifdef CONFIG_GPIOLIB |
| 10 | 11 | ||
| @@ -56,6 +57,8 @@ struct device_node; | |||
| 56 | * enabling module power and clock; may sleep | 57 | * enabling module power and clock; may sleep |
| 57 | * @free: optional hook for chip-specific deactivation, such as | 58 | * @free: optional hook for chip-specific deactivation, such as |
| 58 | * disabling module power and clock; may sleep | 59 | * disabling module power and clock; may sleep |
| 60 | * @get_direction: returns direction for signal "offset", 0=out, 1=in, | ||
| 61 | * (same as GPIOF_DIR_XXX), or negative error | ||
| 59 | * @direction_input: configures signal "offset" as input, or returns error | 62 | * @direction_input: configures signal "offset" as input, or returns error |
| 60 | * @get: returns value for signal "offset"; for output signals this | 63 | * @get: returns value for signal "offset"; for output signals this |
| 61 | * returns either the value actually sensed, or zero | 64 | * returns either the value actually sensed, or zero |
| @@ -100,7 +103,8 @@ struct gpio_chip { | |||
| 100 | unsigned offset); | 103 | unsigned offset); |
| 101 | void (*free)(struct gpio_chip *chip, | 104 | void (*free)(struct gpio_chip *chip, |
| 102 | unsigned offset); | 105 | unsigned offset); |
| 103 | 106 | int (*get_direction)(struct gpio_chip *chip, | |
| 107 | unsigned offset); | ||
| 104 | int (*direction_input)(struct gpio_chip *chip, | 108 | int (*direction_input)(struct gpio_chip *chip, |
| 105 | unsigned offset); | 109 | unsigned offset); |
| 106 | int (*get)(struct gpio_chip *chip, | 110 | int (*get)(struct gpio_chip *chip, |
| @@ -134,6 +138,15 @@ struct gpio_chip { | |||
| 134 | int (*of_xlate)(struct gpio_chip *gc, | 138 | int (*of_xlate)(struct gpio_chip *gc, |
| 135 | const struct of_phandle_args *gpiospec, u32 *flags); | 139 | const struct of_phandle_args *gpiospec, u32 *flags); |
| 136 | #endif | 140 | #endif |
| 141 | #ifdef CONFIG_PINCTRL | ||
| 142 | /* | ||
| 143 | * If CONFIG_PINCTRL is enabled, then gpio controllers can optionally | ||
| 144 | * describe the actual pin range which they serve in an SoC. This | ||
| 145 | * information would be used by pinctrl subsystem to configure | ||
| 146 | * corresponding pins for gpio usage. | ||
| 147 | */ | ||
| 148 | struct list_head pin_ranges; | ||
| 149 | #endif | ||
| 137 | }; | 150 | }; |
| 138 | 151 | ||
| 139 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, | 152 | extern const char *gpiochip_is_requested(struct gpio_chip *chip, |
| @@ -257,4 +270,39 @@ static inline void gpio_unexport(unsigned gpio) | |||
| 257 | } | 270 | } |
| 258 | #endif /* CONFIG_GPIO_SYSFS */ | 271 | #endif /* CONFIG_GPIO_SYSFS */ |
| 259 | 272 | ||
| 273 | #ifdef CONFIG_PINCTRL | ||
| 274 | |||
| 275 | /** | ||
| 276 | * struct gpio_pin_range - pin range controlled by a gpio chip | ||
| 277 | * @head: list for maintaining set of pin ranges, used internally | ||
| 278 | * @pctldev: pinctrl device which handles corresponding pins | ||
| 279 | * @range: actual range of pins controlled by a gpio controller | ||
| 280 | */ | ||
| 281 | |||
| 282 | struct gpio_pin_range { | ||
| 283 | struct list_head node; | ||
| 284 | struct pinctrl_dev *pctldev; | ||
| 285 | struct pinctrl_gpio_range range; | ||
| 286 | }; | ||
| 287 | |||
| 288 | int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
| 289 | unsigned int pin_base, unsigned int npins); | ||
| 290 | void gpiochip_remove_pin_ranges(struct gpio_chip *chip); | ||
| 291 | |||
| 292 | #else | ||
| 293 | |||
| 294 | static inline int | ||
| 295 | gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
| 296 | unsigned int pin_base, unsigned int npins) | ||
| 297 | { | ||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | static inline void | ||
| 302 | gpiochip_remove_pin_ranges(struct gpio_chip *chip) | ||
| 303 | { | ||
| 304 | } | ||
| 305 | |||
| 306 | #endif /* CONFIG_PINCTRL */ | ||
| 307 | |||
| 260 | #endif /* _ASM_GENERIC_GPIO_H */ | 308 | #endif /* _ASM_GENERIC_GPIO_H */ |
diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 2e31e8b3a190..7ba2762abbc9 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h | |||
| @@ -72,9 +72,9 @@ static inline int irq_to_gpio(unsigned int irq) | |||
| 72 | return -EINVAL; | 72 | return -EINVAL; |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | #endif | 75 | #endif /* ! CONFIG_ARCH_HAVE_CUSTOM_GPIO_H */ |
| 76 | 76 | ||
| 77 | #else | 77 | #else /* ! CONFIG_GENERIC_GPIO */ |
| 78 | 78 | ||
| 79 | #include <linux/kernel.h> | 79 | #include <linux/kernel.h> |
| 80 | #include <linux/types.h> | 80 | #include <linux/types.h> |
| @@ -231,6 +231,20 @@ static inline int irq_to_gpio(unsigned irq) | |||
| 231 | return -EINVAL; | 231 | return -EINVAL; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | #endif | 234 | static inline int |
| 235 | gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name, | ||
| 236 | unsigned int pin_base, unsigned int npins) | ||
| 237 | { | ||
| 238 | WARN_ON(1); | ||
| 239 | return -EINVAL; | ||
| 240 | } | ||
| 241 | |||
| 242 | static inline void | ||
| 243 | gpiochip_remove_pin_ranges(struct gpio_chip *chip) | ||
| 244 | { | ||
| 245 | WARN_ON(1); | ||
| 246 | } | ||
| 247 | |||
| 248 | #endif /* ! CONFIG_GENERIC_GPIO */ | ||
| 235 | 249 | ||
| 236 | #endif /* __LINUX_GPIO_H */ | 250 | #endif /* __LINUX_GPIO_H */ |
diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/include/linux/irqchip/spear-shirq.h index 88a7fbd24793..c8be16d213a3 100644 --- a/arch/arm/plat-spear/include/plat/shirq.h +++ b/include/linux/irqchip/spear-shirq.h | |||
| @@ -1,9 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/plat-spear/include/plat/shirq.h | ||
| 3 | * | ||
| 4 | * SPEAr platform shared irq layer header file | 2 | * SPEAr platform shared irq layer header file |
| 5 | * | 3 | * |
| 6 | * Copyright (C) 2009 ST Microelectronics | 4 | * Copyright (C) 2009-2012 ST Microelectronics |
| 7 | * Viresh Kumar <viresh.linux@gmail.com> | 5 | * Viresh Kumar <viresh.linux@gmail.com> |
| 8 | * | 6 | * |
| 9 | * This file is licensed under the terms of the GNU General Public | 7 | * This file is licensed under the terms of the GNU General Public |
| @@ -11,31 +9,15 @@ | |||
| 11 | * warranty of any kind, whether express or implied. | 9 | * warranty of any kind, whether express or implied. |
| 12 | */ | 10 | */ |
| 13 | 11 | ||
| 14 | #ifndef __PLAT_SHIRQ_H | 12 | #ifndef __SPEAR_SHIRQ_H |
| 15 | #define __PLAT_SHIRQ_H | 13 | #define __SPEAR_SHIRQ_H |
| 16 | 14 | ||
| 17 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
| 18 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 19 | 17 | ||
| 20 | /* | 18 | /* |
| 21 | * struct shirq_dev_config: shared irq device configuration | ||
| 22 | * | ||
| 23 | * virq: virtual irq number of device | ||
| 24 | * enb_mask: enable mask of device | ||
| 25 | * status_mask: status mask of device | ||
| 26 | * clear_mask: clear mask of device | ||
| 27 | */ | ||
| 28 | struct shirq_dev_config { | ||
| 29 | u32 virq; | ||
| 30 | u32 enb_mask; | ||
| 31 | u32 status_mask; | ||
| 32 | u32 clear_mask; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /* | ||
| 36 | * struct shirq_regs: shared irq register configuration | 19 | * struct shirq_regs: shared irq register configuration |
| 37 | * | 20 | * |
| 38 | * base: base address of shared irq register | ||
| 39 | * enb_reg: enable register offset | 21 | * enb_reg: enable register offset |
| 40 | * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt | 22 | * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt |
| 41 | * status_reg: status register offset | 23 | * status_reg: status register offset |
| @@ -44,11 +26,9 @@ struct shirq_dev_config { | |||
| 44 | * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt | 26 | * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt |
| 45 | */ | 27 | */ |
| 46 | struct shirq_regs { | 28 | struct shirq_regs { |
| 47 | void __iomem *base; | ||
| 48 | u32 enb_reg; | 29 | u32 enb_reg; |
| 49 | u32 reset_to_enb; | 30 | u32 reset_to_enb; |
| 50 | u32 status_reg; | 31 | u32 status_reg; |
| 51 | u32 status_reg_mask; | ||
| 52 | u32 clear_reg; | 32 | u32 clear_reg; |
| 53 | u32 reset_to_clear; | 33 | u32 reset_to_clear; |
| 54 | }; | 34 | }; |
| @@ -57,17 +37,28 @@ struct shirq_regs { | |||
| 57 | * struct spear_shirq: shared irq structure | 37 | * struct spear_shirq: shared irq structure |
| 58 | * | 38 | * |
| 59 | * irq: hardware irq number | 39 | * irq: hardware irq number |
| 60 | * dev_config: array of device config structures which are using "irq" line | 40 | * irq_base: base irq in linux domain |
| 61 | * dev_count: size of dev_config array | 41 | * irq_nr: no. of shared interrupts in a particular block |
| 42 | * irq_bit_off: starting bit offset in the status register | ||
| 43 | * invalid_irq: irq group is currently disabled | ||
| 44 | * base: base address of shared irq register | ||
| 62 | * regs: register configuration for shared irq block | 45 | * regs: register configuration for shared irq block |
| 63 | */ | 46 | */ |
| 64 | struct spear_shirq { | 47 | struct spear_shirq { |
| 65 | u32 irq; | 48 | u32 irq; |
| 66 | struct shirq_dev_config *dev_config; | 49 | u32 irq_base; |
| 67 | u32 dev_count; | 50 | u32 irq_nr; |
| 51 | u32 irq_bit_off; | ||
| 52 | int invalid_irq; | ||
| 53 | void __iomem *base; | ||
| 68 | struct shirq_regs regs; | 54 | struct shirq_regs regs; |
| 69 | }; | 55 | }; |
| 70 | 56 | ||
| 71 | int spear_shirq_register(struct spear_shirq *shirq); | 57 | int __init spear300_shirq_of_init(struct device_node *np, |
| 58 | struct device_node *parent); | ||
| 59 | int __init spear310_shirq_of_init(struct device_node *np, | ||
| 60 | struct device_node *parent); | ||
| 61 | int __init spear320_shirq_of_init(struct device_node *np, | ||
| 62 | struct device_node *parent); | ||
| 72 | 63 | ||
| 73 | #endif /* __PLAT_SHIRQ_H */ | 64 | #endif /* __SPEAR_SHIRQ_H */ |
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 7d087f03e91e..4a58428bc793 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h | |||
| @@ -134,6 +134,22 @@ extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, | |||
| 134 | extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, | 134 | extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, |
| 135 | struct pinctrl_gpio_range *ranges, | 135 | struct pinctrl_gpio_range *ranges, |
| 136 | unsigned nranges); | 136 | unsigned nranges); |
| 137 | extern void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, | ||
| 138 | struct pinctrl_gpio_range *range); | ||
| 139 | |||
| 140 | extern struct pinctrl_dev *find_pinctrl_and_add_gpio_range(const char *devname, | ||
| 141 | struct pinctrl_gpio_range *range); | ||
| 142 | |||
| 143 | #ifdef CONFIG_OF | ||
| 144 | extern struct pinctrl_dev *of_pinctrl_get(struct device_node *np); | ||
| 145 | #else | ||
| 146 | static inline | ||
| 147 | struct pinctrl_dev *of_pinctrl_get(struct device_node *np) | ||
| 148 | { | ||
| 149 | return NULL; | ||
| 150 | } | ||
| 151 | #endif /* CONFIG_OF */ | ||
| 152 | |||
| 137 | extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); | 153 | extern const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev); |
| 138 | extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); | 154 | extern void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev); |
| 139 | #else | 155 | #else |
diff --git a/include/linux/platform_data/pinctrl-coh901.h b/include/linux/platform_data/pinctrl-coh901.h index 30dea251b835..27a23b318cef 100644 --- a/include/linux/platform_data/pinctrl-coh901.h +++ b/include/linux/platform_data/pinctrl-coh901.h | |||
| @@ -13,13 +13,11 @@ | |||
| 13 | * struct u300_gpio_platform - U300 GPIO platform data | 13 | * struct u300_gpio_platform - U300 GPIO platform data |
| 14 | * @ports: number of GPIO block ports | 14 | * @ports: number of GPIO block ports |
| 15 | * @gpio_base: first GPIO number for this block (use a free range) | 15 | * @gpio_base: first GPIO number for this block (use a free range) |
| 16 | * @gpio_irq_base: first GPIO IRQ number for this block (use a free range) | ||
| 17 | * @pinctrl_device: pin control device to spawn as child | 16 | * @pinctrl_device: pin control device to spawn as child |
| 18 | */ | 17 | */ |
| 19 | struct u300_gpio_platform { | 18 | struct u300_gpio_platform { |
| 20 | u8 ports; | 19 | u8 ports; |
| 21 | int gpio_base; | 20 | int gpio_base; |
| 22 | int gpio_irq_base; | ||
| 23 | struct platform_device *pinctrl_device; | 21 | struct platform_device *pinctrl_device; |
| 24 | }; | 22 | }; |
| 25 | 23 | ||
