Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * phy-brcm-usb.c - Broadcom USB Phy Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2015-2017 Broadcom
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/soc/brcmstb/brcmstb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <dt-bindings/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "phy-brcm-usb-init.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static DEFINE_MUTEX(sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) enum brcm_usb_phy_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	BRCM_USB_PHY_2_0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	BRCM_USB_PHY_3_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	BRCM_USB_PHY_ID_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct value_to_name_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) struct match_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	void *init_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	u8 required_regs[BRCM_REGS_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	u8 optional_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) static const struct value_to_name_map brcm_dr_mode_to_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	{ USB_CTLR_MODE_HOST, "host" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	{ USB_CTLR_MODE_DEVICE, "peripheral" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	{ USB_CTLR_MODE_DRD, "drd" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	{ USB_CTLR_MODE_TYPEC_PD, "typec-pd" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static const struct value_to_name_map brcm_dual_mode_to_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	{ 0, "host" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	{ 1, "device" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	{ 2, "auto" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) struct brcm_usb_phy {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	bool inited;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) struct brcm_usb_phy_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct  brcm_usb_init_params ini;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	bool			has_eohci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	bool			has_xhci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct clk		*usb_20_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct clk		*usb_30_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct clk		*suspend_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct mutex		mutex;	/* serialize phy init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	int			init_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int			wake_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct brcm_usb_phy	phys[BRCM_USB_PHY_ID_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct notifier_block	pm_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	bool			pm_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static s8 *node_reg_names[BRCM_REGS_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	"crtl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static int brcm_pm_notifier(struct notifier_block *notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			    unsigned long pm_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			    void *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct brcm_usb_phy_data *priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		container_of(notifier, struct brcm_usb_phy_data, pm_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	switch (pm_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	case PM_HIBERNATION_PREPARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	case PM_SUSPEND_PREPARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		priv->pm_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	case PM_POST_RESTORE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	case PM_POST_HIBERNATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	case PM_POST_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		priv->pm_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static irqreturn_t brcm_usb_phy_wake_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	struct phy *gphy = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	pm_wakeup_event(&gphy->dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static int brcm_usb_phy_init(struct phy *gphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	struct brcm_usb_phy *phy = phy_get_drvdata(gphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	struct brcm_usb_phy_data *priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (priv->pm_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * Use a lock to make sure a second caller waits until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * the base phy is inited before using it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	mutex_lock(&priv->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (priv->init_count++ == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		clk_prepare_enable(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		clk_prepare_enable(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		clk_prepare_enable(priv->suspend_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		brcm_usb_init_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	mutex_unlock(&priv->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	if (phy->id == BRCM_USB_PHY_2_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		brcm_usb_init_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	else if (phy->id == BRCM_USB_PHY_3_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		brcm_usb_init_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	phy->inited = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	dev_dbg(&gphy->dev, "INIT, id: %d, total: %d\n", phy->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		priv->init_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int brcm_usb_phy_exit(struct phy *gphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct brcm_usb_phy *phy = phy_get_drvdata(gphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct brcm_usb_phy_data *priv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		container_of(phy, struct brcm_usb_phy_data, phys[phy->id]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (priv->pm_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	dev_dbg(&gphy->dev, "EXIT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (phy->id == BRCM_USB_PHY_2_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		brcm_usb_uninit_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (phy->id == BRCM_USB_PHY_3_0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		brcm_usb_uninit_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/* If both xhci and eohci are gone, reset everything else */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	mutex_lock(&priv->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (--priv->init_count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		brcm_usb_uninit_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		clk_disable_unprepare(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		clk_disable_unprepare(priv->suspend_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	mutex_unlock(&priv->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	phy->inited = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static const struct phy_ops brcm_usb_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	.init		= brcm_usb_phy_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	.exit		= brcm_usb_phy_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static struct phy *brcm_usb_phy_xlate(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				      struct of_phandle_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	struct brcm_usb_phy_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	 * values 0 and 1 are for backward compatibility with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 * device tree nodes from older bootloaders.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	switch (args->args[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	case PHY_TYPE_USB2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		if (data->phys[BRCM_USB_PHY_2_0].phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			return data->phys[BRCM_USB_PHY_2_0].phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		dev_warn(dev, "Error, 2.0 Phy not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	case PHY_TYPE_USB3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		if (data->phys[BRCM_USB_PHY_3_0].phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			return data->phys[BRCM_USB_PHY_3_0].phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		dev_warn(dev, "Error, 3.0 Phy not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int name_to_value(const struct value_to_name_map *table, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			 const char *name, int *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	*value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	for (x = 0; x < count; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		if (sysfs_streq(name, table[x].name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			*value = x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static const char *value_to_name(const struct value_to_name_map *table, int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				 int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (value >= count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return "unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	return table[value].name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static ssize_t dr_mode_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			    struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			    char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		value_to_name(&brcm_dr_mode_to_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			      ARRAY_SIZE(brcm_dr_mode_to_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			      priv->ini.mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static DEVICE_ATTR_RO(dr_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static ssize_t dual_select_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				 struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				 const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	mutex_lock(&sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	res = name_to_value(&brcm_dual_mode_to_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 			    ARRAY_SIZE(brcm_dual_mode_to_name), buf, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		brcm_usb_set_dual_select(&priv->ini, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		res = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	mutex_unlock(&sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static ssize_t dual_select_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 				struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 				char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	mutex_lock(&sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	value = brcm_usb_get_dual_select(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	mutex_unlock(&sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		value_to_name(&brcm_dual_mode_to_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			      ARRAY_SIZE(brcm_dual_mode_to_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			      value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static DEVICE_ATTR_RW(dual_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static struct attribute *brcm_usb_phy_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	&dev_attr_dr_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	&dev_attr_dual_select.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static const struct attribute_group brcm_usb_phy_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.attrs = brcm_usb_phy_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static const struct match_chip_info chip_info_7216 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	.init_func = &brcm_usb_dvr_init_7216,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	.required_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		BRCM_REGS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		BRCM_REGS_XHCI_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		BRCM_REGS_XHCI_GBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static const struct match_chip_info chip_info_7211b0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.init_func = &brcm_usb_dvr_init_7211b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	.required_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		BRCM_REGS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		BRCM_REGS_XHCI_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		BRCM_REGS_XHCI_GBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		BRCM_REGS_USB_PHY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		BRCM_REGS_USB_MDIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.optional_reg = BRCM_REGS_BDC_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static const struct match_chip_info chip_info_7445 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	.init_func = &brcm_usb_dvr_init_7445,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	.required_regs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		BRCM_REGS_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		BRCM_REGS_XHCI_EC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const struct of_device_id brcm_usb_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		.compatible = "brcm,bcm7216-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		.data = &chip_info_7216,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		.compatible = "brcm,bcm7211-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		.data = &chip_info_7211b0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		.compatible = "brcm,brcmstb-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		.data = &chip_info_7445,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	{ /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int brcm_usb_get_regs(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 			     enum brcmusb_reg_sel regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			     struct  brcm_usb_init_params *ini,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			     bool optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	/* Older DT nodes have ctrl and optional xhci_ec by index only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 						node_reg_names[regs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		if (regs == BRCM_REGS_CTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		} else if (regs == BRCM_REGS_XHCI_EC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			/* XHCI_EC registers are optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			if (res == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			if (optional) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 				dev_dbg(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 					"Optional reg %s not found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 					node_reg_names[regs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			dev_err(&pdev->dev, "can't get %s base addr\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				node_reg_names[regs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	ini->regs[regs] = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (IS_ERR(ini->regs[regs])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		dev_err(&pdev->dev, "can't map %s register space\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			node_reg_names[regs]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static int brcm_usb_phy_dvr_init(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 				 struct brcm_usb_phy_data *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 				 struct device_node *dn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	struct phy *gphy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	priv->usb_20_clk = of_clk_get_by_name(dn, "sw_usb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (IS_ERR(priv->usb_20_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		if (PTR_ERR(priv->usb_20_clk) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		dev_info(dev, "Clock not found in Device Tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		priv->usb_20_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	err = clk_prepare_enable(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (priv->has_eohci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		gphy = devm_phy_create(dev, NULL, &brcm_usb_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		if (IS_ERR(gphy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 			dev_err(dev, "failed to create EHCI/OHCI PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			return PTR_ERR(gphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		priv->phys[BRCM_USB_PHY_2_0].phy = gphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		priv->phys[BRCM_USB_PHY_2_0].id = BRCM_USB_PHY_2_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		phy_set_drvdata(gphy, &priv->phys[BRCM_USB_PHY_2_0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (priv->has_xhci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		gphy = devm_phy_create(dev, NULL, &brcm_usb_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		if (IS_ERR(gphy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			dev_err(dev, "failed to create XHCI PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			return PTR_ERR(gphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		priv->phys[BRCM_USB_PHY_3_0].phy = gphy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		priv->phys[BRCM_USB_PHY_3_0].id = BRCM_USB_PHY_3_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		phy_set_drvdata(gphy, &priv->phys[BRCM_USB_PHY_3_0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		priv->usb_30_clk = of_clk_get_by_name(dn, "sw_usb3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		if (IS_ERR(priv->usb_30_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			if (PTR_ERR(priv->usb_30_clk) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 				return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 				 "USB3.0 clock not found in Device Tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			priv->usb_30_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		err = clk_prepare_enable(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	priv->suspend_clk = clk_get(dev, "usb0_freerun");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	if (IS_ERR(priv->suspend_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		if (PTR_ERR(priv->suspend_clk) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		dev_err(dev, "Suspend Clock not found in Device Tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		priv->suspend_clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	priv->wake_irq = platform_get_irq_byname(pdev, "wake");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (priv->wake_irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		priv->wake_irq = platform_get_irq_byname(pdev, "wakeup");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	if (priv->wake_irq >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		err = devm_request_irq(dev, priv->wake_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 				       brcm_usb_phy_wake_isr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 				       dev_name(dev), gphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		device_set_wakeup_capable(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		dev_info(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			 "Wake interrupt missing, system wake not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int brcm_usb_phy_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	struct brcm_usb_phy_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct phy_provider *phy_provider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct device_node *dn = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	const char *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	void (*dvr_init)(struct brcm_usb_init_params *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	const struct match_chip_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	struct regmap *rmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	platform_set_drvdata(pdev, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	priv->ini.family_id = brcmstb_get_family_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	priv->ini.product_id = brcmstb_get_product_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	match = of_match_node(brcm_usb_dt_ids, dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	info = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	dvr_init = info->init_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	(*dvr_init)(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	dev_dbg(dev, "Best mapping table is for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		priv->ini.family_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	of_property_read_u32(dn, "brcm,ipp", &priv->ini.ipp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	of_property_read_u32(dn, "brcm,ioc", &priv->ini.ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	priv->ini.mode = USB_CTLR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	err = of_property_read_string(dn, "dr_mode", &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		name_to_value(&brcm_dr_mode_to_name[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 			      ARRAY_SIZE(brcm_dr_mode_to_name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			mode, &priv->ini.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (of_property_read_bool(dn, "brcm,has-xhci"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		priv->has_xhci = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (of_property_read_bool(dn, "brcm,has-eohci"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		priv->has_eohci = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	for (x = 0; x < BRCM_REGS_MAX; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		if (info->required_regs[x] >= BRCM_REGS_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		err = brcm_usb_get_regs(pdev, info->required_regs[x],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 					&priv->ini, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (info->optional_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		err = brcm_usb_get_regs(pdev, info->optional_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 					&priv->ini, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	err = brcm_usb_phy_dvr_init(pdev, priv, dn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	priv->pm_notifier.notifier_call = brcm_pm_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	register_pm_notifier(&priv->pm_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	mutex_init(&priv->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	/* make sure invert settings are correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	brcm_usb_init_ipp(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	 * Create sysfs entries for mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	 * Remove "dual_select" attribute if not in dual mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (priv->ini.mode != USB_CTLR_MODE_DRD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		brcm_usb_phy_attrs[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	err = sysfs_create_group(&dev->kobj, &brcm_usb_phy_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		dev_warn(dev, "Error creating sysfs attributes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	/* Get piarbctl syscon if it exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 						 "syscon-piarbctl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	if (IS_ERR(rmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		rmap = syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 						       "brcm,syscon-piarbctl");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	if (!IS_ERR(rmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		priv->ini.syscon_piarbctl = rmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	/* start with everything off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	if (priv->has_xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		brcm_usb_uninit_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	if (priv->has_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		brcm_usb_uninit_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	brcm_usb_uninit_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	clk_disable_unprepare(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	phy_provider = devm_of_phy_provider_register(dev, brcm_usb_phy_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	return PTR_ERR_OR_ZERO(phy_provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static int brcm_usb_phy_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	sysfs_remove_group(&pdev->dev.kobj, &brcm_usb_phy_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	unregister_pm_notifier(&priv->pm_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int brcm_usb_phy_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (priv->init_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		dev_dbg(dev, "SUSPEND\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		priv->ini.wake_enabled = device_may_wakeup(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		if (priv->phys[BRCM_USB_PHY_3_0].inited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 			brcm_usb_uninit_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		if (priv->phys[BRCM_USB_PHY_2_0].inited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 			brcm_usb_uninit_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		brcm_usb_uninit_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		 * Handle the clocks unless needed for wake. This has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		 * to work for both older XHCI->3.0-clks, EOHCI->2.0-clks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		 * and newer XHCI->2.0-clks/3.0-clks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		if (!priv->ini.suspend_with_clocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 			if (priv->phys[BRCM_USB_PHY_3_0].inited)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 				clk_disable_unprepare(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 			if (priv->phys[BRCM_USB_PHY_2_0].inited ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 			    !priv->has_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 				clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		if (priv->wake_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 			enable_irq_wake(priv->wake_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int brcm_usb_phy_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	struct brcm_usb_phy_data *priv = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	clk_prepare_enable(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	clk_prepare_enable(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	brcm_usb_init_ipp(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	 * Initialize anything that was previously initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	 * Uninitialize anything that wasn't previously initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (priv->init_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		dev_dbg(dev, "RESUME\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		if (priv->wake_irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 			disable_irq_wake(priv->wake_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 		brcm_usb_init_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		if (priv->phys[BRCM_USB_PHY_2_0].inited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 			brcm_usb_init_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		} else if (priv->has_eohci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			brcm_usb_uninit_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 			clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		if (priv->phys[BRCM_USB_PHY_3_0].inited) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			brcm_usb_init_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		} else if (priv->has_xhci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 			brcm_usb_uninit_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			clk_disable_unprepare(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 			if (!priv->has_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 				clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 		if (priv->has_xhci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			brcm_usb_uninit_xhci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		if (priv->has_eohci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 			brcm_usb_uninit_eohci(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		brcm_usb_uninit_common(&priv->ini);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		clk_disable_unprepare(priv->usb_20_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		clk_disable_unprepare(priv->usb_30_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	priv->ini.wake_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static const struct dev_pm_ops brcm_usb_phy_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	SET_LATE_SYSTEM_SLEEP_PM_OPS(brcm_usb_phy_suspend, brcm_usb_phy_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) MODULE_DEVICE_TABLE(of, brcm_usb_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static struct platform_driver brcm_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	.probe		= brcm_usb_phy_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	.remove		= brcm_usb_phy_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		.name	= "brcmstb-usb-phy",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		.pm = &brcm_usb_phy_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		.of_match_table = brcm_usb_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) module_platform_driver(brcm_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) MODULE_ALIAS("platform:brcmstb-usb-phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) MODULE_AUTHOR("Al Cooper <acooper@broadcom.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) MODULE_DESCRIPTION("BRCM USB PHY driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) MODULE_LICENSE("GPL v2");