soc = of_find_node_by_type(NULL, "soc");
if (soc) {
int size;
- const void *prop = of_get_property(soc, "reg", &size);
+ u32 naddr;
+ const u32 *prop = of_get_property(soc, "#address-cells", &size);
+ if (prop && size == 4)
+ naddr = *prop;
+ else
+ naddr = 2;
+
+ prop = of_get_property(soc, "ranges", &size);
if (prop)
- immrbase = of_translate_address(soc, prop);
+ immrbase = of_translate_address(soc, prop + naddr);
+
of_node_put(soc);
}
EXPORT_SYMBOL(get_immrbase);
-#if defined(CONFIG_CPM2) || defined(CONFIG_8xx)
+#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
static u32 brgfreq = -1;
/* Legacy device binding -- will go away when no users are left. */
node = of_find_node_by_type(NULL, "cpm");
+ if (!node)
+ node = of_find_compatible_node(NULL, NULL, "fsl,qe");
+ if (!node)
+ node = of_find_node_by_type(NULL, "qe");
+
if (node) {
prop = of_get_property(node, "brg-frequency", &size);
if (prop && size == 4)
brgfreq = *prop;
+ if (brgfreq == -1 || brgfreq == 0) {
+ prop = of_get_property(node, "bus-frequency", &size);
+ if (prop && size == 4)
+ brgfreq = *prop / 2;
+ }
of_node_put(node);
}
#endif /* CONFIG_8xx */
#endif /* CONFIG_PPC_CPM_NEW_BINDING */
-int __init fsl_spi_init(struct spi_board_info *board_infos,
- unsigned int num_board_infos,
- void (*activate_cs)(u8 cs, u8 polarity),
- void (*deactivate_cs)(u8 cs, u8 polarity))
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+ struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity))
{
struct device_node *np;
- unsigned int i;
- const u32 *sysclk;
-
- /* SPI controller is either clocked from QE or SoC clock */
- np = of_find_node_by_type(NULL, "qe");
- if (!np)
- np = of_find_node_by_type(NULL, "soc");
-
- if (!np)
- return -ENODEV;
-
- sysclk = of_get_property(np, "bus-frequency", NULL);
- if (!sysclk)
- return -ENODEV;
+ unsigned int i = 0;
- for (np = NULL, i = 1;
- (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
- i++) {
- int ret = 0;
+ for_each_compatible_node(np, type, compatible) {
+ int ret;
unsigned int j;
const void *prop;
struct resource res[2];
memset(res, 0, sizeof(res));
- pdata.sysclk = *sysclk;
+ pdata.sysclk = sysclk;
prop = of_get_property(np, "reg", NULL);
if (!prop)
goto err;
pdata.bus_num = *(u32 *)prop;
+ prop = of_get_property(np, "cell-index", NULL);
+ if (prop)
+ i = *(u32 *)prop;
+
prop = of_get_property(np, "mode", NULL);
if (prop && !strcmp(prop, "cpu-qe"))
pdata.qe_mode = 1;
}
if (!pdata.max_chipselect)
- goto err;
+ continue;
ret = of_address_to_resource(np, 0, &res[0]);
if (ret)
if (ret)
goto unreg;
- ret = platform_device_register(pdev);
+ ret = platform_device_add(pdev);
if (ret)
goto unreg;
- continue;
+ goto next;
unreg:
platform_device_del(pdev);
err:
- continue;
+ pr_err("%s: registration failed\n", np->full_name);
+next:
+ i++;
}
+ return i;
+}
+
+int __init fsl_spi_init(struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity))
+{
+ u32 sysclk = -1;
+ int ret;
+
+#ifdef CONFIG_QUICC_ENGINE
+ /* SPI controller is either clocked from QE or SoC clock */
+ sysclk = get_brgfreq();
+#endif
+ if (sysclk == -1) {
+ struct device_node *np;
+ const u32 *freq;
+ int size;
+
+ np = of_find_node_by_type(NULL, "soc");
+ if (!np)
+ return -ENODEV;
+
+ freq = of_get_property(np, "clock-frequency", &size);
+ if (!freq || size != sizeof(*freq) || *freq == 0) {
+ freq = of_get_property(np, "bus-frequency", &size);
+ if (!freq || size != sizeof(*freq) || *freq == 0) {
+ of_node_put(np);
+ return -ENODEV;
+ }
+ }
+
+ sysclk = *freq;
+ of_node_put(np);
+ }
+
+ ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+ num_board_infos, activate_cs, deactivate_cs);
+ if (!ret)
+ of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+ num_board_infos, activate_cs, deactivate_cs);
+
return spi_register_board_info(board_infos, num_board_infos);
}