aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/fsl_soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/fsl_soc.c')
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c187
1 files changed, 170 insertions, 17 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 1cf29c9d4408..3ace7474809e 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/of_platform.h> 25#include <linux/of_platform.h>
26#include <linux/phy.h> 26#include <linux/phy.h>
27#include <linux/spi/spi.h>
27#include <linux/fsl_devices.h> 28#include <linux/fsl_devices.h>
28#include <linux/fs_enet_pd.h> 29#include <linux/fs_enet_pd.h>
29#include <linux/fs_uart_pd.h> 30#include <linux/fs_uart_pd.h>
@@ -52,13 +53,13 @@ phys_addr_t get_immrbase(void)
52 53
53 soc = of_find_node_by_type(NULL, "soc"); 54 soc = of_find_node_by_type(NULL, "soc");
54 if (soc) { 55 if (soc) {
55 unsigned int size; 56 int size;
56 const void *prop = of_get_property(soc, "reg", &size); 57 const void *prop = of_get_property(soc, "reg", &size);
57 58
58 if (prop) 59 if (prop)
59 immrbase = of_translate_address(soc, prop); 60 immrbase = of_translate_address(soc, prop);
60 of_node_put(soc); 61 of_node_put(soc);
61 }; 62 }
62 63
63 return immrbase; 64 return immrbase;
64} 65}
@@ -72,20 +73,31 @@ static u32 brgfreq = -1;
72u32 get_brgfreq(void) 73u32 get_brgfreq(void)
73{ 74{
74 struct device_node *node; 75 struct device_node *node;
76 const unsigned int *prop;
77 int size;
75 78
76 if (brgfreq != -1) 79 if (brgfreq != -1)
77 return brgfreq; 80 return brgfreq;
78 81
79 node = of_find_node_by_type(NULL, "cpm"); 82 node = of_find_compatible_node(NULL, NULL, "fsl,cpm-brg");
80 if (node) { 83 if (node) {
81 unsigned int size; 84 prop = of_get_property(node, "clock-frequency", &size);
82 const unsigned int *prop = of_get_property(node, 85 if (prop && size == 4)
83 "brg-frequency", &size); 86 brgfreq = *prop;
84 87
85 if (prop) 88 of_node_put(node);
89 return brgfreq;
90 }
91
92 /* Legacy device binding -- will go away when no users are left. */
93 node = of_find_node_by_type(NULL, "cpm");
94 if (node) {
95 prop = of_get_property(node, "brg-frequency", &size);
96 if (prop && size == 4)
86 brgfreq = *prop; 97 brgfreq = *prop;
98
87 of_node_put(node); 99 of_node_put(node);
88 }; 100 }
89 101
90 return brgfreq; 102 return brgfreq;
91} 103}
@@ -103,14 +115,14 @@ u32 get_baudrate(void)
103 115
104 node = of_find_node_by_type(NULL, "serial"); 116 node = of_find_node_by_type(NULL, "serial");
105 if (node) { 117 if (node) {
106 unsigned int size; 118 int size;
107 const unsigned int *prop = of_get_property(node, 119 const unsigned int *prop = of_get_property(node,
108 "current-speed", &size); 120 "current-speed", &size);
109 121
110 if (prop) 122 if (prop)
111 fs_baudrate = *prop; 123 fs_baudrate = *prop;
112 of_node_put(node); 124 of_node_put(node);
113 }; 125 }
114 126
115 return fs_baudrate; 127 return fs_baudrate;
116} 128}
@@ -319,34 +331,46 @@ static struct i2c_driver_device i2c_devices[] __initdata = {
319 {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",}, 331 {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",},
320 {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",}, 332 {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",},
321 {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",}, 333 {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",},
334 {"dallas,ds1307", "rtc-ds1307", "ds1307",},
335 {"dallas,ds1337", "rtc-ds1307", "ds1337",},
336 {"dallas,ds1338", "rtc-ds1307", "ds1338",},
337 {"dallas,ds1339", "rtc-ds1307", "ds1339",},
338 {"dallas,ds1340", "rtc-ds1307", "ds1340",},
339 {"stm,m41t00", "rtc-ds1307", "m41t00"},
340 {"dallas,ds1374", "rtc-ds1374", "rtc-ds1374",},
322}; 341};
323 342
324static int __init of_find_i2c_driver(struct device_node *node, struct i2c_board_info *info) 343static int __init of_find_i2c_driver(struct device_node *node,
344 struct i2c_board_info *info)
325{ 345{
326 int i; 346 int i;
327 347
328 for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { 348 for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) {
329 if (!of_device_is_compatible(node, i2c_devices[i].of_device)) 349 if (!of_device_is_compatible(node, i2c_devices[i].of_device))
330 continue; 350 continue;
331 strncpy(info->driver_name, i2c_devices[i].i2c_driver, KOBJ_NAME_LEN); 351 if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver,
332 strncpy(info->type, i2c_devices[i].i2c_type, I2C_NAME_SIZE); 352 KOBJ_NAME_LEN) >= KOBJ_NAME_LEN ||
353 strlcpy(info->type, i2c_devices[i].i2c_type,
354 I2C_NAME_SIZE) >= I2C_NAME_SIZE)
355 return -ENOMEM;
333 return 0; 356 return 0;
334 } 357 }
335 return -ENODEV; 358 return -ENODEV;
336} 359}
337 360
338static void __init of_register_i2c_devices(struct device_node *adap_node, int bus_num) 361static void __init of_register_i2c_devices(struct device_node *adap_node,
362 int bus_num)
339{ 363{
340 struct device_node *node = NULL; 364 struct device_node *node = NULL;
341 365
342 while ((node = of_get_next_child(adap_node, node))) { 366 while ((node = of_get_next_child(adap_node, node))) {
343 struct i2c_board_info info; 367 struct i2c_board_info info = {};
344 const u32 *addr; 368 const u32 *addr;
345 int len; 369 int len;
346 370
347 addr = of_get_property(node, "reg", &len); 371 addr = of_get_property(node, "reg", &len);
348 if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { 372 if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
349 printk(KERN_WARNING "fsl_ioc.c: invalid i2c device entry\n"); 373 printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n");
350 continue; 374 continue;
351 } 375 }
352 376
@@ -357,7 +381,6 @@ static void __init of_register_i2c_devices(struct device_node *adap_node, int bu
357 if (of_find_i2c_driver(node, &info) < 0) 381 if (of_find_i2c_driver(node, &info) < 0)
358 continue; 382 continue;
359 383
360 info.platform_data = NULL;
361 info.addr = *addr; 384 info.addr = *addr;
362 385
363 i2c_register_board_info(bus_num, &info, 1); 386 i2c_register_board_info(bus_num, &info, 1);
@@ -648,6 +671,7 @@ err:
648 671
649arch_initcall(fsl_usb_of_init); 672arch_initcall(fsl_usb_of_init);
650 673
674#ifndef CONFIG_PPC_CPM_NEW_BINDING
651#ifdef CONFIG_CPM2 675#ifdef CONFIG_CPM2
652 676
653extern void init_scc_ioports(struct fs_uart_platform_info*); 677extern void init_scc_ioports(struct fs_uart_platform_info*);
@@ -1187,3 +1211,132 @@ err:
1187arch_initcall(cpm_smc_uart_of_init); 1211arch_initcall(cpm_smc_uart_of_init);
1188 1212
1189#endif /* CONFIG_8xx */ 1213#endif /* CONFIG_8xx */
1214#endif /* CONFIG_PPC_CPM_NEW_BINDING */
1215
1216int __init fsl_spi_init(struct spi_board_info *board_infos,
1217 unsigned int num_board_infos,
1218 void (*activate_cs)(u8 cs, u8 polarity),
1219 void (*deactivate_cs)(u8 cs, u8 polarity))
1220{
1221 struct device_node *np;
1222 unsigned int i;
1223 const u32 *sysclk;
1224
1225 /* SPI controller is either clocked from QE or SoC clock */
1226 np = of_find_node_by_type(NULL, "qe");
1227 if (!np)
1228 np = of_find_node_by_type(NULL, "soc");
1229
1230 if (!np)
1231 return -ENODEV;
1232
1233 sysclk = of_get_property(np, "bus-frequency", NULL);
1234 if (!sysclk)
1235 return -ENODEV;
1236
1237 for (np = NULL, i = 1;
1238 (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
1239 i++) {
1240 int ret = 0;
1241 unsigned int j;
1242 const void *prop;
1243 struct resource res[2];
1244 struct platform_device *pdev;
1245 struct fsl_spi_platform_data pdata = {
1246 .activate_cs = activate_cs,
1247 .deactivate_cs = deactivate_cs,
1248 };
1249
1250 memset(res, 0, sizeof(res));
1251
1252 pdata.sysclk = *sysclk;
1253
1254 prop = of_get_property(np, "reg", NULL);
1255 if (!prop)
1256 goto err;
1257 pdata.bus_num = *(u32 *)prop;
1258
1259 prop = of_get_property(np, "mode", NULL);
1260 if (prop && !strcmp(prop, "cpu-qe"))
1261 pdata.qe_mode = 1;
1262
1263 for (j = 0; j < num_board_infos; j++) {
1264 if (board_infos[j].bus_num == pdata.bus_num)
1265 pdata.max_chipselect++;
1266 }
1267
1268 if (!pdata.max_chipselect)
1269 goto err;
1270
1271 ret = of_address_to_resource(np, 0, &res[0]);
1272 if (ret)
1273 goto err;
1274
1275 ret = of_irq_to_resource(np, 0, &res[1]);
1276 if (ret == NO_IRQ)
1277 goto err;
1278
1279 pdev = platform_device_alloc("mpc83xx_spi", i);
1280 if (!pdev)
1281 goto err;
1282
1283 ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
1284 if (ret)
1285 goto unreg;
1286
1287 ret = platform_device_add_resources(pdev, res,
1288 ARRAY_SIZE(res));
1289 if (ret)
1290 goto unreg;
1291
1292 ret = platform_device_register(pdev);
1293 if (ret)
1294 goto unreg;
1295
1296 continue;
1297unreg:
1298 platform_device_del(pdev);
1299err:
1300 continue;
1301 }
1302
1303 return spi_register_board_info(board_infos, num_board_infos);
1304}
1305
1306#if defined(CONFIG_PPC_85xx) || defined(CONFIG_PPC_86xx)
1307static __be32 __iomem *rstcr;
1308
1309static int __init setup_rstcr(void)
1310{
1311 struct device_node *np;
1312 np = of_find_node_by_name(NULL, "global-utilities");
1313 if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
1314 const u32 *prop = of_get_property(np, "reg", NULL);
1315 if (prop) {
1316 /* map reset control register
1317 * 0xE00B0 is offset of reset control register
1318 */
1319 rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
1320 if (!rstcr)
1321 printk (KERN_EMERG "Error: reset control "
1322 "register not mapped!\n");
1323 }
1324 } else
1325 printk (KERN_INFO "rstcr compatible register does not exist!\n");
1326 if (np)
1327 of_node_put(np);
1328 return 0;
1329}
1330
1331arch_initcall(setup_rstcr);
1332
1333void fsl_rstcr_restart(char *cmd)
1334{
1335 local_irq_disable();
1336 if (rstcr)
1337 /* set reset control register */
1338 out_be32(rstcr, 0x2); /* HRESET_REQ */
1339
1340 while (1) ;
1341}
1342#endif