Commit 88e0abcd7a8171ca7af3402373e7bd81fe9b6754

Authored by Pawel Moll
1 parent 3ecbf05be1

mfd: Versatile Express system registers driver

This is a platform driver for Versatile Express' "system
register" block. It's a random collection of registers providing
the following functionality:

- low level platform functions like board ID access; in order to
  use those, the driver must be initialized early, either statically
  or based on the DT

- config bus bridge via "system control" interface; as the response
  from the controller does not generate interrupt (yet), the status
  register is periodically polled using a timer

- pseudo GPIO lines providing MMC card status and Flash WP#
  signal control

- LED interface for a set of 8 LEDs on the motherboard, with
  "heartbeat", "mmc0" and "cpu0" to "cpu5" as default triggers

Signed-off-by: Pawel Moll <pawel.moll@arm.com>

Showing 4 changed files with 628 additions and 1 deletions Inline Diff

Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
File was created 1 ARM Versatile Express system registers
2 --------------------------------------
3
4 This is a system control registers block, providing multiple low level
5 platform functions like board detection and identification, software
6 interrupt generation, MMC and NOR Flash control etc.
7
8 Required node properties:
9 - compatible value : = "arm,vexpress,sysreg";
10 - reg : physical base address and the size of the registers window
11 - gpio-controller : specifies that the node is a GPIO controller
12 - #gpio-cells : size of the GPIO specifier, should be 2:
13 - first cell is the pseudo-GPIO line number:
14 0 - MMC CARDIN
15 1 - MMC WPROT
16 2 - NOR FLASH WPn
17 - second cell can take standard GPIO flags (currently ignored).
18
19 Example:
20 v2m_sysreg: sysreg@10000000 {
21 compatible = "arm,vexpress-sysreg";
22 reg = <0x10000000 0x1000>;
23 gpio-controller;
24 #gpio-cells = <2>;
25 };
26
27 This block also can also act a bridge to the platform's configuration
28 bus via "system control" interface, addressing devices with site number,
29 position in the board stack, config controller, function and device
30 numbers - see motherboard's TRM for more details.
31
32 The node describing a config device must refer to the sysreg node via
33 "arm,vexpress,config-bridge" phandle (can be also defined in the node's
34 parent) and relies on the board topology properties - see main vexpress
35 node documentation for more details. It must must also define the
36 following property:
37 - arm,vexpress-sysreg,func : must contain two cells:
38 - first cell defines function number (eg. 1 for clock generator,
39 2 for voltage regulators etc.)
40 - device number (eg. osc 0, osc 1 etc.)
41
42 Example:
43 mcc {
44 arm,vexpress,config-bridge = <&v2m_sysreg>;
45
46 osc@0 {
47 compatible = "arm,vexpress-osc";
48 arm,vexpress-sysreg,func = <1 0>;
49 };
50 };
51
drivers/mfd/Makefile
1 # 1 #
2 # Makefile for multifunction miscellaneous devices 2 # Makefile for multifunction miscellaneous devices
3 # 3 #
4 4
5 88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o 5 88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o
6 obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o 6 obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
7 obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o 7 obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o
8 obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o 8 obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
9 obj-$(CONFIG_MFD_SM501) += sm501.o 9 obj-$(CONFIG_MFD_SM501) += sm501.o
10 obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o 10 obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
11 11
12 obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o 12 obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
13 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o 13 obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
14 obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o 14 obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
15 15
16 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o 16 obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
17 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o 17 obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
18 obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o 18 obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
19 19
20 obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o 20 obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
21 obj-$(CONFIG_MFD_STMPE) += stmpe.o 21 obj-$(CONFIG_MFD_STMPE) += stmpe.o
22 obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o 22 obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o
23 obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o 23 obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o
24 obj-$(CONFIG_MFD_TC3589X) += tc3589x.o 24 obj-$(CONFIG_MFD_TC3589X) += tc3589x.o
25 obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o 25 obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
26 obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o 26 obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o
27 obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o 27 obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o
28 28
29 obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o 29 obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o
30 obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o 30 obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o
31 obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o 31 obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o
32 obj-$(CONFIG_MFD_ARIZONA_SPI) += arizona-spi.o 32 obj-$(CONFIG_MFD_ARIZONA_SPI) += arizona-spi.o
33 ifneq ($(CONFIG_MFD_WM5102),n) 33 ifneq ($(CONFIG_MFD_WM5102),n)
34 obj-$(CONFIG_MFD_ARIZONA) += wm5102-tables.o 34 obj-$(CONFIG_MFD_ARIZONA) += wm5102-tables.o
35 endif 35 endif
36 ifneq ($(CONFIG_MFD_WM5110),n) 36 ifneq ($(CONFIG_MFD_WM5110),n)
37 obj-$(CONFIG_MFD_ARIZONA) += wm5110-tables.o 37 obj-$(CONFIG_MFD_ARIZONA) += wm5110-tables.o
38 endif 38 endif
39 obj-$(CONFIG_MFD_WM8400) += wm8400-core.o 39 obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
40 wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o 40 wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o
41 wm831x-objs += wm831x-auxadc.o 41 wm831x-objs += wm831x-auxadc.o
42 obj-$(CONFIG_MFD_WM831X) += wm831x.o 42 obj-$(CONFIG_MFD_WM831X) += wm831x.o
43 obj-$(CONFIG_MFD_WM831X_I2C) += wm831x-i2c.o 43 obj-$(CONFIG_MFD_WM831X_I2C) += wm831x-i2c.o
44 obj-$(CONFIG_MFD_WM831X_SPI) += wm831x-spi.o 44 obj-$(CONFIG_MFD_WM831X_SPI) += wm831x-spi.o
45 wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o 45 wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
46 wm8350-objs += wm8350-irq.o 46 wm8350-objs += wm8350-irq.o
47 obj-$(CONFIG_MFD_WM8350) += wm8350.o 47 obj-$(CONFIG_MFD_WM8350) += wm8350.o
48 obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 48 obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
49 obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o 49 obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o
50 50
51 obj-$(CONFIG_TPS6105X) += tps6105x.o 51 obj-$(CONFIG_TPS6105X) += tps6105x.o
52 obj-$(CONFIG_TPS65010) += tps65010.o 52 obj-$(CONFIG_TPS65010) += tps65010.o
53 obj-$(CONFIG_TPS6507X) += tps6507x.o 53 obj-$(CONFIG_TPS6507X) += tps6507x.o
54 obj-$(CONFIG_MFD_TPS65217) += tps65217.o 54 obj-$(CONFIG_MFD_TPS65217) += tps65217.o
55 obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o 55 obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o
56 tps65912-objs := tps65912-core.o tps65912-irq.o 56 tps65912-objs := tps65912-core.o tps65912-irq.o
57 obj-$(CONFIG_MFD_TPS65912) += tps65912.o 57 obj-$(CONFIG_MFD_TPS65912) += tps65912.o
58 obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o 58 obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
59 obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o 59 obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
60 obj-$(CONFIG_MENELAUS) += menelaus.o 60 obj-$(CONFIG_MENELAUS) += menelaus.o
61 61
62 obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o 62 obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
63 obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o 63 obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
64 obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o 64 obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
65 obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o 65 obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
66 obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o 66 obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o
67 67
68 obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o 68 obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
69 obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o 69 obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
70 obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o 70 obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
71 71
72 obj-$(CONFIG_MFD_CORE) += mfd-core.o 72 obj-$(CONFIG_MFD_CORE) += mfd-core.o
73 73
74 obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o 74 obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
75 75
76 obj-$(CONFIG_MCP) += mcp-core.o 76 obj-$(CONFIG_MCP) += mcp-core.o
77 obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o 77 obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
78 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o 78 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
79 obj-$(CONFIG_MFD_SMSC) += smsc-ece1099.o 79 obj-$(CONFIG_MFD_SMSC) += smsc-ece1099.o
80 obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o 80 obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
81 81
82 ifeq ($(CONFIG_SA1100_ASSABET),y) 82 ifeq ($(CONFIG_SA1100_ASSABET),y)
83 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o 83 obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
84 endif 84 endif
85 obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o 85 obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
86 86
87 obj-$(CONFIG_PMIC_DA903X) += da903x.o 87 obj-$(CONFIG_PMIC_DA903X) += da903x.o
88 88
89 obj-$(CONFIG_PMIC_DA9052) += da9052-core.o 89 obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
90 obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o 90 obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
91 obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o 91 obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
92 92
93 obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o 93 obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
94 94
95 da9055-objs := da9055-core.o da9055-i2c.o 95 da9055-objs := da9055-core.o da9055-i2c.o
96 obj-$(CONFIG_MFD_DA9055) += da9055.o 96 obj-$(CONFIG_MFD_DA9055) += da9055.o
97 97
98 obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o 98 obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
99 obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o 99 obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
100 obj-$(CONFIG_MFD_MAX8907) += max8907.o 100 obj-$(CONFIG_MFD_MAX8907) += max8907.o
101 max8925-objs := max8925-core.o max8925-i2c.o 101 max8925-objs := max8925-core.o max8925-i2c.o
102 obj-$(CONFIG_MFD_MAX8925) += max8925.o 102 obj-$(CONFIG_MFD_MAX8925) += max8925.o
103 obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o 103 obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
104 obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o 104 obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o
105 105
106 pcf50633-objs := pcf50633-core.o pcf50633-irq.o 106 pcf50633-objs := pcf50633-core.o pcf50633-irq.o
107 obj-$(CONFIG_MFD_PCF50633) += pcf50633.o 107 obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
108 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o 108 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
109 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o 109 obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
110 obj-$(CONFIG_ABX500_CORE) += abx500-core.o 110 obj-$(CONFIG_ABX500_CORE) += abx500-core.o
111 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 111 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
112 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 112 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
113 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 113 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
114 obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o 114 obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
115 obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o 115 obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
116 # ab8500-core need to come after db8500-prcmu (which provides the channel) 116 # ab8500-core need to come after db8500-prcmu (which provides the channel)
117 obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 117 obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
118 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 118 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
119 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 119 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
120 obj-$(CONFIG_LPC_SCH) += lpc_sch.o 120 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
121 obj-$(CONFIG_LPC_ICH) += lpc_ich.o 121 obj-$(CONFIG_LPC_ICH) += lpc_ich.o
122 obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o 122 obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
123 obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o 123 obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
124 obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o 124 obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o
125 obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o 125 obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
126 obj-$(CONFIG_MFD_VX855) += vx855.o 126 obj-$(CONFIG_MFD_VX855) += vx855.o
127 obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o 127 obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
128 obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o 128 obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
129 obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o 129 obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
130 obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o 130 obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
131 obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o 131 obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
132 obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o 132 obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
133 obj-$(CONFIG_MFD_TPS65090) += tps65090.o 133 obj-$(CONFIG_MFD_TPS65090) += tps65090.o
134 obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o 134 obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
135 obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o 135 obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
136 obj-$(CONFIG_MFD_PALMAS) += palmas.o 136 obj-$(CONFIG_MFD_PALMAS) += palmas.o
137 obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o 137 obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
138 obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o 138 obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
139 obj-$(CONFIG_MFD_SYSCON) += syscon.o 139 obj-$(CONFIG_MFD_SYSCON) += syscon.o
140 obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o 140 obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
141 obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o 141 obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
142 142
drivers/mfd/vexpress-sysreg.c
File was created 1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * Copyright (C) 2012 ARM Limited
12 */
13
14 #include <linux/err.h>
15 #include <linux/gpio.h>
16 #include <linux/io.h>
17 #include <linux/leds.h>
18 #include <linux/of_address.h>
19 #include <linux/platform_device.h>
20 #include <linux/regulator/driver.h>
21 #include <linux/slab.h>
22 #include <linux/stat.h>
23 #include <linux/timer.h>
24 #include <linux/vexpress.h>
25
26 #define SYS_ID 0x000
27 #define SYS_SW 0x004
28 #define SYS_LED 0x008
29 #define SYS_100HZ 0x024
30 #define SYS_FLAGS 0x030
31 #define SYS_FLAGSSET 0x030
32 #define SYS_FLAGSCLR 0x034
33 #define SYS_NVFLAGS 0x038
34 #define SYS_NVFLAGSSET 0x038
35 #define SYS_NVFLAGSCLR 0x03c
36 #define SYS_MCI 0x048
37 #define SYS_FLASH 0x04c
38 #define SYS_CFGSW 0x058
39 #define SYS_24MHZ 0x05c
40 #define SYS_MISC 0x060
41 #define SYS_DMA 0x064
42 #define SYS_PROCID0 0x084
43 #define SYS_PROCID1 0x088
44 #define SYS_CFGDATA 0x0a0
45 #define SYS_CFGCTRL 0x0a4
46 #define SYS_CFGSTAT 0x0a8
47
48 #define SYS_HBI_MASK 0xfff
49 #define SYS_ID_HBI_SHIFT 16
50 #define SYS_PROCIDx_HBI_SHIFT 0
51
52 #define SYS_MCI_CARDIN (1 << 0)
53 #define SYS_MCI_WPROT (1 << 1)
54
55 #define SYS_FLASH_WPn (1 << 0)
56
57 #define SYS_MISC_MASTERSITE (1 << 14)
58
59 #define SYS_CFGCTRL_START (1 << 31)
60 #define SYS_CFGCTRL_WRITE (1 << 30)
61 #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26)
62 #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20)
63 #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16)
64 #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12)
65 #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0)
66
67 #define SYS_CFGSTAT_ERR (1 << 1)
68 #define SYS_CFGSTAT_COMPLETE (1 << 0)
69
70
71 static void __iomem *vexpress_sysreg_base;
72 static struct device *vexpress_sysreg_dev;
73 static int vexpress_master_site;
74
75
76 void vexpress_flags_set(u32 data)
77 {
78 writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR);
79 writel(data, vexpress_sysreg_base + SYS_FLAGSSET);
80 }
81
82 u32 vexpress_get_procid(int site)
83 {
84 if (site == VEXPRESS_SITE_MASTER)
85 site = vexpress_master_site;
86
87 return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ?
88 SYS_PROCID0 : SYS_PROCID1));
89 }
90
91 u32 vexpress_get_hbi(int site)
92 {
93 u32 id;
94
95 switch (site) {
96 case VEXPRESS_SITE_MB:
97 id = readl(vexpress_sysreg_base + SYS_ID);
98 return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK;
99 case VEXPRESS_SITE_MASTER:
100 case VEXPRESS_SITE_DB1:
101 case VEXPRESS_SITE_DB2:
102 id = vexpress_get_procid(site);
103 return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
104 }
105
106 return ~0;
107 }
108
109 void __iomem *vexpress_get_24mhz_clock_base(void)
110 {
111 return vexpress_sysreg_base + SYS_24MHZ;
112 }
113
114
115 static void vexpress_sysreg_find_prop(struct device_node *node,
116 const char *name, u32 *val)
117 {
118 of_node_get(node);
119 while (node) {
120 if (of_property_read_u32(node, name, val) == 0) {
121 of_node_put(node);
122 return;
123 }
124 node = of_get_next_parent(node);
125 }
126 }
127
128 unsigned __vexpress_get_site(struct device *dev, struct device_node *node)
129 {
130 u32 site = 0;
131
132 WARN_ON(dev && node && dev->of_node != node);
133 if (dev && !node)
134 node = dev->of_node;
135
136 if (node) {
137 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
138 } else if (dev && dev->bus == &platform_bus_type) {
139 struct platform_device *pdev = to_platform_device(dev);
140
141 if (pdev->num_resources == 1 &&
142 pdev->resource[0].flags == IORESOURCE_BUS)
143 site = pdev->resource[0].start;
144 } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) {
145 site = VEXPRESS_SITE_MASTER;
146 }
147
148 if (site == VEXPRESS_SITE_MASTER)
149 site = vexpress_master_site;
150
151 return site;
152 }
153
154
155 struct vexpress_sysreg_config_func {
156 u32 template;
157 u32 device;
158 };
159
160 static struct vexpress_config_bridge *vexpress_sysreg_config_bridge;
161 static struct timer_list vexpress_sysreg_config_timer;
162 static u32 *vexpress_sysreg_config_data;
163 static int vexpress_sysreg_config_tries;
164
165 static void *vexpress_sysreg_config_func_get(struct device *dev,
166 struct device_node *node)
167 {
168 struct vexpress_sysreg_config_func *config_func;
169 u32 site;
170 u32 position = 0;
171 u32 dcc = 0;
172 u32 func_device[2];
173 int err = -EFAULT;
174
175 if (node) {
176 of_node_get(node);
177 vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site);
178 vexpress_sysreg_find_prop(node, "arm,vexpress,position",
179 &position);
180 vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc);
181 err = of_property_read_u32_array(node,
182 "arm,vexpress-sysreg,func", func_device,
183 ARRAY_SIZE(func_device));
184 of_node_put(node);
185 } else if (dev && dev->bus == &platform_bus_type) {
186 struct platform_device *pdev = to_platform_device(dev);
187
188 if (pdev->num_resources == 1 &&
189 pdev->resource[0].flags == IORESOURCE_BUS) {
190 site = pdev->resource[0].start;
191 func_device[0] = pdev->resource[0].end;
192 func_device[1] = pdev->id;
193 err = 0;
194 }
195 }
196 if (err)
197 return NULL;
198
199 config_func = kzalloc(sizeof(*config_func), GFP_KERNEL);
200 if (!config_func)
201 return NULL;
202
203 config_func->template = SYS_CFGCTRL_DCC(dcc);
204 config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]);
205 config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ?
206 vexpress_master_site : site);
207 config_func->template |= SYS_CFGCTRL_POSITION(position);
208 config_func->device |= func_device[1];
209
210 dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func,
211 config_func->template, config_func->device);
212
213 return config_func;
214 }
215
216 static void vexpress_sysreg_config_func_put(void *func)
217 {
218 kfree(func);
219 }
220
221 static int vexpress_sysreg_config_func_exec(void *func, int offset,
222 bool write, u32 *data)
223 {
224 int status;
225 struct vexpress_sysreg_config_func *config_func = func;
226 u32 command;
227
228 if (WARN_ON(!vexpress_sysreg_base))
229 return -ENOENT;
230
231 command = readl(vexpress_sysreg_base + SYS_CFGCTRL);
232 if (WARN_ON(command & SYS_CFGCTRL_START))
233 return -EBUSY;
234
235 command = SYS_CFGCTRL_START;
236 command |= write ? SYS_CFGCTRL_WRITE : 0;
237 command |= config_func->template;
238 command |= SYS_CFGCTRL_DEVICE(config_func->device + offset);
239
240 /* Use a canary for reads */
241 if (!write)
242 *data = 0xdeadbeef;
243
244 dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n",
245 command, *data);
246 writel(*data, vexpress_sysreg_base + SYS_CFGDATA);
247 writel(0, vexpress_sysreg_base + SYS_CFGSTAT);
248 writel(command, vexpress_sysreg_base + SYS_CFGCTRL);
249 mb();
250
251 if (vexpress_sysreg_dev) {
252 /* Schedule completion check */
253 if (!write)
254 vexpress_sysreg_config_data = data;
255 vexpress_sysreg_config_tries = 100;
256 mod_timer(&vexpress_sysreg_config_timer,
257 jiffies + usecs_to_jiffies(100));
258 status = VEXPRESS_CONFIG_STATUS_WAIT;
259 } else {
260 /* Early execution, no timer available, have to spin */
261 u32 cfgstat;
262
263 do {
264 cpu_relax();
265 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
266 } while (!cfgstat);
267
268 if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE))
269 *data = readl(vexpress_sysreg_base + SYS_CFGDATA);
270 status = VEXPRESS_CONFIG_STATUS_DONE;
271
272 if (cfgstat & SYS_CFGSTAT_ERR)
273 status = -EINVAL;
274 }
275
276 return status;
277 }
278
279 struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = {
280 .name = "vexpress-sysreg",
281 .func_get = vexpress_sysreg_config_func_get,
282 .func_put = vexpress_sysreg_config_func_put,
283 .func_exec = vexpress_sysreg_config_func_exec,
284 };
285
286 static void vexpress_sysreg_config_complete(unsigned long data)
287 {
288 int status = VEXPRESS_CONFIG_STATUS_DONE;
289 u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT);
290
291 if (cfgstat & SYS_CFGSTAT_ERR)
292 status = -EINVAL;
293 if (!vexpress_sysreg_config_tries--)
294 status = -ETIMEDOUT;
295
296 if (status < 0) {
297 dev_err(vexpress_sysreg_dev, "error %d\n", status);
298 } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) {
299 mod_timer(&vexpress_sysreg_config_timer,
300 jiffies + usecs_to_jiffies(50));
301 return;
302 }
303
304 if (vexpress_sysreg_config_data) {
305 *vexpress_sysreg_config_data = readl(vexpress_sysreg_base +
306 SYS_CFGDATA);
307 dev_dbg(vexpress_sysreg_dev, "read data %x\n",
308 *vexpress_sysreg_config_data);
309 vexpress_sysreg_config_data = NULL;
310 }
311
312 vexpress_config_complete(vexpress_sysreg_config_bridge, status);
313 }
314
315
316 void __init vexpress_sysreg_early_init(void __iomem *base)
317 {
318 struct device_node *node = of_find_compatible_node(NULL, NULL,
319 "arm,vexpress-sysreg");
320
321 if (node)
322 base = of_iomap(node, 0);
323
324 if (WARN_ON(!base))
325 return;
326
327 vexpress_sysreg_base = base;
328
329 if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE)
330 vexpress_master_site = VEXPRESS_SITE_DB2;
331 else
332 vexpress_master_site = VEXPRESS_SITE_DB1;
333
334 vexpress_sysreg_config_bridge = vexpress_config_bridge_register(
335 node, &vexpress_sysreg_config_bridge_info);
336 WARN_ON(!vexpress_sysreg_config_bridge);
337 }
338
339 void __init vexpress_sysreg_of_early_init(void)
340 {
341 vexpress_sysreg_early_init(NULL);
342 }
343
344
345 static struct vexpress_sysreg_gpio {
346 unsigned long reg;
347 u32 value;
348 } vexpress_sysreg_gpios[] = {
349 [VEXPRESS_GPIO_MMC_CARDIN] = {
350 .reg = SYS_MCI,
351 .value = SYS_MCI_CARDIN,
352 },
353 [VEXPRESS_GPIO_MMC_WPROT] = {
354 .reg = SYS_MCI,
355 .value = SYS_MCI_WPROT,
356 },
357 [VEXPRESS_GPIO_FLASH_WPn] = {
358 .reg = SYS_FLASH,
359 .value = SYS_FLASH_WPn,
360 },
361 };
362
363 static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip,
364 unsigned offset)
365 {
366 return 0;
367 }
368
369 static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip,
370 unsigned offset, int value)
371 {
372 return 0;
373 }
374
375 static int vexpress_sysreg_gpio_get(struct gpio_chip *chip,
376 unsigned offset)
377 {
378 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
379 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
380
381 return !!(reg_value & gpio->value);
382 }
383
384 static void vexpress_sysreg_gpio_set(struct gpio_chip *chip,
385 unsigned offset, int value)
386 {
387 struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset];
388 u32 reg_value = readl(vexpress_sysreg_base + gpio->reg);
389
390 if (value)
391 reg_value |= gpio->value;
392 else
393 reg_value &= ~gpio->value;
394
395 writel(reg_value, vexpress_sysreg_base + gpio->reg);
396 }
397
398 static struct gpio_chip vexpress_sysreg_gpio_chip = {
399 .label = "vexpress-sysreg",
400 .direction_input = vexpress_sysreg_gpio_direction_input,
401 .direction_output = vexpress_sysreg_gpio_direction_output,
402 .get = vexpress_sysreg_gpio_get,
403 .set = vexpress_sysreg_gpio_set,
404 .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios),
405 .base = 0,
406 };
407
408
409 static ssize_t vexpress_sysreg_sys_id_show(struct device *dev,
410 struct device_attribute *attr, char *buf)
411 {
412 return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID));
413 }
414
415 DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL);
416
417 static int __devinit vexpress_sysreg_probe(struct platform_device *pdev)
418 {
419 int err;
420 struct resource *res = platform_get_resource(pdev,
421 IORESOURCE_MEM, 0);
422
423 if (!devm_request_mem_region(&pdev->dev, res->start,
424 resource_size(res), pdev->name)) {
425 dev_err(&pdev->dev, "Failed to request memory region!\n");
426 return -EBUSY;
427 }
428
429 if (!vexpress_sysreg_base)
430 vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start,
431 resource_size(res));
432
433 if (!vexpress_sysreg_base) {
434 dev_err(&pdev->dev, "Failed to obtain base address!\n");
435 return -EFAULT;
436 }
437
438 setup_timer(&vexpress_sysreg_config_timer,
439 vexpress_sysreg_config_complete, 0);
440
441 vexpress_sysreg_gpio_chip.dev = &pdev->dev;
442 err = gpiochip_add(&vexpress_sysreg_gpio_chip);
443 if (err) {
444 vexpress_config_bridge_unregister(
445 vexpress_sysreg_config_bridge);
446 dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n",
447 err);
448 return err;
449 }
450
451 vexpress_sysreg_dev = &pdev->dev;
452
453 device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id);
454
455 return 0;
456 }
457
458 static const struct of_device_id vexpress_sysreg_match[] = {
459 { .compatible = "arm,vexpress-sysreg", },
460 {},
461 };
462
463 static struct platform_driver vexpress_sysreg_driver = {
464 .driver = {
465 .name = "vexpress-sysreg",
466 .of_match_table = vexpress_sysreg_match,
467 },
468 .probe = vexpress_sysreg_probe,
469 };
470
471 static int __init vexpress_sysreg_init(void)
472 {
473 return platform_driver_register(&vexpress_sysreg_driver);
474 }
475 core_initcall(vexpress_sysreg_init);
476
477
478 #if defined(CONFIG_LEDS_CLASS)
479
480 struct vexpress_sysreg_led {
481 u32 mask;
482 struct led_classdev cdev;
483 } vexpress_sysreg_leds[] = {
484 { .mask = 1 << 0, .cdev.name = "v2m:green:user1",
485 .cdev.default_trigger = "heartbeat", },
486 { .mask = 1 << 1, .cdev.name = "v2m:green:user2",
487 .cdev.default_trigger = "mmc0", },
488 { .mask = 1 << 2, .cdev.name = "v2m:green:user3",
489 .cdev.default_trigger = "cpu0", },
490 { .mask = 1 << 3, .cdev.name = "v2m:green:user4",
491 .cdev.default_trigger = "cpu1", },
492 { .mask = 1 << 4, .cdev.name = "v2m:green:user5",
493 .cdev.default_trigger = "cpu2", },
494 { .mask = 1 << 5, .cdev.name = "v2m:green:user6",
495 .cdev.default_trigger = "cpu3", },
496 { .mask = 1 << 6, .cdev.name = "v2m:green:user7",
497 .cdev.default_trigger = "cpu4", },
498 { .mask = 1 << 7, .cdev.name = "v2m:green:user8",
499 .cdev.default_trigger = "cpu5", },
500 };
501
502 static DEFINE_SPINLOCK(vexpress_sysreg_leds_lock);
503
504 static void vexpress_sysreg_led_brightness_set(struct led_classdev *cdev,
505 enum led_brightness brightness)
506 {
507 struct vexpress_sysreg_led *led = container_of(cdev,
508 struct vexpress_sysreg_led, cdev);
509 unsigned long flags;
510 u32 val;
511
512 spin_lock_irqsave(&vexpress_sysreg_leds_lock, flags);
513
514 val = readl(vexpress_sysreg_base + SYS_LED);
515 if (brightness == LED_OFF)
516 val &= ~led->mask;
517 else
518 val |= led->mask;
519 writel(val, vexpress_sysreg_base + SYS_LED);
520
521 spin_unlock_irqrestore(&vexpress_sysreg_leds_lock, flags);
522 }
523
524 static int __init vexpress_sysreg_init_leds(void)
525 {
526 struct vexpress_sysreg_led *led;
527 int i;
528
529 /* Clear all user LEDs */
530 writel(0, vexpress_sysreg_base + SYS_LED);
531
532 for (i = 0, led = vexpress_sysreg_leds;
533 i < ARRAY_SIZE(vexpress_sysreg_leds); i++, led++) {
534 int err;
535
536 led->cdev.brightness_set = vexpress_sysreg_led_brightness_set;
537 err = led_classdev_register(vexpress_sysreg_dev, &led->cdev);
538 if (err) {
539 dev_err(vexpress_sysreg_dev,
540 "Failed to register LED %d! (%d)\n",
541 i, err);
542 while (led--, i--)
543 led_classdev_unregister(&led->cdev);
544 return err;
545 }
546 }
547
548 return 0;
549 }
550 device_initcall(vexpress_sysreg_init_leds);
551
552 #endif
553
include/linux/vexpress.h
1 /* 1 /*
2 * This program is free software; you can redistribute it and/or modify 2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as 3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation. 4 * published by the Free Software Foundation.
5 * 5 *
6 * This program is distributed in the hope that it will be useful, 6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of 7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details. 9 * GNU General Public License for more details.
10 * 10 *
11 * Copyright (C) 2012 ARM Limited 11 * Copyright (C) 2012 ARM Limited
12 */ 12 */
13 13
14 #ifndef _LINUX_VEXPRESS_H 14 #ifndef _LINUX_VEXPRESS_H
15 #define _LINUX_VEXPRESS_H 15 #define _LINUX_VEXPRESS_H
16 16
17 #include <linux/device.h> 17 #include <linux/device.h>
18 18
19 #define VEXPRESS_SITE_MB 0 19 #define VEXPRESS_SITE_MB 0
20 #define VEXPRESS_SITE_DB1 1 20 #define VEXPRESS_SITE_DB1 1
21 #define VEXPRESS_SITE_DB2 2 21 #define VEXPRESS_SITE_DB2 2
22 #define VEXPRESS_SITE_MASTER 0xf 22 #define VEXPRESS_SITE_MASTER 0xf
23 23
24 #define VEXPRESS_CONFIG_STATUS_DONE 0 24 #define VEXPRESS_CONFIG_STATUS_DONE 0
25 #define VEXPRESS_CONFIG_STATUS_WAIT 1 25 #define VEXPRESS_CONFIG_STATUS_WAIT 1
26 26
27 #define VEXPRESS_GPIO_MMC_CARDIN 0
28 #define VEXPRESS_GPIO_MMC_WPROT 1
29 #define VEXPRESS_GPIO_FLASH_WPn 2
30
31 #define VEXPRESS_RES_FUNC(_site, _func) \
32 { \
33 .start = (_site), \
34 .end = (_func), \
35 .flags = IORESOURCE_BUS, \
36 }
37
27 /* Config bridge API */ 38 /* Config bridge API */
28 39
29 /** 40 /**
30 * struct vexpress_config_bridge_info - description of the platform 41 * struct vexpress_config_bridge_info - description of the platform
31 * configuration infrastructure bridge. 42 * configuration infrastructure bridge.
32 * 43 *
33 * @name: Bridge name 44 * @name: Bridge name
34 * 45 *
35 * @func_get: Obtains pointer to a configuration function for a given 46 * @func_get: Obtains pointer to a configuration function for a given
36 * device or a Device Tree node, to be used with @func_put 47 * device or a Device Tree node, to be used with @func_put
37 * and @func_exec. The node pointer should take precedence 48 * and @func_exec. The node pointer should take precedence
38 * over device pointer when both are passed. 49 * over device pointer when both are passed.
39 * 50 *
40 * @func_put: Tells the bridge that the function will not be used any 51 * @func_put: Tells the bridge that the function will not be used any
41 * more, so all allocated resources can be released. 52 * more, so all allocated resources can be released.
42 * 53 *
43 * @func_exec: Executes a configuration function read or write operation. 54 * @func_exec: Executes a configuration function read or write operation.
44 * The offset selects a 32 bit word of the value accessed. 55 * The offset selects a 32 bit word of the value accessed.
45 * Must return VEXPRESS_CONFIG_STATUS_DONE when operation 56 * Must return VEXPRESS_CONFIG_STATUS_DONE when operation
46 * is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when 57 * is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when
47 * will be completed in some time or negative value in case 58 * will be completed in some time or negative value in case
48 * of error. 59 * of error.
49 */ 60 */
50 struct vexpress_config_bridge_info { 61 struct vexpress_config_bridge_info {
51 const char *name; 62 const char *name;
52 void *(*func_get)(struct device *dev, struct device_node *node); 63 void *(*func_get)(struct device *dev, struct device_node *node);
53 void (*func_put)(void *func); 64 void (*func_put)(void *func);
54 int (*func_exec)(void *func, int offset, bool write, u32 *data); 65 int (*func_exec)(void *func, int offset, bool write, u32 *data);
55 }; 66 };
56 67
57 struct vexpress_config_bridge; 68 struct vexpress_config_bridge;
58 69
59 struct vexpress_config_bridge *vexpress_config_bridge_register( 70 struct vexpress_config_bridge *vexpress_config_bridge_register(
60 struct device_node *node, 71 struct device_node *node,
61 struct vexpress_config_bridge_info *info); 72 struct vexpress_config_bridge_info *info);
62 void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge); 73 void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge);
63 74
64 void vexpress_config_complete(struct vexpress_config_bridge *bridge, 75 void vexpress_config_complete(struct vexpress_config_bridge *bridge,
65 int status); 76 int status);
66 77
67 /* Config function API */ 78 /* Config function API */
68 79
69 struct vexpress_config_func; 80 struct vexpress_config_func;
70 81
71 struct vexpress_config_func *__vexpress_config_func_get(struct device *dev, 82 struct vexpress_config_func *__vexpress_config_func_get(struct device *dev,
72 struct device_node *node); 83 struct device_node *node);
73 #define vexpress_config_func_get_by_dev(dev) \ 84 #define vexpress_config_func_get_by_dev(dev) \
74 __vexpress_config_func_get(dev, NULL) 85 __vexpress_config_func_get(dev, NULL)
75 #define vexpress_config_func_get_by_node(node) \ 86 #define vexpress_config_func_get_by_node(node) \
76 __vexpress_config_func_get(NULL, node) 87 __vexpress_config_func_get(NULL, node)
77 void vexpress_config_func_put(struct vexpress_config_func *func); 88 void vexpress_config_func_put(struct vexpress_config_func *func);
78 89
79 /* Both may sleep! */ 90 /* Both may sleep! */
80 int vexpress_config_read(struct vexpress_config_func *func, int offset, 91 int vexpress_config_read(struct vexpress_config_func *func, int offset,
81 u32 *data); 92 u32 *data);
82 int vexpress_config_write(struct vexpress_config_func *func, int offset, 93 int vexpress_config_write(struct vexpress_config_func *func, int offset,
83 u32 data); 94 u32 data);
95
96 /* Platform control */
97
98 u32 vexpress_get_procid(int site);
99 u32 vexpress_get_hbi(int site);
100 void *vexpress_get_24mhz_clock_base(void);
101 void vexpress_flags_set(u32 data);
102
103 #define vexpress_get_site_by_node(node) __vexpress_get_site(NULL, node)
104 #define vexpress_get_site_by_dev(dev) __vexpress_get_site(dev, NULL)
105 unsigned __vexpress_get_site(struct device *dev, struct device_node *node);
106
107 void vexpress_sysreg_early_init(void __iomem *base);
108 void vexpress_sysreg_of_early_init(void);
84 109
85 #endif 110 #endif
86 111