summaryrefslogtreecommitdiff
path: root/drivers/phy/broadcom/phy-brcm-usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/broadcom/phy-brcm-usb.c')
-rw-r--r--drivers/phy/broadcom/phy-brcm-usb.c70
1 files changed, 53 insertions, 17 deletions
diff --git a/drivers/phy/broadcom/phy-brcm-usb.c b/drivers/phy/broadcom/phy-brcm-usb.c
index 9d93c5599511..64379ede480e 100644
--- a/drivers/phy/broadcom/phy-brcm-usb.c
+++ b/drivers/phy/broadcom/phy-brcm-usb.c
@@ -241,6 +241,15 @@ static const struct attribute_group brcm_usb_phy_group = {
.attrs = brcm_usb_phy_attrs,
};
+static const struct of_device_id brcm_usb_dt_ids[] = {
+ {
+ .compatible = "brcm,bcm7216-usb-phy",
+ .data = &brcm_usb_dvr_init_7216,
+ },
+ { .compatible = "brcm,brcmstb-usb-phy" },
+ { /* sentinel */ }
+};
+
static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
struct brcm_usb_phy_data *priv,
struct device_node *dn)
@@ -316,13 +325,16 @@ static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
static int brcm_usb_phy_probe(struct platform_device *pdev)
{
- struct resource *res;
+ struct resource *res_ctrl;
+ struct resource *res_xhciec = NULL;
+ struct resource *res_xhcigbl = NULL;
struct device *dev = &pdev->dev;
struct brcm_usb_phy_data *priv;
struct phy_provider *phy_provider;
struct device_node *dn = pdev->dev.of_node;
int err;
const char *mode;
+ const struct of_device_id *match;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -331,30 +343,59 @@ static int brcm_usb_phy_probe(struct platform_device *pdev)
priv->ini.family_id = brcmstb_get_family_id();
priv->ini.product_id = brcmstb_get_product_id();
- brcm_usb_dvr_init_7445(&priv->ini);
+
+ match = of_match_node(brcm_usb_dt_ids, dev->of_node);
+ if (match && match->data) {
+ void (*dvr_init)(struct brcm_usb_init_params *params);
+
+ dvr_init = match->data;
+ (*dvr_init)(&priv->ini);
+ } else {
+ brcm_usb_dvr_init_7445(&priv->ini);
+ }
+
dev_dbg(dev, "Best mapping table is for %s\n",
priv->ini.family_name);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(dev, "can't get USB_CTRL base address\n");
- return -EINVAL;
+
+ /* Newer DT node has reg-names. xhci_ec and xhci_gbl are optional. */
+ res_ctrl = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
+ if (res_ctrl != NULL) {
+ res_xhciec = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM,
+ "xhci_ec");
+ res_xhcigbl = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM,
+ "xhci_gbl");
+ } else {
+ /* Older DT node without reg-names, use index */
+ res_ctrl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res_ctrl == NULL) {
+ dev_err(dev, "can't get CTRL base address\n");
+ return -EINVAL;
+ }
+ res_xhciec = platform_get_resource(pdev, IORESOURCE_MEM, 1);
}
- priv->ini.ctrl_regs = devm_ioremap_resource(dev, res);
+ priv->ini.ctrl_regs = devm_ioremap_resource(dev, res_ctrl);
if (IS_ERR(priv->ini.ctrl_regs)) {
dev_err(dev, "can't map CTRL register space\n");
return -EINVAL;
}
-
- /* The XHCI EC registers are optional */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- if (res) {
+ if (res_xhciec) {
priv->ini.xhci_ec_regs =
- devm_ioremap_resource(dev, res);
+ devm_ioremap_resource(dev, res_xhciec);
if (IS_ERR(priv->ini.xhci_ec_regs)) {
dev_err(dev, "can't map XHCI EC register space\n");
return -EINVAL;
}
}
+ if (res_xhcigbl) {
+ priv->ini.xhci_gbl_regs =
+ devm_ioremap_resource(dev, res_xhcigbl);
+ if (IS_ERR(priv->ini.xhci_gbl_regs)) {
+ dev_err(dev, "can't map XHCI Global register space\n");
+ return -EINVAL;
+ }
+ }
of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp);
of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc);
@@ -480,11 +521,6 @@ static const struct dev_pm_ops brcm_usb_phy_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(brcm_usb_phy_suspend, brcm_usb_phy_resume)
};
-static const struct of_device_id brcm_usb_dt_ids[] = {
- { .compatible = "brcm,brcmstb-usb-phy" },
- { /* sentinel */ }
-};
-
MODULE_DEVICE_TABLE(of, brcm_usb_dt_ids);
static struct platform_driver brcm_usb_driver = {