aboutsummaryrefslogtreecommitdiff
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.c103
1 files changed, 77 insertions, 26 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 217bcc2e8f8..f2c0988a03b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
+#include <linux/phy_fixed.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h>
@@ -54,10 +55,18 @@ phys_addr_t get_immrbase(void)
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);
}
@@ -130,6 +139,37 @@ u32 get_baudrate(void)
EXPORT_SYMBOL(get_baudrate);
#endif /* CONFIG_CPM2 */
+#ifdef CONFIG_FIXED_PHY
+static int __init of_add_fixed_phys(void)
+{
+ int ret;
+ struct device_node *np;
+ u32 *fixed_link;
+ struct fixed_phy_status status = {};
+
+ for_each_node_by_name(np, "ethernet") {
+ fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
+ if (!fixed_link)
+ continue;
+
+ status.link = 1;
+ status.duplex = fixed_link[1];
+ status.speed = fixed_link[2];
+ status.pause = fixed_link[3];
+ status.asym_pause = fixed_link[4];
+
+ ret = fixed_phy_add(PHY_POLL, fixed_link[0], &status);
+ if (ret) {
+ of_node_put(np);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+arch_initcall(of_add_fixed_phys);
+#endif /* CONFIG_FIXED_PHY */
+
static int __init gfar_mdio_of_init(void)
{
struct device_node *np = NULL;
@@ -198,7 +238,6 @@ static const char *gfar_tx_intr = "tx";
static const char *gfar_rx_intr = "rx";
static const char *gfar_err_intr = "error";
-
static int __init gfar_of_init(void)
{
struct device_node *np;
@@ -282,29 +321,43 @@ static int __init gfar_of_init(void)
gfar_data.interface = PHY_INTERFACE_MODE_MII;
ph = of_get_property(np, "phy-handle", NULL);
- phy = of_find_node_by_phandle(*ph);
+ if (ph == NULL) {
+ u32 *fixed_link;
- if (phy == NULL) {
- ret = -ENODEV;
- goto unreg;
- }
+ fixed_link = (u32 *)of_get_property(np, "fixed-link",
+ NULL);
+ if (!fixed_link) {
+ ret = -ENODEV;
+ goto unreg;
+ }
- mdio = of_get_parent(phy);
+ gfar_data.bus_id = 0;
+ gfar_data.phy_id = fixed_link[0];
+ } else {
+ phy = of_find_node_by_phandle(*ph);
+
+ if (phy == NULL) {
+ ret = -ENODEV;
+ goto unreg;
+ }
+
+ mdio = of_get_parent(phy);
+
+ id = of_get_property(phy, "reg", NULL);
+ ret = of_address_to_resource(mdio, 0, &res);
+ if (ret) {
+ of_node_put(phy);
+ of_node_put(mdio);
+ goto unreg;
+ }
+
+ gfar_data.phy_id = *id;
+ gfar_data.bus_id = res.start;
- id = of_get_property(phy, "reg", NULL);
- ret = of_address_to_resource(mdio, 0, &res);
- if (ret) {
of_node_put(phy);
of_node_put(mdio);
- goto unreg;
}
- gfar_data.phy_id = *id;
- gfar_data.bus_id = res.start;
-
- of_node_put(phy);
- of_node_put(mdio);
-
ret =
platform_device_add_data(gfar_dev, &gfar_data,
sizeof(struct
@@ -531,14 +584,12 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)
static int __init fsl_usb_of_init(void)
{
struct device_node *np;
- unsigned int i;
+ unsigned int i = 0;
struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL,
*usb_dev_dr_client = NULL;
int ret;
- for (np = NULL, i = 0;
- (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
- i++) {
+ for_each_compatible_node(np, NULL, "fsl-usb2-mph") {
struct resource r[2];
struct fsl_usb2_platform_data usb_data;
const unsigned char *prop = NULL;
@@ -581,11 +632,10 @@ static int __init fsl_usb_of_init(void)
fsl_usb2_platform_data));
if (ret)
goto unreg_mph;
+ i++;
}
- for (np = NULL;
- (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
- i++) {
+ for_each_compatible_node(np, NULL, "fsl-usb2-dr") {
struct resource r[2];
struct fsl_usb2_platform_data usb_data;
const unsigned char *prop = NULL;
@@ -657,6 +707,7 @@ static int __init fsl_usb_of_init(void)
fsl_usb2_platform_data))))
goto unreg_dr;
}
+ i++;
}
return 0;