diff options
author | Arnd Bergmann <arnd@arndb.de> | 2016-07-14 09:23:19 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2016-07-14 09:23:19 -0400 |
commit | f1844aca29025bb436bfc4f872456b832632df56 (patch) | |
tree | a9df7248ed8595db2f3313ea2e016cf19757eca4 /drivers | |
parent | cf1d9dd447935bd90d42ee349c1da2498cff8775 (diff) | |
parent | a16729ea822806a6f87415bcb523eaeb7f4b4ebd (diff) |
Merge tag 'ux500-cleanup-bundle' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into next/drivers
Merge "Ux500 cleanups from Arnd" from Linus Walleij:
This is a set of cleanups for the Ux500 that reduce the number
of machine-local files and boardfile-type data for regulators
and ASoC.
* tag 'ux500-cleanup-bundle' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson:
ARM: ux500: consolidate base platform files
ARM: ux500: move soc_id driver to drivers/soc
ARM: ux500: call ux500_setup_id later
ARM: ux500: consolidate soc_device code in id.c
ARM: ux500: remove cpu_is_u* helpers
ARM: ux500: use CLK_OF_DECLARE()
ARM: ux500: move l2x0 init to .init_irq
mfd: db8500 stop passing around platform data
ASoC: ab8500-codec: remove platform data based probe
ARM: ux500: move ab8500_regulator_plat_data into driver
ARM: ux500: remove unused regulator data
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/ux500/u8500_of_clk.c | 16 | ||||
-rw-r--r-- | drivers/clk/ux500/u8540_clk.c | 16 | ||||
-rw-r--r-- | drivers/clk/ux500/u9540_clk.c | 4 | ||||
-rw-r--r-- | drivers/mfd/ab8500-core.c | 4 | ||||
-rw-r--r-- | drivers/mfd/ab8500-sysctrl.c | 34 | ||||
-rw-r--r-- | drivers/mfd/db8500-prcmu.c | 10 | ||||
-rw-r--r-- | drivers/regulator/ab8500-ext.c | 465 | ||||
-rw-r--r-- | drivers/soc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/soc/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/ux500/Kconfig | 7 | ||||
-rw-r--r-- | drivers/soc/ux500/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/ux500/ux500-soc-id.c | 222 |
12 files changed, 692 insertions, 89 deletions
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 9a736d939806..e960d686d9db 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/of_address.h> | 11 | #include <linux/of_address.h> |
12 | #include <linux/clk-provider.h> | 12 | #include <linux/clk-provider.h> |
13 | #include <linux/mfd/dbx500-prcmu.h> | 13 | #include <linux/mfd/dbx500-prcmu.h> |
14 | #include <linux/platform_data/clk-ux500.h> | ||
15 | #include "clk.h" | 14 | #include "clk.h" |
16 | 15 | ||
17 | #define PRCC_NUM_PERIPH_CLUSTERS 6 | 16 | #define PRCC_NUM_PERIPH_CLUSTERS 6 |
@@ -48,11 +47,6 @@ static struct clk *ux500_twocell_get(struct of_phandle_args *clkspec, | |||
48 | return PRCC_SHOW(clk_data, base, bit); | 47 | return PRCC_SHOW(clk_data, base, bit); |
49 | } | 48 | } |
50 | 49 | ||
51 | static const struct of_device_id u8500_clk_of_match[] = { | ||
52 | { .compatible = "stericsson,u8500-clks", }, | ||
53 | { }, | ||
54 | }; | ||
55 | |||
56 | /* CLKRST4 is missing making it hard to index things */ | 50 | /* CLKRST4 is missing making it hard to index things */ |
57 | enum clkrst_index { | 51 | enum clkrst_index { |
58 | CLKRST1_INDEX = 0, | 52 | CLKRST1_INDEX = 0, |
@@ -63,22 +57,15 @@ enum clkrst_index { | |||
63 | CLKRST_MAX, | 57 | CLKRST_MAX, |
64 | }; | 58 | }; |
65 | 59 | ||
66 | void u8500_clk_init(void) | 60 | static void u8500_clk_init(struct device_node *np) |
67 | { | 61 | { |
68 | struct prcmu_fw_version *fw_version; | 62 | struct prcmu_fw_version *fw_version; |
69 | struct device_node *np = NULL; | ||
70 | struct device_node *child = NULL; | 63 | struct device_node *child = NULL; |
71 | const char *sgaclk_parent = NULL; | 64 | const char *sgaclk_parent = NULL; |
72 | struct clk *clk, *rtc_clk, *twd_clk; | 65 | struct clk *clk, *rtc_clk, *twd_clk; |
73 | u32 bases[CLKRST_MAX]; | 66 | u32 bases[CLKRST_MAX]; |
74 | int i; | 67 | int i; |
75 | 68 | ||
76 | if (of_have_populated_dt()) | ||
77 | np = of_find_matching_node(NULL, u8500_clk_of_match); | ||
78 | if (!np) { | ||
79 | pr_err("Either DT or U8500 Clock node not found\n"); | ||
80 | return; | ||
81 | } | ||
82 | for (i = 0; i < ARRAY_SIZE(bases); i++) { | 69 | for (i = 0; i < ARRAY_SIZE(bases); i++) { |
83 | struct resource r; | 70 | struct resource r; |
84 | 71 | ||
@@ -573,3 +560,4 @@ void u8500_clk_init(void) | |||
573 | of_clk_add_provider(child, of_clk_src_simple_get, twd_clk); | 560 | of_clk_add_provider(child, of_clk_src_simple_get, twd_clk); |
574 | } | 561 | } |
575 | } | 562 | } |
563 | CLK_OF_DECLARE(u8500_clks, "stericsson,u8500-clks", u8500_clk_init); | ||
diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c index 86549e59fb42..133859f0e2bf 100644 --- a/drivers/clk/ux500/u8540_clk.c +++ b/drivers/clk/ux500/u8540_clk.c | |||
@@ -12,14 +12,8 @@ | |||
12 | #include <linux/clkdev.h> | 12 | #include <linux/clkdev.h> |
13 | #include <linux/clk-provider.h> | 13 | #include <linux/clk-provider.h> |
14 | #include <linux/mfd/dbx500-prcmu.h> | 14 | #include <linux/mfd/dbx500-prcmu.h> |
15 | #include <linux/platform_data/clk-ux500.h> | ||
16 | #include "clk.h" | 15 | #include "clk.h" |
17 | 16 | ||
18 | static const struct of_device_id u8540_clk_of_match[] = { | ||
19 | { .compatible = "stericsson,u8540-clks", }, | ||
20 | { } | ||
21 | }; | ||
22 | |||
23 | /* CLKRST4 is missing making it hard to index things */ | 17 | /* CLKRST4 is missing making it hard to index things */ |
24 | enum clkrst_index { | 18 | enum clkrst_index { |
25 | CLKRST1_INDEX = 0, | 19 | CLKRST1_INDEX = 0, |
@@ -30,19 +24,12 @@ enum clkrst_index { | |||
30 | CLKRST_MAX, | 24 | CLKRST_MAX, |
31 | }; | 25 | }; |
32 | 26 | ||
33 | void u8540_clk_init(void) | 27 | static void u8540_clk_init(struct device_node *np) |
34 | { | 28 | { |
35 | struct clk *clk; | 29 | struct clk *clk; |
36 | struct device_node *np = NULL; | ||
37 | u32 bases[CLKRST_MAX]; | 30 | u32 bases[CLKRST_MAX]; |
38 | int i; | 31 | int i; |
39 | 32 | ||
40 | if (of_have_populated_dt()) | ||
41 | np = of_find_matching_node(NULL, u8540_clk_of_match); | ||
42 | if (!np) { | ||
43 | pr_err("Either DT or U8540 Clock node not found\n"); | ||
44 | return; | ||
45 | } | ||
46 | for (i = 0; i < ARRAY_SIZE(bases); i++) { | 33 | for (i = 0; i < ARRAY_SIZE(bases); i++) { |
47 | struct resource r; | 34 | struct resource r; |
48 | 35 | ||
@@ -607,3 +594,4 @@ void u8540_clk_init(void) | |||
607 | bases[CLKRST6_INDEX], BIT(0), CLK_SET_RATE_GATE); | 594 | bases[CLKRST6_INDEX], BIT(0), CLK_SET_RATE_GATE); |
608 | clk_register_clkdev(clk, NULL, "rng"); | 595 | clk_register_clkdev(clk, NULL, "rng"); |
609 | } | 596 | } |
597 | CLK_OF_DECLARE(u8540_clks, "stericsson,u8540-clks", u8540_clk_init); | ||
diff --git a/drivers/clk/ux500/u9540_clk.c b/drivers/clk/ux500/u9540_clk.c index 2138a4c8cbca..7b6bca49ce42 100644 --- a/drivers/clk/ux500/u9540_clk.c +++ b/drivers/clk/ux500/u9540_clk.c | |||
@@ -9,10 +9,10 @@ | |||
9 | 9 | ||
10 | #include <linux/clk-provider.h> | 10 | #include <linux/clk-provider.h> |
11 | #include <linux/mfd/dbx500-prcmu.h> | 11 | #include <linux/mfd/dbx500-prcmu.h> |
12 | #include <linux/platform_data/clk-ux500.h> | ||
13 | #include "clk.h" | 12 | #include "clk.h" |
14 | 13 | ||
15 | void u9540_clk_init(void) | 14 | static void u9540_clk_init(struct device_node *np) |
16 | { | 15 | { |
17 | /* register clocks here */ | 16 | /* register clocks here */ |
18 | } | 17 | } |
18 | CLK_OF_DECLARE(u9540_clks, "stericsson,u9540-clks", u9540_clk_init); | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index f3d689176fc2..589eebfc13df 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -1087,7 +1087,6 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1087 | "Vbus Detect (USB)", | 1087 | "Vbus Detect (USB)", |
1088 | "USB ID Detect", | 1088 | "USB ID Detect", |
1089 | "UART Factory Mode Detect"}; | 1089 | "UART Factory Mode Detect"}; |
1090 | struct ab8500_platform_data *plat = dev_get_platdata(&pdev->dev); | ||
1091 | const struct platform_device_id *platid = platform_get_device_id(pdev); | 1090 | const struct platform_device_id *platid = platform_get_device_id(pdev); |
1092 | enum ab8500_version version = AB8500_VERSION_UNDEFINED; | 1091 | enum ab8500_version version = AB8500_VERSION_UNDEFINED; |
1093 | struct device_node *np = pdev->dev.of_node; | 1092 | struct device_node *np = pdev->dev.of_node; |
@@ -1219,9 +1218,6 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1219 | pr_cont("None\n"); | 1218 | pr_cont("None\n"); |
1220 | } | 1219 | } |
1221 | 1220 | ||
1222 | if (plat && plat->init) | ||
1223 | plat->init(ab8500); | ||
1224 | |||
1225 | if (is_ab9540(ab8500)) { | 1221 | if (is_ab9540(ab8500)) { |
1226 | ret = get_register_interruptible(ab8500, AB8500_CHARGER, | 1222 | ret = get_register_interruptible(ab8500, AB8500_CHARGER, |
1227 | AB8500_CH_USBCH_STAT1_REG, &value); | 1223 | AB8500_CH_USBCH_STAT1_REG, &value); |
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index b9f0010309f9..207cc497958a 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
@@ -127,45 +127,11 @@ EXPORT_SYMBOL(ab8500_sysctrl_write); | |||
127 | 127 | ||
128 | static int ab8500_sysctrl_probe(struct platform_device *pdev) | 128 | static int ab8500_sysctrl_probe(struct platform_device *pdev) |
129 | { | 129 | { |
130 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
131 | struct ab8500_platform_data *plat; | ||
132 | struct ab8500_sysctrl_platform_data *pdata; | ||
133 | |||
134 | plat = dev_get_platdata(pdev->dev.parent); | ||
135 | |||
136 | if (!plat) | ||
137 | return -EINVAL; | ||
138 | |||
139 | sysctrl_dev = &pdev->dev; | 130 | sysctrl_dev = &pdev->dev; |
140 | 131 | ||
141 | if (!pm_power_off) | 132 | if (!pm_power_off) |
142 | pm_power_off = ab8500_power_off; | 133 | pm_power_off = ab8500_power_off; |
143 | 134 | ||
144 | pdata = plat->sysctrl; | ||
145 | if (pdata) { | ||
146 | int last, ret, i, j; | ||
147 | |||
148 | if (is_ab8505(ab8500)) | ||
149 | last = AB8500_SYSCLKREQ4RFCLKBUF; | ||
150 | else | ||
151 | last = AB8500_SYSCLKREQ8RFCLKBUF; | ||
152 | |||
153 | for (i = AB8500_SYSCLKREQ1RFCLKBUF; i <= last; i++) { | ||
154 | j = i - AB8500_SYSCLKREQ1RFCLKBUF; | ||
155 | ret = ab8500_sysctrl_write(i, 0xff, | ||
156 | pdata->initial_req_buf_config[j]); | ||
157 | dev_dbg(&pdev->dev, | ||
158 | "Setting SysClkReq%dRfClkBuf 0x%X\n", | ||
159 | j + 1, | ||
160 | pdata->initial_req_buf_config[j]); | ||
161 | if (ret < 0) { | ||
162 | dev_err(&pdev->dev, | ||
163 | "Can't set sysClkReq%dRfClkBuf: %d\n", | ||
164 | j + 1, ret); | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | |||
169 | return 0; | 135 | return 0; |
170 | } | 136 | } |
171 | 137 | ||
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index c0a86aeb1733..388e268b9bcf 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -3094,8 +3094,7 @@ static void db8500_prcmu_update_cpufreq(void) | |||
3094 | } | 3094 | } |
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | static int db8500_prcmu_register_ab8500(struct device *parent, | 3097 | static int db8500_prcmu_register_ab8500(struct device *parent) |
3098 | struct ab8500_platform_data *pdata) | ||
3099 | { | 3098 | { |
3100 | struct device_node *np; | 3099 | struct device_node *np; |
3101 | struct resource ab8500_resource; | 3100 | struct resource ab8500_resource; |
@@ -3103,8 +3102,6 @@ static int db8500_prcmu_register_ab8500(struct device *parent, | |||
3103 | .name = "ab8500-core", | 3102 | .name = "ab8500-core", |
3104 | .of_compatible = "stericsson,ab8500", | 3103 | .of_compatible = "stericsson,ab8500", |
3105 | .id = AB8500_VERSION_AB8500, | 3104 | .id = AB8500_VERSION_AB8500, |
3106 | .platform_data = pdata, | ||
3107 | .pdata_size = sizeof(struct ab8500_platform_data), | ||
3108 | .resources = &ab8500_resource, | 3105 | .resources = &ab8500_resource, |
3109 | .num_resources = 1, | 3106 | .num_resources = 1, |
3110 | }; | 3107 | }; |
@@ -3133,7 +3130,6 @@ static int db8500_prcmu_register_ab8500(struct device *parent, | |||
3133 | static int db8500_prcmu_probe(struct platform_device *pdev) | 3130 | static int db8500_prcmu_probe(struct platform_device *pdev) |
3134 | { | 3131 | { |
3135 | struct device_node *np = pdev->dev.of_node; | 3132 | struct device_node *np = pdev->dev.of_node; |
3136 | struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
3137 | int irq = 0, err = 0; | 3133 | int irq = 0, err = 0; |
3138 | struct resource *res; | 3134 | struct resource *res; |
3139 | 3135 | ||
@@ -3149,7 +3145,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3149 | return -ENOMEM; | 3145 | return -ENOMEM; |
3150 | } | 3146 | } |
3151 | init_prcm_registers(); | 3147 | init_prcm_registers(); |
3152 | dbx500_fw_version_init(pdev, pdata->version_offset); | 3148 | dbx500_fw_version_init(pdev, DB8500_PRCMU_FW_VERSION_OFFSET); |
3153 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); | 3149 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); |
3154 | if (!res) { | 3150 | if (!res) { |
3155 | dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); | 3151 | dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); |
@@ -3204,7 +3200,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) | |||
3204 | } | 3200 | } |
3205 | } | 3201 | } |
3206 | 3202 | ||
3207 | err = db8500_prcmu_register_ab8500(&pdev->dev, pdata->ab_platdata); | 3203 | err = db8500_prcmu_register_ab8500(&pdev->dev); |
3208 | if (err) { | 3204 | if (err) { |
3209 | mfd_remove_devices(&pdev->dev); | 3205 | mfd_remove_devices(&pdev->dev); |
3210 | pr_err("prcmu: Failed to add ab8500 subdevice\n"); | 3206 | pr_err("prcmu: Failed to add ab8500 subdevice\n"); |
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index 84c1ee39ddae..2ca00045eb99 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c | |||
@@ -25,6 +25,456 @@ | |||
25 | #include <linux/mfd/abx500/ab8500.h> | 25 | #include <linux/mfd/abx500/ab8500.h> |
26 | #include <linux/regulator/ab8500.h> | 26 | #include <linux/regulator/ab8500.h> |
27 | 27 | ||
28 | static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { | ||
29 | /* Main display, u8500 R3 uib */ | ||
30 | REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), | ||
31 | /* Main display, u8500 uib and ST uib */ | ||
32 | REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.0"), | ||
33 | /* Secondary display, ST uib */ | ||
34 | REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.1"), | ||
35 | /* SFH7741 proximity sensor */ | ||
36 | REGULATOR_SUPPLY("vcc", "gpio-keys.0"), | ||
37 | /* BH1780GLS ambient light sensor */ | ||
38 | REGULATOR_SUPPLY("vcc", "2-0029"), | ||
39 | /* lsm303dlh accelerometer */ | ||
40 | REGULATOR_SUPPLY("vdd", "2-0018"), | ||
41 | /* lsm303dlhc accelerometer */ | ||
42 | REGULATOR_SUPPLY("vdd", "2-0019"), | ||
43 | /* lsm303dlh magnetometer */ | ||
44 | REGULATOR_SUPPLY("vdd", "2-001e"), | ||
45 | /* Rohm BU21013 Touchscreen devices */ | ||
46 | REGULATOR_SUPPLY("avdd", "3-005c"), | ||
47 | REGULATOR_SUPPLY("avdd", "3-005d"), | ||
48 | /* Synaptics RMI4 Touchscreen device */ | ||
49 | REGULATOR_SUPPLY("vdd", "3-004b"), | ||
50 | /* L3G4200D Gyroscope device */ | ||
51 | REGULATOR_SUPPLY("vdd", "2-0068"), | ||
52 | /* Ambient light sensor device */ | ||
53 | REGULATOR_SUPPLY("vdd", "3-0029"), | ||
54 | /* Pressure sensor device */ | ||
55 | REGULATOR_SUPPLY("vdd", "2-005c"), | ||
56 | /* Cypress TrueTouch Touchscreen device */ | ||
57 | REGULATOR_SUPPLY("vcpin", "spi8.0"), | ||
58 | /* Camera device */ | ||
59 | REGULATOR_SUPPLY("vaux12v5", "mmio_camera"), | ||
60 | }; | ||
61 | |||
62 | static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { | ||
63 | /* On-board eMMC power */ | ||
64 | REGULATOR_SUPPLY("vmmc", "sdi4"), | ||
65 | /* AB8500 audio codec */ | ||
66 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"), | ||
67 | /* AB8500 accessory detect 1 */ | ||
68 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-acc-det.0"), | ||
69 | /* AB8500 Tv-out device */ | ||
70 | REGULATOR_SUPPLY("vcc-N2158", "mcde_tv_ab8500.4"), | ||
71 | /* AV8100 HDMI device */ | ||
72 | REGULATOR_SUPPLY("vcc-N2158", "av8100_hdmi.3"), | ||
73 | }; | ||
74 | |||
75 | static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { | ||
76 | REGULATOR_SUPPLY("v-SD-STM", "stm"), | ||
77 | /* External MMC slot power */ | ||
78 | REGULATOR_SUPPLY("vmmc", "sdi0"), | ||
79 | }; | ||
80 | |||
81 | static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { | ||
82 | /* TV-out DENC supply */ | ||
83 | REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), | ||
84 | /* Internal general-purpose ADC */ | ||
85 | REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), | ||
86 | /* ADC for charger */ | ||
87 | REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"), | ||
88 | /* AB8500 Tv-out device */ | ||
89 | REGULATOR_SUPPLY("vtvout", "mcde_tv_ab8500.4"), | ||
90 | }; | ||
91 | |||
92 | static struct regulator_consumer_supply ab8500_vaud_consumers[] = { | ||
93 | /* AB8500 audio-codec main supply */ | ||
94 | REGULATOR_SUPPLY("vaud", "ab8500-codec.0"), | ||
95 | }; | ||
96 | |||
97 | static struct regulator_consumer_supply ab8500_vamic1_consumers[] = { | ||
98 | /* AB8500 audio-codec Mic1 supply */ | ||
99 | REGULATOR_SUPPLY("vamic1", "ab8500-codec.0"), | ||
100 | }; | ||
101 | |||
102 | static struct regulator_consumer_supply ab8500_vamic2_consumers[] = { | ||
103 | /* AB8500 audio-codec Mic2 supply */ | ||
104 | REGULATOR_SUPPLY("vamic2", "ab8500-codec.0"), | ||
105 | }; | ||
106 | |||
107 | static struct regulator_consumer_supply ab8500_vdmic_consumers[] = { | ||
108 | /* AB8500 audio-codec DMic supply */ | ||
109 | REGULATOR_SUPPLY("vdmic", "ab8500-codec.0"), | ||
110 | }; | ||
111 | |||
112 | static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { | ||
113 | /* SoC core supply, no device */ | ||
114 | REGULATOR_SUPPLY("v-intcore", NULL), | ||
115 | /* USB Transceiver */ | ||
116 | REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"), | ||
117 | /* Handled by abx500 clk driver */ | ||
118 | REGULATOR_SUPPLY("v-intcore", "abx500-clk.0"), | ||
119 | }; | ||
120 | |||
121 | static struct regulator_consumer_supply ab8500_vana_consumers[] = { | ||
122 | /* DB8500 DSI */ | ||
123 | REGULATOR_SUPPLY("vdddsi1v2", "mcde"), | ||
124 | REGULATOR_SUPPLY("vdddsi1v2", "b2r2_core"), | ||
125 | REGULATOR_SUPPLY("vdddsi1v2", "b2r2_1_core"), | ||
126 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.0"), | ||
127 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.1"), | ||
128 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.2"), | ||
129 | /* DB8500 CSI */ | ||
130 | REGULATOR_SUPPLY("vddcsi1v2", "mmio_camera"), | ||
131 | }; | ||
132 | |||
133 | /* ab8500 regulator register initialization */ | ||
134 | static struct ab8500_regulator_reg_init ab8500_reg_init[] = { | ||
135 | /* | ||
136 | * VanaRequestCtrl = HP/LP depending on VxRequest | ||
137 | * VextSupply1RequestCtrl = HP/LP depending on VxRequest | ||
138 | */ | ||
139 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xf0, 0x00), | ||
140 | /* | ||
141 | * VextSupply2RequestCtrl = HP/LP depending on VxRequest | ||
142 | * VextSupply3RequestCtrl = HP/LP depending on VxRequest | ||
143 | * Vaux1RequestCtrl = HP/LP depending on VxRequest | ||
144 | * Vaux2RequestCtrl = HP/LP depending on VxRequest | ||
145 | */ | ||
146 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0xff, 0x00), | ||
147 | /* | ||
148 | * Vaux3RequestCtrl = HP/LP depending on VxRequest | ||
149 | * SwHPReq = Control through SWValid disabled | ||
150 | */ | ||
151 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00), | ||
152 | /* | ||
153 | * VanaSysClkReq1HPValid = disabled | ||
154 | * Vaux1SysClkReq1HPValid = disabled | ||
155 | * Vaux2SysClkReq1HPValid = disabled | ||
156 | * Vaux3SysClkReq1HPValid = disabled | ||
157 | */ | ||
158 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), | ||
159 | /* | ||
160 | * VextSupply1SysClkReq1HPValid = disabled | ||
161 | * VextSupply2SysClkReq1HPValid = disabled | ||
162 | * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled | ||
163 | */ | ||
164 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x70, 0x40), | ||
165 | /* | ||
166 | * VanaHwHPReq1Valid = disabled | ||
167 | * Vaux1HwHPreq1Valid = disabled | ||
168 | * Vaux2HwHPReq1Valid = disabled | ||
169 | * Vaux3HwHPReqValid = disabled | ||
170 | */ | ||
171 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0xe8, 0x00), | ||
172 | /* | ||
173 | * VextSupply1HwHPReq1Valid = disabled | ||
174 | * VextSupply2HwHPReq1Valid = disabled | ||
175 | * VextSupply3HwHPReq1Valid = disabled | ||
176 | */ | ||
177 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x07, 0x00), | ||
178 | /* | ||
179 | * VanaHwHPReq2Valid = disabled | ||
180 | * Vaux1HwHPReq2Valid = disabled | ||
181 | * Vaux2HwHPReq2Valid = disabled | ||
182 | * Vaux3HwHPReq2Valid = disabled | ||
183 | */ | ||
184 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0xe8, 0x00), | ||
185 | /* | ||
186 | * VextSupply1HwHPReq2Valid = disabled | ||
187 | * VextSupply2HwHPReq2Valid = disabled | ||
188 | * VextSupply3HwHPReq2Valid = HWReq2 controlled | ||
189 | */ | ||
190 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x07, 0x04), | ||
191 | /* | ||
192 | * VanaSwHPReqValid = disabled | ||
193 | * Vaux1SwHPReqValid = disabled | ||
194 | */ | ||
195 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0xa0, 0x00), | ||
196 | /* | ||
197 | * Vaux2SwHPReqValid = disabled | ||
198 | * Vaux3SwHPReqValid = disabled | ||
199 | * VextSupply1SwHPReqValid = disabled | ||
200 | * VextSupply2SwHPReqValid = disabled | ||
201 | * VextSupply3SwHPReqValid = disabled | ||
202 | */ | ||
203 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x1f, 0x00), | ||
204 | /* | ||
205 | * SysClkReq2Valid1 = SysClkReq2 controlled | ||
206 | * SysClkReq3Valid1 = disabled | ||
207 | * SysClkReq4Valid1 = SysClkReq4 controlled | ||
208 | * SysClkReq5Valid1 = disabled | ||
209 | * SysClkReq6Valid1 = SysClkReq6 controlled | ||
210 | * SysClkReq7Valid1 = disabled | ||
211 | * SysClkReq8Valid1 = disabled | ||
212 | */ | ||
213 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0xfe, 0x2a), | ||
214 | /* | ||
215 | * SysClkReq2Valid2 = disabled | ||
216 | * SysClkReq3Valid2 = disabled | ||
217 | * SysClkReq4Valid2 = disabled | ||
218 | * SysClkReq5Valid2 = disabled | ||
219 | * SysClkReq6Valid2 = SysClkReq6 controlled | ||
220 | * SysClkReq7Valid2 = disabled | ||
221 | * SysClkReq8Valid2 = disabled | ||
222 | */ | ||
223 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0xfe, 0x20), | ||
224 | /* | ||
225 | * VTVoutEna = disabled | ||
226 | * Vintcore12Ena = disabled | ||
227 | * Vintcore12Sel = 1.25 V | ||
228 | * Vintcore12LP = inactive (HP) | ||
229 | * VTVoutLP = inactive (HP) | ||
230 | */ | ||
231 | INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0xfe, 0x10), | ||
232 | /* | ||
233 | * VaudioEna = disabled | ||
234 | * VdmicEna = disabled | ||
235 | * Vamic1Ena = disabled | ||
236 | * Vamic2Ena = disabled | ||
237 | */ | ||
238 | INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x1e, 0x00), | ||
239 | /* | ||
240 | * Vamic1_dzout = high-Z when Vamic1 is disabled | ||
241 | * Vamic2_dzout = high-Z when Vamic2 is disabled | ||
242 | */ | ||
243 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), | ||
244 | /* | ||
245 | * VPll = Hw controlled (NOTE! PRCMU bits) | ||
246 | * VanaRegu = force off | ||
247 | */ | ||
248 | INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02), | ||
249 | /* | ||
250 | * VrefDDREna = disabled | ||
251 | * VrefDDRSleepMode = inactive (no pulldown) | ||
252 | */ | ||
253 | INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x03, 0x00), | ||
254 | /* | ||
255 | * VextSupply1Regu = force LP | ||
256 | * VextSupply2Regu = force OFF | ||
257 | * VextSupply3Regu = force HP (-> STBB2=LP and TPS=LP) | ||
258 | * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 | ||
259 | * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 | ||
260 | */ | ||
261 | INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0xff, 0x13), | ||
262 | /* | ||
263 | * Vaux1Regu = force HP | ||
264 | * Vaux2Regu = force off | ||
265 | */ | ||
266 | INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01), | ||
267 | /* | ||
268 | * Vaux3Regu = force off | ||
269 | */ | ||
270 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x03, 0x00), | ||
271 | /* | ||
272 | * Vaux1Sel = 2.8 V | ||
273 | */ | ||
274 | INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x0f, 0x0C), | ||
275 | /* | ||
276 | * Vaux2Sel = 2.9 V | ||
277 | */ | ||
278 | INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0f, 0x0d), | ||
279 | /* | ||
280 | * Vaux3Sel = 2.91 V | ||
281 | */ | ||
282 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07, 0x07), | ||
283 | /* | ||
284 | * VextSupply12LP = disabled (no LP) | ||
285 | */ | ||
286 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x01, 0x00), | ||
287 | /* | ||
288 | * Vaux1Disch = short discharge time | ||
289 | * Vaux2Disch = short discharge time | ||
290 | * Vaux3Disch = short discharge time | ||
291 | * Vintcore12Disch = short discharge time | ||
292 | * VTVoutDisch = short discharge time | ||
293 | * VaudioDisch = short discharge time | ||
294 | */ | ||
295 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0xfc, 0x00), | ||
296 | /* | ||
297 | * VanaDisch = short discharge time | ||
298 | * VdmicPullDownEna = pulldown disabled when Vdmic is disabled | ||
299 | * VdmicDisch = short discharge time | ||
300 | */ | ||
301 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x16, 0x00), | ||
302 | }; | ||
303 | |||
304 | /* AB8500 regulators */ | ||
305 | static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | ||
306 | /* supplies to the display/camera */ | ||
307 | [AB8500_LDO_AUX1] = { | ||
308 | .supply_regulator = "ab8500-ext-supply3", | ||
309 | .constraints = { | ||
310 | .name = "V-DISPLAY", | ||
311 | .min_uV = 2800000, | ||
312 | .max_uV = 3300000, | ||
313 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
314 | REGULATOR_CHANGE_STATUS, | ||
315 | .boot_on = 1, /* display is on at boot */ | ||
316 | }, | ||
317 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), | ||
318 | .consumer_supplies = ab8500_vaux1_consumers, | ||
319 | }, | ||
320 | /* supplies to the on-board eMMC */ | ||
321 | [AB8500_LDO_AUX2] = { | ||
322 | .supply_regulator = "ab8500-ext-supply3", | ||
323 | .constraints = { | ||
324 | .name = "V-eMMC1", | ||
325 | .min_uV = 1100000, | ||
326 | .max_uV = 3300000, | ||
327 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
328 | REGULATOR_CHANGE_STATUS | | ||
329 | REGULATOR_CHANGE_MODE, | ||
330 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
331 | REGULATOR_MODE_IDLE, | ||
332 | }, | ||
333 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), | ||
334 | .consumer_supplies = ab8500_vaux2_consumers, | ||
335 | }, | ||
336 | /* supply for VAUX3, supplies to SDcard slots */ | ||
337 | [AB8500_LDO_AUX3] = { | ||
338 | .supply_regulator = "ab8500-ext-supply3", | ||
339 | .constraints = { | ||
340 | .name = "V-MMC-SD", | ||
341 | .min_uV = 1100000, | ||
342 | .max_uV = 3300000, | ||
343 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
344 | REGULATOR_CHANGE_STATUS | | ||
345 | REGULATOR_CHANGE_MODE, | ||
346 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
347 | REGULATOR_MODE_IDLE, | ||
348 | }, | ||
349 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), | ||
350 | .consumer_supplies = ab8500_vaux3_consumers, | ||
351 | }, | ||
352 | /* supply for tvout, gpadc, TVOUT LDO */ | ||
353 | [AB8500_LDO_TVOUT] = { | ||
354 | .constraints = { | ||
355 | .name = "V-TVOUT", | ||
356 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
357 | }, | ||
358 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vtvout_consumers), | ||
359 | .consumer_supplies = ab8500_vtvout_consumers, | ||
360 | }, | ||
361 | /* supply for ab8500-vaudio, VAUDIO LDO */ | ||
362 | [AB8500_LDO_AUDIO] = { | ||
363 | .constraints = { | ||
364 | .name = "V-AUD", | ||
365 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
366 | }, | ||
367 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers), | ||
368 | .consumer_supplies = ab8500_vaud_consumers, | ||
369 | }, | ||
370 | /* supply for v-anamic1 VAMic1-LDO */ | ||
371 | [AB8500_LDO_ANAMIC1] = { | ||
372 | .constraints = { | ||
373 | .name = "V-AMIC1", | ||
374 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
375 | }, | ||
376 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers), | ||
377 | .consumer_supplies = ab8500_vamic1_consumers, | ||
378 | }, | ||
379 | /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ | ||
380 | [AB8500_LDO_ANAMIC2] = { | ||
381 | .constraints = { | ||
382 | .name = "V-AMIC2", | ||
383 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
384 | }, | ||
385 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers), | ||
386 | .consumer_supplies = ab8500_vamic2_consumers, | ||
387 | }, | ||
388 | /* supply for v-dmic, VDMIC LDO */ | ||
389 | [AB8500_LDO_DMIC] = { | ||
390 | .constraints = { | ||
391 | .name = "V-DMIC", | ||
392 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
393 | }, | ||
394 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vdmic_consumers), | ||
395 | .consumer_supplies = ab8500_vdmic_consumers, | ||
396 | }, | ||
397 | /* supply for v-intcore12, VINTCORE12 LDO */ | ||
398 | [AB8500_LDO_INTCORE] = { | ||
399 | .constraints = { | ||
400 | .name = "V-INTCORE", | ||
401 | .min_uV = 1250000, | ||
402 | .max_uV = 1350000, | ||
403 | .input_uV = 1800000, | ||
404 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
405 | REGULATOR_CHANGE_STATUS | | ||
406 | REGULATOR_CHANGE_MODE | | ||
407 | REGULATOR_CHANGE_DRMS, | ||
408 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
409 | REGULATOR_MODE_IDLE, | ||
410 | }, | ||
411 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), | ||
412 | .consumer_supplies = ab8500_vintcore_consumers, | ||
413 | }, | ||
414 | /* supply for U8500 CSI-DSI, VANA LDO */ | ||
415 | [AB8500_LDO_ANA] = { | ||
416 | .constraints = { | ||
417 | .name = "V-CSI-DSI", | ||
418 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
419 | }, | ||
420 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), | ||
421 | .consumer_supplies = ab8500_vana_consumers, | ||
422 | }, | ||
423 | }; | ||
424 | |||
425 | /* supply for VextSupply3 */ | ||
426 | static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = { | ||
427 | /* SIM supply for 3 V SIM cards */ | ||
428 | REGULATOR_SUPPLY("vinvsim", "sim-detect.0"), | ||
429 | }; | ||
430 | |||
431 | /* | ||
432 | * AB8500 external regulators | ||
433 | */ | ||
434 | static struct regulator_init_data ab8500_ext_regulators[] = { | ||
435 | /* fixed Vbat supplies VSMPS1_EXT_1V8 */ | ||
436 | [AB8500_EXT_SUPPLY1] = { | ||
437 | .constraints = { | ||
438 | .name = "ab8500-ext-supply1", | ||
439 | .min_uV = 1800000, | ||
440 | .max_uV = 1800000, | ||
441 | .initial_mode = REGULATOR_MODE_IDLE, | ||
442 | .boot_on = 1, | ||
443 | .always_on = 1, | ||
444 | }, | ||
445 | }, | ||
446 | /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */ | ||
447 | [AB8500_EXT_SUPPLY2] = { | ||
448 | .constraints = { | ||
449 | .name = "ab8500-ext-supply2", | ||
450 | .min_uV = 1360000, | ||
451 | .max_uV = 1360000, | ||
452 | }, | ||
453 | }, | ||
454 | /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */ | ||
455 | [AB8500_EXT_SUPPLY3] = { | ||
456 | .constraints = { | ||
457 | .name = "ab8500-ext-supply3", | ||
458 | .min_uV = 3400000, | ||
459 | .max_uV = 3400000, | ||
460 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
461 | .boot_on = 1, | ||
462 | }, | ||
463 | .num_consumer_supplies = | ||
464 | ARRAY_SIZE(ab8500_ext_supply3_consumers), | ||
465 | .consumer_supplies = ab8500_ext_supply3_consumers, | ||
466 | }, | ||
467 | }; | ||
468 | |||
469 | static struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { | ||
470 | .reg_init = ab8500_reg_init, | ||
471 | .num_reg_init = ARRAY_SIZE(ab8500_reg_init), | ||
472 | .regulator = ab8500_regulators, | ||
473 | .num_regulator = ARRAY_SIZE(ab8500_regulators), | ||
474 | .ext_regulator = ab8500_ext_regulators, | ||
475 | .num_ext_regulator = ARRAY_SIZE(ab8500_ext_regulators), | ||
476 | }; | ||
477 | |||
28 | /** | 478 | /** |
29 | * struct ab8500_ext_regulator_info - ab8500 regulator information | 479 | * struct ab8500_ext_regulator_info - ab8500 regulator information |
30 | * @dev: device pointer | 480 | * @dev: device pointer |
@@ -344,8 +794,7 @@ static struct of_regulator_match ab8500_ext_regulator_match[] = { | |||
344 | static int ab8500_ext_regulator_probe(struct platform_device *pdev) | 794 | static int ab8500_ext_regulator_probe(struct platform_device *pdev) |
345 | { | 795 | { |
346 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 796 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
347 | struct ab8500_platform_data *ppdata; | 797 | struct ab8500_regulator_platform_data *pdata = &ab8500_regulator_plat_data; |
348 | struct ab8500_regulator_platform_data *pdata; | ||
349 | struct device_node *np = pdev->dev.of_node; | 798 | struct device_node *np = pdev->dev.of_node; |
350 | struct regulator_config config = { }; | 799 | struct regulator_config config = { }; |
351 | int i, err; | 800 | int i, err; |
@@ -366,18 +815,6 @@ static int ab8500_ext_regulator_probe(struct platform_device *pdev) | |||
366 | return -EINVAL; | 815 | return -EINVAL; |
367 | } | 816 | } |
368 | 817 | ||
369 | ppdata = dev_get_platdata(ab8500->dev); | ||
370 | if (!ppdata) { | ||
371 | dev_err(&pdev->dev, "null parent pdata\n"); | ||
372 | return -EINVAL; | ||
373 | } | ||
374 | |||
375 | pdata = ppdata->regulator; | ||
376 | if (!pdata) { | ||
377 | dev_err(&pdev->dev, "null pdata\n"); | ||
378 | return -EINVAL; | ||
379 | } | ||
380 | |||
381 | /* make sure the platform data has the correct size */ | 818 | /* make sure the platform data has the correct size */ |
382 | if (pdata->num_ext_regulator != ARRAY_SIZE(ab8500_ext_regulator_info)) { | 819 | if (pdata->num_ext_regulator != ARRAY_SIZE(ab8500_ext_regulator_info)) { |
383 | dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); | 820 | dev_err(&pdev->dev, "Configuration error: size mismatch.\n"); |
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 91d5c05d395f..fe42a2fdf351 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig | |||
@@ -9,6 +9,7 @@ source "drivers/soc/samsung/Kconfig" | |||
9 | source "drivers/soc/sunxi/Kconfig" | 9 | source "drivers/soc/sunxi/Kconfig" |
10 | source "drivers/soc/tegra/Kconfig" | 10 | source "drivers/soc/tegra/Kconfig" |
11 | source "drivers/soc/ti/Kconfig" | 11 | source "drivers/soc/ti/Kconfig" |
12 | source "drivers/soc/ux500/Kconfig" | ||
12 | source "drivers/soc/versatile/Kconfig" | 13 | source "drivers/soc/versatile/Kconfig" |
13 | 14 | ||
14 | endmenu | 15 | endmenu |
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index b75e3bd0a01e..50c23d0bd457 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile | |||
@@ -14,4 +14,5 @@ obj-$(CONFIG_SOC_SAMSUNG) += samsung/ | |||
14 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ | 14 | obj-$(CONFIG_ARCH_SUNXI) += sunxi/ |
15 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | 15 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ |
16 | obj-$(CONFIG_SOC_TI) += ti/ | 16 | obj-$(CONFIG_SOC_TI) += ti/ |
17 | obj-$(CONFIG_ARCH_U8500) += ux500/ | ||
17 | obj-$(CONFIG_PLAT_VERSATILE) += versatile/ | 18 | obj-$(CONFIG_PLAT_VERSATILE) += versatile/ |
diff --git a/drivers/soc/ux500/Kconfig b/drivers/soc/ux500/Kconfig new file mode 100644 index 000000000000..025a44aef5db --- /dev/null +++ b/drivers/soc/ux500/Kconfig | |||
@@ -0,0 +1,7 @@ | |||
1 | config UX500_SOC_ID | ||
2 | bool "SoC bus for ST-Ericsson ux500" | ||
3 | depends on ARCH_U8500 || COMPILE_TEST | ||
4 | default ARCH_U8500 | ||
5 | help | ||
6 | Include support for the SoC bus on the ARM RealView platforms | ||
7 | providing some sysfs information about the ASIC variant. | ||
diff --git a/drivers/soc/ux500/Makefile b/drivers/soc/ux500/Makefile new file mode 100644 index 000000000000..0b87ad04b018 --- /dev/null +++ b/drivers/soc/ux500/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_UX500_SOC_ID) += ux500-soc-id.o | |||
diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c new file mode 100644 index 000000000000..6c1be74e5fcc --- /dev/null +++ b/drivers/soc/ux500/ux500-soc-id.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/io.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/random.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/sys_soc.h> | ||
17 | |||
18 | #include <asm/cputype.h> | ||
19 | #include <asm/tlbflush.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | #include <asm/mach/map.h> | ||
22 | |||
23 | /** | ||
24 | * struct dbx500_asic_id - fields of the ASIC ID | ||
25 | * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard" | ||
26 | * @partnumber: hithereto 0x8500 for DB8500 | ||
27 | * @revision: version code in the series | ||
28 | */ | ||
29 | struct dbx500_asic_id { | ||
30 | u16 partnumber; | ||
31 | u8 revision; | ||
32 | u8 process; | ||
33 | }; | ||
34 | |||
35 | static struct dbx500_asic_id dbx500_id; | ||
36 | |||
37 | static unsigned int __init ux500_read_asicid(phys_addr_t addr) | ||
38 | { | ||
39 | void __iomem *virt = ioremap(addr, 4); | ||
40 | unsigned int asicid; | ||
41 | |||
42 | if (!virt) | ||
43 | return 0; | ||
44 | |||
45 | asicid = readl(virt); | ||
46 | iounmap(virt); | ||
47 | |||
48 | return asicid; | ||
49 | } | ||
50 | |||
51 | static void ux500_print_soc_info(unsigned int asicid) | ||
52 | { | ||
53 | unsigned int rev = dbx500_id.revision; | ||
54 | |||
55 | pr_info("DB%4x ", dbx500_id.partnumber); | ||
56 | |||
57 | if (rev == 0x01) | ||
58 | pr_cont("Early Drop"); | ||
59 | else if (rev >= 0xA0) | ||
60 | pr_cont("v%d.%d" , (rev >> 4) - 0xA + 1, rev & 0xf); | ||
61 | else | ||
62 | pr_cont("Unknown"); | ||
63 | |||
64 | pr_cont(" [%#010x]\n", asicid); | ||
65 | } | ||
66 | |||
67 | static unsigned int partnumber(unsigned int asicid) | ||
68 | { | ||
69 | return (asicid >> 8) & 0xffff; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * SOC MIDR ASICID ADDRESS ASICID VALUE | ||
74 | * DB8500ed 0x410fc090 0x9001FFF4 0x00850001 | ||
75 | * DB8500v1 0x411fc091 0x9001FFF4 0x008500A0 | ||
76 | * DB8500v1.1 0x411fc091 0x9001FFF4 0x008500A1 | ||
77 | * DB8500v2 0x412fc091 0x9001DBF4 0x008500B0 | ||
78 | * DB8520v2.2 0x412fc091 0x9001DBF4 0x008500B2 | ||
79 | * DB5500v1 0x412fc091 0x9001FFF4 0x005500A0 | ||
80 | * DB9540 0x413fc090 0xFFFFDBF4 0x009540xx | ||
81 | */ | ||
82 | |||
83 | static void __init ux500_setup_id(void) | ||
84 | { | ||
85 | unsigned int cpuid = read_cpuid_id(); | ||
86 | unsigned int asicid = 0; | ||
87 | phys_addr_t addr = 0; | ||
88 | |||
89 | switch (cpuid) { | ||
90 | case 0x410fc090: /* DB8500ed */ | ||
91 | case 0x411fc091: /* DB8500v1 */ | ||
92 | addr = 0x9001FFF4; | ||
93 | break; | ||
94 | |||
95 | case 0x412fc091: /* DB8520 / DB8500v2 / DB5500v1 */ | ||
96 | asicid = ux500_read_asicid(0x9001DBF4); | ||
97 | if (partnumber(asicid) == 0x8500 || | ||
98 | partnumber(asicid) == 0x8520) | ||
99 | /* DB8500v2 */ | ||
100 | break; | ||
101 | |||
102 | /* DB5500v1 */ | ||
103 | addr = 0x9001FFF4; | ||
104 | break; | ||
105 | |||
106 | case 0x413fc090: /* DB9540 */ | ||
107 | addr = 0xFFFFDBF4; | ||
108 | break; | ||
109 | } | ||
110 | |||
111 | if (addr) | ||
112 | asicid = ux500_read_asicid(addr); | ||
113 | |||
114 | if (!asicid) { | ||
115 | pr_err("Unable to identify SoC\n"); | ||
116 | BUG(); | ||
117 | } | ||
118 | |||
119 | dbx500_id.process = asicid >> 24; | ||
120 | dbx500_id.partnumber = partnumber(asicid); | ||
121 | dbx500_id.revision = asicid & 0xff; | ||
122 | |||
123 | ux500_print_soc_info(asicid); | ||
124 | } | ||
125 | |||
126 | static const char * __init ux500_get_machine(void) | ||
127 | { | ||
128 | return kasprintf(GFP_KERNEL, "DB%4x", dbx500_id.partnumber); | ||
129 | } | ||
130 | |||
131 | static const char * __init ux500_get_family(void) | ||
132 | { | ||
133 | return kasprintf(GFP_KERNEL, "ux500"); | ||
134 | } | ||
135 | |||
136 | static const char * __init ux500_get_revision(void) | ||
137 | { | ||
138 | unsigned int rev = dbx500_id.revision; | ||
139 | |||
140 | if (rev == 0x01) | ||
141 | return kasprintf(GFP_KERNEL, "%s", "ED"); | ||
142 | else if (rev >= 0xA0) | ||
143 | return kasprintf(GFP_KERNEL, "%d.%d", | ||
144 | (rev >> 4) - 0xA + 1, rev & 0xf); | ||
145 | |||
146 | return kasprintf(GFP_KERNEL, "%s", "Unknown"); | ||
147 | } | ||
148 | |||
149 | static ssize_t ux500_get_process(struct device *dev, | ||
150 | struct device_attribute *attr, | ||
151 | char *buf) | ||
152 | { | ||
153 | if (dbx500_id.process == 0x00) | ||
154 | return sprintf(buf, "Standard\n"); | ||
155 | |||
156 | return sprintf(buf, "%02xnm\n", dbx500_id.process); | ||
157 | } | ||
158 | |||
159 | static const char *db8500_read_soc_id(struct device_node *backupram) | ||
160 | { | ||
161 | void __iomem *base; | ||
162 | void __iomem *uid; | ||
163 | const char *retstr; | ||
164 | |||
165 | base = of_iomap(backupram, 0); | ||
166 | if (!base) | ||
167 | return NULL; | ||
168 | uid = base + 0x1fc0; | ||
169 | |||
170 | /* Throw these device-specific numbers into the entropy pool */ | ||
171 | add_device_randomness(uid, 0x14); | ||
172 | retstr = kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", | ||
173 | readl((u32 *)uid+0), | ||
174 | readl((u32 *)uid+1), readl((u32 *)uid+2), | ||
175 | readl((u32 *)uid+3), readl((u32 *)uid+4)); | ||
176 | iounmap(base); | ||
177 | return retstr; | ||
178 | } | ||
179 | |||
180 | static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, | ||
181 | struct device_node *backupram) | ||
182 | { | ||
183 | soc_dev_attr->soc_id = db8500_read_soc_id(backupram); | ||
184 | soc_dev_attr->machine = ux500_get_machine(); | ||
185 | soc_dev_attr->family = ux500_get_family(); | ||
186 | soc_dev_attr->revision = ux500_get_revision(); | ||
187 | } | ||
188 | |||
189 | static const struct device_attribute ux500_soc_attr = | ||
190 | __ATTR(process, S_IRUGO, ux500_get_process, NULL); | ||
191 | |||
192 | static int __init ux500_soc_device_init(void) | ||
193 | { | ||
194 | struct device *parent; | ||
195 | struct soc_device *soc_dev; | ||
196 | struct soc_device_attribute *soc_dev_attr; | ||
197 | struct device_node *backupram; | ||
198 | |||
199 | backupram = of_find_compatible_node(NULL, NULL, "ste,dbx500-backupram"); | ||
200 | if (!backupram) | ||
201 | return 0; | ||
202 | |||
203 | ux500_setup_id(); | ||
204 | |||
205 | soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); | ||
206 | if (!soc_dev_attr) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | soc_info_populate(soc_dev_attr, backupram); | ||
210 | |||
211 | soc_dev = soc_device_register(soc_dev_attr); | ||
212 | if (IS_ERR(soc_dev)) { | ||
213 | kfree(soc_dev_attr); | ||
214 | return PTR_ERR(soc_dev); | ||
215 | } | ||
216 | |||
217 | parent = soc_device_to_device(soc_dev); | ||
218 | device_create_file(parent, &ux500_soc_attr); | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | subsys_initcall(ux500_soc_device_init); | ||