summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bootcount/Kconfig36
-rw-r--r--drivers/bootcount/Makefile2
-rw-r--r--drivers/bootcount/bootcount_fs.c (renamed from drivers/bootcount/bootcount_ext.c)12
-rw-r--r--drivers/clk/sunxi/clk_v3s.c6
-rw-r--r--drivers/firmware/psci.c41
-rw-r--r--drivers/misc/rockchip-io-domain.c66
-rw-r--r--drivers/mmc/am654_sdhci.c38
-rw-r--r--drivers/net/sun8i_emac.c7
-rw-r--r--drivers/phy/rockchip/phy-rockchip-inno-hdmi.c8
-rw-r--r--drivers/phy/rockchip/phy-rockchip-naneng-combphy.c4
-rw-r--r--drivers/phy/rockchip/phy-rockchip-snps-pcie3.c42
-rw-r--r--drivers/power/Kconfig17
-rw-r--r--drivers/power/Makefile9
-rw-r--r--drivers/power/axp305.c82
-rw-r--r--drivers/power/axp313.c133
-rw-r--r--drivers/power/axp_spl.c173
-rw-r--r--drivers/power/pmic/axp.c1
-rw-r--r--drivers/power/pmic/rk8xx.c2
-rw-r--r--drivers/power/regulator/axp_regulator.c28
-rw-r--r--drivers/rng/smccc_trng.c4
-rw-r--r--drivers/rtc/goldfish_rtc.c4
-rw-r--r--drivers/spi/spi-sunxi.c21
-rw-r--r--drivers/timer/mtk_timer.c3
-rw-r--r--drivers/usb/cdns3/core.c24
-rw-r--r--drivers/usb/cdns3/gadget-export.h2
-rw-r--r--drivers/usb/cdns3/gadget.c11
-rw-r--r--drivers/usb/dwc3/dwc3-generic.c23
-rw-r--r--drivers/usb/dwc3/dwc3-layerscape.c21
-rw-r--r--drivers/usb/dwc3/gadget.c33
-rw-r--r--drivers/usb/eth/asix88179.c6
-rw-r--r--drivers/usb/gadget/dwc2_udc_otg.c20
-rw-r--r--drivers/usb/gadget/epautoconf.c81
-rw-r--r--drivers/usb/gadget/ether.c25
-rw-r--r--drivers/usb/gadget/g_dnl.c17
-rw-r--r--drivers/usb/gadget/gadget_chips.h210
-rw-r--r--drivers/usb/gadget/max3420_udc.c19
-rw-r--r--drivers/usb/gadget/udc/udc-uclass.c24
-rw-r--r--drivers/usb/host/usb-sandbox.c7
-rw-r--r--drivers/usb/mtu3/mtu3_plat.c23
-rw-r--r--drivers/usb/musb-new/omap2430.c26
-rw-r--r--drivers/usb/musb-new/ti-musb.c23
-rw-r--r--drivers/usb/musb-new/ux500.c22
42 files changed, 654 insertions, 702 deletions
diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig
index 3c56253b1ea..2105cea3d45 100644
--- a/drivers/bootcount/Kconfig
+++ b/drivers/bootcount/Kconfig
@@ -25,13 +25,13 @@ config BOOTCOUNT_GENERIC
Set to the address where the bootcount and bootcount magic
will be stored.
-config BOOTCOUNT_EXT
- bool "Boot counter on EXT filesystem"
- depends on FS_EXT4
- select EXT4_WRITE
+config BOOTCOUNT_FS
+ bool "Boot counter on a filesystem"
help
- Add support for maintaining boot count in a file on an EXT
- filesystem.
+ Add support for maintaining boot count in a file on a filesystem.
+ This requires that you have enabled write support for the filesystem
+ that will be used by the partition that you configure this feature
+ for.
config BOOTCOUNT_AM33XX
bool "Boot counter in AM33XX RTC IP block"
@@ -184,26 +184,26 @@ config SYS_BOOTCOUNT_SINGLEWORD
This option enables packing boot count magic value and boot count
into single word (32 bits).
-config SYS_BOOTCOUNT_EXT_INTERFACE
- string "Interface on which to find boot counter EXT filesystem"
+config SYS_BOOTCOUNT_FS_INTERFACE
+ string "Interface on which to find boot counter filesystem"
default "mmc"
- depends on BOOTCOUNT_EXT
+ depends on BOOTCOUNT_FS
help
Set the interface to use when locating the filesystem to use for the
boot counter.
-config SYS_BOOTCOUNT_EXT_DEVPART
- string "Partition of the boot counter EXT filesystem"
+config SYS_BOOTCOUNT_FS_DEVPART
+ string "Partition of the boot counter filesystem"
default "0:1"
- depends on BOOTCOUNT_EXT
+ depends on BOOTCOUNT_FS
help
Set the partition to use when locating the filesystem to use for the
boot counter.
-config SYS_BOOTCOUNT_EXT_NAME
- string "Path and filename of the EXT filesystem based boot counter"
+config SYS_BOOTCOUNT_FS_NAME
+ string "Path and filename of the FS filesystem based boot counter"
default "/boot/failures"
- depends on BOOTCOUNT_EXT
+ depends on BOOTCOUNT_FS
help
Set the filename and path of the file used to store the boot counter.
@@ -211,18 +211,18 @@ config SYS_BOOTCOUNT_ADDR
hex "RAM address used for reading and writing the boot counter"
default 0x44E3E000 if BOOTCOUNT_AM33XX || BOOTCOUNT_AM33XX_NVMEM
default 0xE0115FF8 if ARCH_LS1043A || ARCH_LS1021A
- depends on BOOTCOUNT_AM33XX || BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
+ depends on BOOTCOUNT_AM33XX || BOOTCOUNT_GENERIC || BOOTCOUNT_FS || \
BOOTCOUNT_AM33XX_NVMEM
help
Set the address used for reading and writing the boot counter.
config SYS_BOOTCOUNT_MAGIC
hex "Magic value for the boot counter"
- default 0xB001C041 if BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
+ default 0xB001C041 if BOOTCOUNT_GENERIC || BOOTCOUNT_FS || \
BOOTCOUNT_AM33XX || BOOTCOUNT_ENV || \
BOOTCOUNT_RAM || BOOTCOUNT_AT91 || DM_BOOTCOUNT
default 0xB0 if BOOTCOUNT_AM33XX_NVMEM
- depends on BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
+ depends on BOOTCOUNT_GENERIC || BOOTCOUNT_FS || \
BOOTCOUNT_AM33XX || BOOTCOUNT_ENV || \
BOOTCOUNT_RAM || BOOTCOUNT_AT91 || DM_BOOTCOUNT || \
BOOTCOUNT_AM33XX_NVMEM
diff --git a/drivers/bootcount/Makefile b/drivers/bootcount/Makefile
index e7771f5b36d..245f8796337 100644
--- a/drivers/bootcount/Makefile
+++ b/drivers/bootcount/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_BOOTCOUNT_AT91) += bootcount_at91.o
obj-$(CONFIG_BOOTCOUNT_AM33XX) += bootcount_davinci.o
obj-$(CONFIG_BOOTCOUNT_RAM) += bootcount_ram.o
obj-$(CONFIG_BOOTCOUNT_ENV) += bootcount_env.o
-obj-$(CONFIG_BOOTCOUNT_EXT) += bootcount_ext.o
+obj-$(CONFIG_BOOTCOUNT_FS) += bootcount_fs.o
obj-$(CONFIG_BOOTCOUNT_AM33XX_NVMEM) += bootcount_nvmem.o
obj-$(CONFIG_DM_BOOTCOUNT) += bootcount-uclass.o
diff --git a/drivers/bootcount/bootcount_ext.c b/drivers/bootcount/bootcount_fs.c
index 9639e638e95..569592d8aad 100644
--- a/drivers/bootcount/bootcount_ext.c
+++ b/drivers/bootcount/bootcount_fs.c
@@ -25,8 +25,8 @@ void bootcount_store(ulong a)
loff_t len;
int ret;
- if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_EXT_INTERFACE,
- CONFIG_SYS_BOOTCOUNT_EXT_DEVPART, FS_TYPE_EXT)) {
+ if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_FS_INTERFACE,
+ CONFIG_SYS_BOOTCOUNT_FS_DEVPART, FS_TYPE_ANY)) {
puts("Error selecting device\n");
return;
}
@@ -42,7 +42,7 @@ void bootcount_store(ulong a)
buf->upgrade_available = upgrade_available;
unmap_sysmem(buf);
- ret = fs_write(CONFIG_SYS_BOOTCOUNT_EXT_NAME,
+ ret = fs_write(CONFIG_SYS_BOOTCOUNT_FS_NAME,
CONFIG_SYS_BOOTCOUNT_ADDR, 0, sizeof(bootcount_ext_t),
&len);
if (ret != 0)
@@ -55,13 +55,13 @@ ulong bootcount_load(void)
loff_t len_read;
int ret;
- if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_EXT_INTERFACE,
- CONFIG_SYS_BOOTCOUNT_EXT_DEVPART, FS_TYPE_EXT)) {
+ if (fs_set_blk_dev(CONFIG_SYS_BOOTCOUNT_FS_INTERFACE,
+ CONFIG_SYS_BOOTCOUNT_FS_DEVPART, FS_TYPE_ANY)) {
puts("Error selecting device\n");
return 0;
}
- ret = fs_read(CONFIG_SYS_BOOTCOUNT_EXT_NAME, CONFIG_SYS_BOOTCOUNT_ADDR,
+ ret = fs_read(CONFIG_SYS_BOOTCOUNT_FS_NAME, CONFIG_SYS_BOOTCOUNT_ADDR,
0, sizeof(bootcount_ext_t), &len_read);
if (ret != 0 || len_read != sizeof(bootcount_ext_t)) {
puts("Error loading bootcount\n");
diff --git a/drivers/clk/sunxi/clk_v3s.c b/drivers/clk/sunxi/clk_v3s.c
index 85410e282e8..292c8c44f97 100644
--- a/drivers/clk/sunxi/clk_v3s.c
+++ b/drivers/clk/sunxi/clk_v3s.c
@@ -16,6 +16,7 @@ static struct ccu_clk_gate v3s_gates[] = {
[CLK_BUS_MMC0] = GATE(0x060, BIT(8)),
[CLK_BUS_MMC1] = GATE(0x060, BIT(9)),
[CLK_BUS_MMC2] = GATE(0x060, BIT(10)),
+ [CLK_BUS_EMAC] = GATE(0x060, BIT(17)),
[CLK_BUS_SPI0] = GATE(0x060, BIT(20)),
[CLK_BUS_OTG] = GATE(0x060, BIT(24)),
@@ -30,6 +31,8 @@ static struct ccu_clk_gate v3s_gates[] = {
[CLK_BUS_UART1] = GATE(0x06c, BIT(17)),
[CLK_BUS_UART2] = GATE(0x06c, BIT(18)),
+ [CLK_BUS_EPHY] = GATE(0x070, BIT(0)),
+
[CLK_SPI0] = GATE(0x0a0, BIT(31)),
[CLK_USB_PHY0] = GATE(0x0cc, BIT(8)),
@@ -44,12 +47,15 @@ static struct ccu_reset v3s_resets[] = {
[RST_BUS_MMC0] = RESET(0x2c0, BIT(8)),
[RST_BUS_MMC1] = RESET(0x2c0, BIT(9)),
[RST_BUS_MMC2] = RESET(0x2c0, BIT(10)),
+ [RST_BUS_EMAC] = RESET(0x2c0, BIT(17)),
[RST_BUS_SPI0] = RESET(0x2c0, BIT(20)),
[RST_BUS_OTG] = RESET(0x2c0, BIT(24)),
[RST_BUS_TCON0] = RESET(0x2c4, BIT(4)),
[RST_BUS_DE] = RESET(0x2c4, BIT(12)),
+ [RST_BUS_EPHY] = RESET(0x2c8, BIT(2)),
+
[RST_BUS_I2C0] = RESET(0x2d8, BIT(0)),
[RST_BUS_I2C1] = RESET(0x2d8, BIT(1)),
[RST_BUS_UART0] = RESET(0x2d8, BIT(16)),
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index c32c3f5c6a5..2e3223e1c32 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -22,6 +22,7 @@
#include <linux/libfdt.h>
#include <linux/printk.h>
#include <linux/psci.h>
+#include <power-domain-uclass.h>
#define DRIVER_NAME "psci"
@@ -171,6 +172,10 @@ static int bind_smccc_features(struct udevice *dev, int psci_method)
static int psci_bind(struct udevice *dev)
{
+#if IS_ENABLED(CONFIG_POWER_DOMAIN)
+ ofnode node;
+#endif
+
/* No SYSTEM_RESET support for PSCI 0.1 */
if (device_is_compatible(dev, "arm,psci-0.2") ||
device_is_compatible(dev, "arm,psci-1.0")) {
@@ -187,6 +192,16 @@ static int psci_bind(struct udevice *dev)
if (IS_ENABLED(CONFIG_ARM_SMCCC_FEATURES) && device_is_compatible(dev, "arm,psci-1.0"))
dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+ /* Bind power-domain subnodes */
+#if IS_ENABLED(CONFIG_POWER_DOMAIN)
+ dev_for_each_subnode(node, dev) {
+ if (device_bind_driver_to_node(dev, "psci_power_domain",
+ ofnode_get_name(node),
+ node, NULL))
+ pr_warn("failed to bind %s\n", ofnode_get_name(node));
+ }
+#endif
+
return 0;
}
@@ -323,3 +338,29 @@ U_BOOT_DRIVER(psci) = {
#endif
.flags = DM_FLAG_PRE_RELOC,
};
+
+#if IS_ENABLED(CONFIG_POWER_DOMAIN)
+/* Accept #power-domain-cells == 0 */
+static int psci_power_domain_xlate(struct power_domain *power_domain,
+ struct ofnode_phandle_args *args)
+{
+ return args->args_count == 0 ? 0 : -EINVAL;
+}
+
+static const struct power_domain_ops psci_power_ops = {
+ .of_xlate = psci_power_domain_xlate,
+};
+
+static int psci_power_domain_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+U_BOOT_DRIVER(psci_power_domain) = {
+ .name = "psci_power_domain",
+ .id = UCLASS_POWER_DOMAIN,
+ .ops = &psci_power_ops,
+ .probe = psci_power_domain_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+#endif
diff --git a/drivers/misc/rockchip-io-domain.c b/drivers/misc/rockchip-io-domain.c
index 04d4d07c412..cf4f7c3984c 100644
--- a/drivers/misc/rockchip-io-domain.c
+++ b/drivers/misc/rockchip-io-domain.c
@@ -27,6 +27,10 @@
#define MAX_VOLTAGE_1_8 1980000
#define MAX_VOLTAGE_3_3 3600000
+#define PX30_IO_VSEL 0x180
+#define PX30_IO_VSEL_VCCIO6_SRC BIT(0)
+#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1
+
#define RK3328_SOC_CON4 0x410
#define RK3328_SOC_CON4_VCCIO2 BIT(7)
#define RK3328_SOC_VCCIO2_SUPPLY_NUM 1
@@ -99,6 +103,22 @@ static int rockchip_iodomain_write(struct regmap *grf, uint offset, int idx, int
return regmap_write(grf, offset, val);
}
+static int px30_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
+{
+ int ret = rockchip_iodomain_write(grf, offset, idx, uV);
+
+ if (!ret && idx == PX30_IO_VSEL_VCCIO6_SUPPLY_NUM) {
+ /*
+ * set vccio6 iodomain to also use this framework
+ * instead of a special gpio.
+ */
+ u32 val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
+ ret = regmap_write(grf, PX30_IO_VSEL, val);
+ }
+
+ return ret;
+}
+
static int rk3328_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
{
int ret = rockchip_iodomain_write(grf, offset, idx, uV);
@@ -131,6 +151,44 @@ static int rk3399_pmu_iodomain_write(struct regmap *grf, uint offset, int idx, i
return ret;
}
+static const struct rockchip_iodomain_soc_data soc_data_px30 = {
+ .grf_offset = 0x180,
+ .supply_names = {
+ NULL,
+ "vccio6-supply",
+ "vccio1-supply",
+ "vccio2-supply",
+ "vccio3-supply",
+ "vccio4-supply",
+ "vccio5-supply",
+ "vccio-oscgpi-supply",
+ },
+ .write = px30_iodomain_write,
+};
+
+static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
+ .grf_offset = 0x100,
+ .supply_names = {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "pmuio1-supply",
+ "pmuio2-supply",
+ },
+ .write = rockchip_iodomain_write,
+};
+
static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
.grf_offset = 0x410,
.supply_names = {
@@ -191,6 +249,14 @@ static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
static const struct udevice_id rockchip_iodomain_ids[] = {
{
+ .compatible = "rockchip,px30-io-voltage-domain",
+ .data = (ulong)&soc_data_px30,
+ },
+ {
+ .compatible = "rockchip,px30-pmu-io-voltage-domain",
+ .data = (ulong)&soc_data_px30_pmu,
+ },
+ {
.compatible = "rockchip,rk3328-io-voltage-domain",
.data = (ulong)&soc_data_rk3328,
},
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index 48fac7a11b4..b4c60a48d2e 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -105,6 +105,8 @@ struct am654_sdhci_plat {
#define FREQSEL_2_BIT BIT(2)
#define STRBSEL_4_BIT BIT(3)
#define DLL_CALIB BIT(4)
+ u32 quirks;
+#define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
};
struct timing_data {
@@ -350,10 +352,8 @@ int am654_sdhci_init(struct am654_sdhci_plat *plat)
}
#define MAX_SDCD_DEBOUNCE_TIME 2000
-static int am654_sdhci_deferred_probe(struct sdhci_host *host)
+static int am654_sdhci_cd_poll(struct mmc *mmc)
{
- struct udevice *dev = host->mmc->dev;
- struct am654_sdhci_plat *plat = dev_get_plat(dev);
unsigned long start;
int val;
@@ -368,12 +368,35 @@ static int am654_sdhci_deferred_probe(struct sdhci_host *host)
if (get_timer(start) > MAX_SDCD_DEBOUNCE_TIME)
return -ENOMEDIUM;
- val = mmc_getcd(host->mmc);
+ val = mmc_getcd(mmc);
} while (!val);
+ return 0;
+}
+
+static int am654_sdhci_deferred_probe(struct sdhci_host *host)
+{
+ struct udevice *dev = host->mmc->dev;
+ struct am654_sdhci_plat *plat = dev_get_plat(dev);
+ int ret;
+
+ if (!(plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)) {
+ if (am654_sdhci_cd_poll(host->mmc))
+ return -ENOMEDIUM;
+ }
+
am654_sdhci_init(plat);
- return sdhci_probe(dev);
+ ret = sdhci_probe(dev);
+
+ if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) {
+ u8 hostctrlreg = sdhci_readb(host, SDHCI_HOST_CONTROL);
+
+ hostctrlreg |= SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST;
+ sdhci_writeb(host, hostctrlreg, SDHCI_HOST_CONTROL);
+ }
+
+ return ret;
}
static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg)
@@ -679,6 +702,9 @@ static int am654_sdhci_probe(struct udevice *dev)
regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
+ if (plat->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST)
+ am654_sdhci_deferred_probe(host);
+
return 0;
}
@@ -728,6 +754,8 @@ static int am654_sdhci_of_to_plat(struct udevice *dev)
dev_read_u32(dev, "ti,strobe-sel", &plat->strb_sel);
dev_read_u32(dev, "ti,clkbuf-sel", &plat->clkbuf_sel);
+ if (dev_read_bool(dev, "ti,fails-without-test-cd"))
+ plat->quirks |= SDHCI_AM654_QUIRK_FORCE_CDTEST;
ret = mmc_of_parse(dev, cfg);
if (ret)
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index f4b97798d2d..6fab34715de 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -892,6 +892,11 @@ static const struct emac_variant emac_variant_r40 = {
.syscon_offset = 0x164,
};
+static const struct emac_variant emac_variant_v3s = {
+ .syscon_offset = 0x30,
+ .soc_has_internal_phy = true,
+};
+
static const struct emac_variant emac_variant_a64 = {
.syscon_offset = 0x30,
.support_rmii = true,
@@ -909,6 +914,8 @@ static const struct udevice_id sun8i_emac_eth_ids[] = {
.data = (ulong)&emac_variant_h3 },
{ .compatible = "allwinner,sun8i-r40-gmac",
.data = (ulong)&emac_variant_r40 },
+ { .compatible = "allwinner,sun8i-v3s-emac",
+ .data = (ulong)&emac_variant_v3s },
{ .compatible = "allwinner,sun50i-a64-emac",
.data = (ulong)&emac_variant_a64 },
{ .compatible = "allwinner,sun50i-h6-emac",
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
index 3bb1a254ffb..7459779dffe 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c
@@ -432,8 +432,8 @@ static inline void inno_update_bits(struct inno_hdmi_phy *inno, u8 reg,
inno_write(inno, reg, tmp);
}
-#define inno_poll(reg, val, cond, sleep_us, timeout_us) \
- readl_poll_sleep_timeout((reg) * 4, val, cond, sleep_us, timeout_us)
+#define inno_poll(inno, reg, val, cond, sleep_us, timeout_us) \
+ readl_poll_sleep_timeout((inno)->regs + ((reg) * 4), val, cond, sleep_us, timeout_us)
static unsigned long inno_hdmi_phy_get_tmdsclk(struct inno_hdmi_phy *inno,
unsigned long rate)
@@ -575,7 +575,7 @@ inno_hdmi_phy_rk3328_clk_set_rate(struct phy *phy,
inno_update_bits(inno, 0xa0, RK3328_PRE_PLL_POWER_DOWN, 0);
/* Wait for Pre-PLL lock */
- ret = inno_poll(0xa9, val, val & RK3328_PRE_PLL_LOCK_STATUS,
+ ret = inno_poll(inno, 0xa9, val, val & RK3328_PRE_PLL_LOCK_STATUS,
1000, 10000);
if (ret) {
dev_err(phy->dev, "Pre-PLL locking failed\n");
@@ -674,7 +674,7 @@ inno_hdmi_phy_rk3328_power_on(struct phy *phy,
RK3328_TMDS_DRIVER_ENABLE);
/* Wait for post PLL lock */
- ret = inno_poll(0xaf, v, v & RK3328_POST_PLL_LOCK_STATUS,
+ ret = inno_poll(inno, 0xaf, v, v & RK3328_POST_PLL_LOCK_STATUS,
1000, 10000);
if (ret) {
dev_err(phy->dev, "Post-PLL locking failed\n");
diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
index 3ad339bccc1..1b85cbcce8d 100644
--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
@@ -225,7 +225,7 @@ static int rockchip_combphy_xlate(struct phy *phy, struct ofnode_phandle_args *a
return 0;
}
-static const struct phy_ops rochchip_combphy_ops = {
+static const struct phy_ops rockchip_combphy_ops = {
.init = rockchip_combphy_init,
.exit = rockchip_combphy_exit,
.of_xlate = rockchip_combphy_xlate,
@@ -535,7 +535,7 @@ U_BOOT_DRIVER(rockchip_naneng_combphy) = {
.name = "naneng-combphy",
.id = UCLASS_PHY,
.of_match = rockchip_combphy_ids,
- .ops = &rochchip_combphy_ops,
+ .ops = &rockchip_combphy_ops,
.probe = rockchip_combphy_probe,
.priv_auto = sizeof(struct rockchip_combphy_priv),
};
diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
index 2737bd81dd9..62b42d1805b 100644
--- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
+++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c
@@ -36,6 +36,8 @@
#define RK3588_BIFURCATION_LANE_0_1 BIT(0)
#define RK3588_BIFURCATION_LANE_2_3 BIT(1)
#define RK3588_LANE_AGGREGATION BIT(2)
+#define RK3588_PCIE1LN_SEL_EN (GENMASK(1, 0) << 16)
+#define RK3588_PCIE30_PHY_MODE_EN (GENMASK(2, 0) << 16)
/**
* struct rockchip_p3phy_priv - RK DW PCIe PHY state
@@ -108,7 +110,7 @@ static int rockchip_p3phy_rk3588_init(struct phy *phy)
{
struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
u32 reg = 0;
- u8 mode = 0;
+ u8 mode = RK3588_LANE_AGGREGATION; /* Lane aggregation by default */
int ret;
/* Deassert PCIe PMA output clamp mode */
@@ -117,31 +119,23 @@ static int rockchip_p3phy_rk3588_init(struct phy *phy)
/* Set bifurcation if needed */
for (int i = 0; i < priv->num_lanes; i++) {
- if (!priv->lanes[i])
- mode |= (BIT(i) << 3);
-
if (priv->lanes[i] > 1)
- mode |= (BIT(i) >> 1);
- }
-
- if (!mode) {
- reg = RK3588_LANE_AGGREGATION;
- } else {
- if (mode & (BIT(0) | BIT(1)))
- reg |= RK3588_BIFURCATION_LANE_0_1;
-
- if (mode & (BIT(2) | BIT(3)))
- reg |= RK3588_BIFURCATION_LANE_2_3;
+ mode &= ~RK3588_LANE_AGGREGATION;
+ if (priv->lanes[i] == 3)
+ mode |= RK3588_BIFURCATION_LANE_0_1;
+ if (priv->lanes[i] == 4)
+ mode |= RK3588_BIFURCATION_LANE_2_3;
}
+ reg = mode;
regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0,
- (0x7 << 16) | reg);
+ RK3588_PCIE30_PHY_MODE_EN | reg);
/* Set pcie1ln_sel in PHP_GRF_PCIESEL_CON */
- reg = (mode & (BIT(6) | BIT(7))) >> 6;
+ reg = mode & (RK3588_BIFURCATION_LANE_0_1 | RK3588_BIFURCATION_LANE_2_3);
if (reg)
regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON,
- (reg << 16) | reg);
+ RK3588_PCIE1LN_SEL_EN | reg);
reset_deassert(&priv->p30phy);
udelay(1);
@@ -164,7 +158,7 @@ static const struct rockchip_p3phy_ops rk3588_ops = {
.phy_init = rockchip_p3phy_rk3588_init,
};
-static int rochchip_p3phy_init(struct phy *phy)
+static int rockchip_p3phy_init(struct phy *phy)
{
struct rockchip_p3phy_ops *ops =
(struct rockchip_p3phy_ops *)dev_get_driver_data(phy->dev);
@@ -185,7 +179,7 @@ static int rochchip_p3phy_init(struct phy *phy)
return ret;
}
-static int rochchip_p3phy_exit(struct phy *phy)
+static int rockchip_p3phy_exit(struct phy *phy)
{
struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev);
@@ -251,9 +245,9 @@ static int rockchip_p3phy_probe(struct udevice *dev)
return 0;
}
-static struct phy_ops rochchip_p3phy_ops = {
- .init = rochchip_p3phy_init,
- .exit = rochchip_p3phy_exit,
+static struct phy_ops rockchip_p3phy_ops = {
+ .init = rockchip_p3phy_init,
+ .exit = rockchip_p3phy_exit,
};
static const struct udevice_id rockchip_p3phy_of_match[] = {
@@ -272,7 +266,7 @@ U_BOOT_DRIVER(rockchip_pcie3phy) = {
.name = "rockchip_pcie3phy",
.id = UCLASS_PHY,
.of_match = rockchip_p3phy_of_match,
- .ops = &rochchip_p3phy_ops,
+ .ops = &rockchip_p3phy_ops,
.probe = rockchip_p3phy_probe,
.priv_auto = sizeof(struct rockchip_p3phy_priv),
};
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 33b8bc1214d..5556a22cf69 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -109,6 +109,13 @@ config AXP313_POWER
Select this to enable support for the AXP313 PMIC found on some
H616 boards.
+config AXP717_POWER
+ bool "axp717 pmic support"
+ select AXP_PMIC_BUS
+ select CMD_POWEROFF
+ ---help---
+ Select this to enable support for the AXP717 PMIC found on some boards.
+
config AXP809_POWER
bool "axp809 pmic support"
depends on MACH_SUN9I
@@ -151,10 +158,11 @@ config AXP_DCDC1_VOLT
config AXP_DCDC2_VOLT
int "axp pmic dcdc2 voltage"
- depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP313_POWER
+ depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP313_POWER || AXP717_POWER
default 900 if AXP818_POWER
default 1400 if AXP152_POWER || AXP209_POWER
default 1000 if AXP313_POWER
+ default 1000 if AXP717_POWER
default 1200 if MACH_SUN6I
default 1100 if MACH_SUN8I
default 0 if MACH_SUN9I
@@ -167,11 +175,11 @@ config AXP_DCDC2_VOLT
On A80 boards dcdc2 powers the GPU and can be left off.
On A83T boards dcdc2 is used for VDD-CPUA(cluster 0) and should be 0.9V.
On R40 boards dcdc2 is VDD-CPU and should be 1.1V
- On boards using the AXP313 it's often VDD-CPU.
+ On boards using the AXP313 or AXP717 it's often VDD-CPU.
config AXP_DCDC3_VOLT
int "axp pmic dcdc3 voltage"
- depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP313_POWER
+ depends on AXP152_POWER || AXP209_POWER || AXP221_POWER || AXP809_POWER || AXP818_POWER || AXP313_POWER || AXP717_POWER
default 900 if AXP809_POWER || AXP818_POWER
default 1500 if AXP152_POWER
default 1250 if AXP209_POWER
@@ -188,7 +196,8 @@ config AXP_DCDC3_VOLT
On A80 boards dcdc3 is used for VDD-CPUA(cluster 0) and should be 0.9V.
On A83T boards dcdc3 is used for VDD-CPUB(cluster 1) and should be 0.9V.
On R40 boards dcdc3 is VDD-SYS and VDD-GPU and should be 1.1V.
- On boards using the AXP313 it's often VDD-DRAM and should be 1.1V for LPDDR4.
+ On boards using the AXP313 or AXP717 it's often VDD-DRAM and should
+ be 1.1V for LPDDR4.
config AXP_DCDC4_VOLT
int "axp pmic dcdc4 voltage"
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index c7ee4595fc8..9f94df8d641 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -8,13 +8,16 @@ obj-$(CONFIG_$(SPL_TPL_)POWER_DOMAIN) += domain/
obj-y += pmic/
obj-y += regulator/
+obj-$(CONFIG_AXP221_POWER) += axp221.o
+ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_AXP152_POWER) += axp152.o
obj-$(CONFIG_AXP209_POWER) += axp209.o
-obj-$(CONFIG_AXP221_POWER) += axp221.o
-obj-$(CONFIG_AXP305_POWER) += axp305.o
-obj-$(CONFIG_AXP313_POWER) += axp313.o
+obj-$(CONFIG_AXP305_POWER) += axp_spl.o
+obj-$(CONFIG_AXP313_POWER) += axp_spl.o
+obj-$(CONFIG_AXP717_POWER) += axp_spl.o
obj-$(CONFIG_AXP809_POWER) += axp809.o
obj-$(CONFIG_AXP818_POWER) += axp818.o
+endif
obj-$(CONFIG_EXYNOS_TMU) += exynos-tmu.o
obj-$(CONFIG_SY8106A_POWER) += sy8106a.o
obj-$(CONFIG_TPS6586X_POWER) += tps6586x.o
diff --git a/drivers/power/axp305.c b/drivers/power/axp305.c
deleted file mode 100644
index 0312ad9af76..00000000000
--- a/drivers/power/axp305.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * AXP305 driver
- *
- * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
- *
- * Based on axp221.c
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
- * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
- */
-
-#include <command.h>
-#include <errno.h>
-#include <asm/arch/pmic_bus.h>
-#include <axp_pmic.h>
-
-#define AXP305_DCDC4_1600MV_OFFSET 46
-
-static u8 axp305_mvolt_to_cfg(int mvolt, int min, int max, int div)
-{
- if (mvolt < min)
- mvolt = min;
- else if (mvolt > max)
- mvolt = max;
-
- return (mvolt - min) / div;
-}
-
-int axp_set_dcdc4(unsigned int mvolt)
-{
- int ret;
- u8 cfg;
-
- if (mvolt >= 1600)
- cfg = AXP305_DCDC4_1600MV_OFFSET +
- axp305_mvolt_to_cfg(mvolt, 1600, 3300, 100);
- else
- cfg = axp305_mvolt_to_cfg(mvolt, 600, 1500, 20);
-
- if (mvolt == 0)
- return pmic_bus_clrbits(AXP305_OUTPUT_CTRL1,
- AXP305_OUTPUT_CTRL1_DCDCD_EN);
-
- ret = pmic_bus_write(AXP305_DCDCD_VOLTAGE, cfg);
- if (ret)
- return ret;
-
- return pmic_bus_setbits(AXP305_OUTPUT_CTRL1,
- AXP305_OUTPUT_CTRL1_DCDCD_EN);
-}
-
-int axp_init(void)
-{
- u8 axp_chip_id;
- int ret;
-
- ret = pmic_bus_init();
- if (ret)
- return ret;
-
- ret = pmic_bus_read(AXP305_CHIP_VERSION, &axp_chip_id);
- if (ret)
- return ret;
-
- if ((axp_chip_id & AXP305_CHIP_VERSION_MASK) != 0x40)
- return -ENODEV;
-
- return ret;
-}
-
-#if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
-int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- pmic_bus_write(AXP305_SHUTDOWN, AXP305_POWEROFF);
-
- /* infinite loop during shutdown */
- while (1) {}
-
- /* not reached */
- return 0;
-}
-#endif
diff --git a/drivers/power/axp313.c b/drivers/power/axp313.c
deleted file mode 100644
index 09ecb5b1ec2..00000000000
--- a/drivers/power/axp313.c
+++ /dev/null
@@ -1,133 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * AXP313(a) driver
- *
- * (C) Copyright 2023 Arm Ltd.
- *
- * Based on axp305.c
- * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
- * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com>
- * (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
- */
-
-#include <command.h>
-#include <errno.h>
-#include <asm/arch/pmic_bus.h>
-#include <axp_pmic.h>
-
-enum axp313_reg {
- AXP313_CHIP_VERSION = 0x03,
- AXP313_OUTPUT_CTRL = 0x10,
- AXP313_DCDC1_CTRL = 0x13,
- AXP313_SHUTDOWN = 0x1a,
-};
-
-#define AXP313_CHIP_VERSION_MASK 0xcf
-#define AXP313_CHIP_VERSION_AXP1530 0x48
-#define AXP313_CHIP_VERSION_AXP313A 0x4b
-#define AXP313_CHIP_VERSION_AXP313B 0x4c
-
-#define AXP313_DCDC_SPLIT_OFFSET 71
-#define AXP313_DCDC_SPLIT_MVOLT 1200
-
-#define AXP313_POWEROFF BIT(7)
-
-static u8 mvolt_to_cfg(int mvolt, int min, int max, int div)
-{
- if (mvolt < min)
- mvolt = min;
- else if (mvolt > max)
- mvolt = max;
-
- return (mvolt - min) / div;
-}
-
-static int axp_set_dcdc(int dcdc_num, unsigned int mvolt)
-{
- int ret;
- u8 cfg, enable_mask = 1U << (dcdc_num - 1);
- int volt_reg = AXP313_DCDC1_CTRL + dcdc_num - 1;
- int max_mV;
-
- switch (dcdc_num) {
- case 1:
- case 2:
- max_mV = 1540;
- break;
- case 3:
- /*
- * The manual defines a different split point, but tests
- * show that it's the same 1200mV as for DCDC1/2.
- */
- max_mV = 1840;
- break;
- default:
- return -EINVAL;
- }
-
- if (mvolt > AXP313_DCDC_SPLIT_MVOLT)
- cfg = AXP313_DCDC_SPLIT_OFFSET + mvolt_to_cfg(mvolt,
- AXP313_DCDC_SPLIT_MVOLT + 20, max_mV, 20);
- else
- cfg = mvolt_to_cfg(mvolt, 500, AXP313_DCDC_SPLIT_MVOLT, 10);
-
- if (mvolt == 0)
- return pmic_bus_clrbits(AXP313_OUTPUT_CTRL, enable_mask);
-
- debug("DCDC%d: writing 0x%x to reg 0x%x\n", dcdc_num, cfg, volt_reg);
- ret = pmic_bus_write(volt_reg, cfg);
- if (ret)
- return ret;
-
- return pmic_bus_setbits(AXP313_OUTPUT_CTRL, enable_mask);
-}
-
-int axp_set_dcdc2(unsigned int mvolt)
-{
- return axp_set_dcdc(2, mvolt);
-}
-
-int axp_set_dcdc3(unsigned int mvolt)
-{
- return axp_set_dcdc(3, mvolt);
-}
-
-int axp_init(void)
-{
- u8 axp_chip_id;
- int ret;
-
- ret = pmic_bus_init();
- if (ret)
- return ret;
-
- ret = pmic_bus_read(AXP313_CHIP_VERSION, &axp_chip_id);
- if (ret)
- return ret;
-
- axp_chip_id &= AXP313_CHIP_VERSION_MASK;
- switch (axp_chip_id) {
- case AXP313_CHIP_VERSION_AXP1530:
- case AXP313_CHIP_VERSION_AXP313A:
- case AXP313_CHIP_VERSION_AXP313B:
- break;
- default:
- debug("unknown PMIC: 0x%x\n", axp_chip_id);
- return -EINVAL;
- }
-
- return ret;
-}
-
-#if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
-int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
-{
- pmic_bus_write(AXP313_SHUTDOWN, AXP313_POWEROFF);
-
- /* infinite loop during shutdown */
- while (1) {}
-
- /* not reached */
- return 0;
-}
-#endif
diff --git a/drivers/power/axp_spl.c b/drivers/power/axp_spl.c
new file mode 100644
index 00000000000..3c86eb20ab4
--- /dev/null
+++ b/drivers/power/axp_spl.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * AXP PMIC SPL driver
+ * (C) Copyright 2024 Arm Ltd.
+ */
+
+#include <errno.h>
+#include <linux/types.h>
+#include <asm/arch/pmic_bus.h>
+#include <axp_pmic.h>
+
+struct axp_reg_desc_spl {
+ u8 enable_reg;
+ u8 enable_mask;
+ u8 volt_reg;
+ u8 volt_mask;
+ u16 min_mV;
+ u16 max_mV;
+ u8 step_mV;
+ u8 split;
+};
+
+#define NA 0xff
+
+#if defined(CONFIG_AXP717_POWER) /* AXP717 */
+
+static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
+ { 0x80, BIT(0), 0x83, 0x7f, 500, 1540, 10, 70 },
+ { 0x80, BIT(1), 0x84, 0x7f, 500, 1540, 10, 70 },
+ { 0x80, BIT(2), 0x85, 0x7f, 500, 1840, 10, 70 },
+};
+
+#define AXP_CHIP_VERSION 0x0
+#define AXP_CHIP_VERSION_MASK 0x0
+#define AXP_CHIP_ID 0x0
+#define AXP_SHUTDOWN_REG 0x27
+#define AXP_SHUTDOWN_MASK BIT(0)
+
+#elif defined(CONFIG_AXP313_POWER) /* AXP313 */
+
+static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
+ { 0x10, BIT(0), 0x13, 0x7f, 500, 1540, 10, 70 },
+ { 0x10, BIT(1), 0x14, 0x7f, 500, 1540, 10, 70 },
+ { 0x10, BIT(2), 0x15, 0x7f, 500, 1840, 10, 70 },
+};
+
+#define AXP_CHIP_VERSION 0x3
+#define AXP_CHIP_VERSION_MASK 0xc8
+#define AXP_CHIP_ID 0x48
+#define AXP_SHUTDOWN_REG 0x1a
+#define AXP_SHUTDOWN_MASK BIT(7)
+
+#elif defined(CONFIG_AXP305_POWER) /* AXP305 */
+
+static const struct axp_reg_desc_spl axp_spl_dcdc_regulators[] = {
+ { 0x10, BIT(0), 0x12, 0x7f, 600, 1520, 10, 50 },
+ { 0x10, BIT(1), 0x13, 0x1f, 1000, 2550, 50, NA },
+ { 0x10, BIT(2), 0x14, 0x7f, 600, 1520, 10, 50 },
+ { 0x10, BIT(3), 0x15, 0x3f, 600, 1500, 20, NA },
+ { 0x10, BIT(4), 0x16, 0x1f, 1100, 3400, 100, NA },
+};
+
+#define AXP_CHIP_VERSION 0x3
+#define AXP_CHIP_VERSION_MASK 0xcf
+#define AXP_CHIP_ID 0x40
+#define AXP_SHUTDOWN_REG 0x32
+#define AXP_SHUTDOWN_MASK BIT(7)
+
+#else
+
+ #error "Please define the regulator registers in axp_spl_regulators[]."
+
+#endif
+
+static u8 axp_mvolt_to_cfg(int mvolt, const struct axp_reg_desc_spl *reg)
+{
+ if (mvolt < reg->min_mV)
+ mvolt = reg->min_mV;
+ else if (mvolt > reg->max_mV)
+ mvolt = reg->max_mV;
+
+ mvolt -= reg->min_mV;
+
+ /* voltage in the first range ? */
+ if (mvolt <= reg->split * reg->step_mV)
+ return mvolt / reg->step_mV;
+
+ mvolt -= reg->split * reg->step_mV;
+
+ return reg->split + mvolt / (reg->step_mV * 2);
+}
+
+static int axp_set_dcdc(int dcdc_num, unsigned int mvolt)
+{
+ const struct axp_reg_desc_spl *reg;
+ int ret;
+
+ if (dcdc_num < 1 || dcdc_num > ARRAY_SIZE(axp_spl_dcdc_regulators))
+ return -EINVAL;
+
+ reg = &axp_spl_dcdc_regulators[dcdc_num - 1];
+
+ if (mvolt == 0)
+ return pmic_bus_clrbits(reg->enable_reg, reg->enable_mask);
+
+ ret = pmic_bus_write(reg->volt_reg, axp_mvolt_to_cfg(mvolt, reg));
+ if (ret)
+ return ret;
+
+ return pmic_bus_setbits(reg->enable_reg, reg->enable_mask);
+}
+
+int axp_set_dcdc1(unsigned int mvolt)
+{
+ return axp_set_dcdc(1, mvolt);
+}
+
+int axp_set_dcdc2(unsigned int mvolt)
+{
+ return axp_set_dcdc(2, mvolt);
+}
+
+int axp_set_dcdc3(unsigned int mvolt)
+{
+ return axp_set_dcdc(3, mvolt);
+}
+
+int axp_set_dcdc4(unsigned int mvolt)
+{
+ return axp_set_dcdc(4, mvolt);
+}
+
+int axp_set_dcdc5(unsigned int mvolt)
+{
+ return axp_set_dcdc(5, mvolt);
+}
+
+int axp_init(void)
+{
+ int ret = pmic_bus_init();
+
+ if (ret)
+ return ret;
+
+ if (AXP_CHIP_VERSION_MASK) {
+ u8 axp_chip_id;
+
+ ret = pmic_bus_read(AXP_CHIP_VERSION, &axp_chip_id);
+ if (ret)
+ return ret;
+
+ if ((axp_chip_id & AXP_CHIP_VERSION_MASK) != AXP_CHIP_ID) {
+ debug("unknown PMIC: 0x%x\n", axp_chip_id);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+#if !CONFIG_IS_ENABLED(ARM_PSCI_FW) && !IS_ENABLED(CONFIG_SYSRESET_CMD_POWEROFF)
+int do_poweroff(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+{
+ pmic_bus_setbits(AXP_SHUTDOWN_REG, AXP_SHUTDOWN_MASK);
+
+ /* infinite loop during shutdown */
+ while (1)
+ ;
+
+ /* not reached */
+ return 0;
+}
+#endif
diff --git a/drivers/power/pmic/axp.c b/drivers/power/pmic/axp.c
index 0e1e45fba74..521a39dd566 100644
--- a/drivers/power/pmic/axp.c
+++ b/drivers/power/pmic/axp.c
@@ -88,6 +88,7 @@ static const struct udevice_id axp_pmic_ids[] = {
{ .compatible = "x-powers,axp221", .data = AXP221_ID },
{ .compatible = "x-powers,axp223", .data = AXP223_ID },
{ .compatible = "x-powers,axp313a", .data = AXP313_ID },
+ { .compatible = "x-powers,axp717", .data = AXP717_ID },
{ .compatible = "x-powers,axp803", .data = AXP803_ID },
{ .compatible = "x-powers,axp806", .data = AXP806_ID },
{ .compatible = "x-powers,axp809", .data = AXP809_ID },
diff --git a/drivers/power/pmic/rk8xx.c b/drivers/power/pmic/rk8xx.c
index 617bb511e4e..4d5a5ceafad 100644
--- a/drivers/power/pmic/rk8xx.c
+++ b/drivers/power/pmic/rk8xx.c
@@ -281,6 +281,8 @@ static int rk8xx_probe(struct udevice *dev)
show_variant = bitfield_extract_by_mask(priv->variant, RK8XX_ID_MSK);
switch (priv->variant) {
case RK808_ID:
+ /* RK808 ID is 0x0000, so fix show_variant for that PMIC */
+ show_variant = 0x808;
break;
case RK805_ID:
case RK816_ID:
diff --git a/drivers/power/regulator/axp_regulator.c b/drivers/power/regulator/axp_regulator.c
index d27e09538e0..75cdbca30f6 100644
--- a/drivers/power/regulator/axp_regulator.c
+++ b/drivers/power/regulator/axp_regulator.c
@@ -189,6 +189,33 @@ static const struct axp_regulator_plat axp313_regulators[] = {
{ }
};
+/*
+ * The "dcdc2" regulator has another range, beyond 1.54V up to 3.4V, in
+ * steps of 100mV. We cannot model this easily, but also don't need that,
+ * since it's typically only used for lower voltages anyway, so just ignore it.
+ */
+static const struct axp_regulator_plat axp717_regulators[] = {
+ { "dcdc1", 0x80, BIT(0), 0x83, 0x7f, 500, 1540, 10, 70 },
+ { "dcdc2", 0x80, BIT(1), 0x84, 0x7f, 500, 1540, 10, 70 },
+ { "dcdc3", 0x80, BIT(2), 0x85, 0x7f, 500, 1840, 10, 70 },
+ { "dcdc4", 0x80, BIT(3), 0x86, 0x7f, 1000, 3700, 100, NA },
+ { "aldo1", 0x90, BIT(0), 0x93, 0x1f, 500, 3500, 100, NA },
+ { "aldo2", 0x90, BIT(1), 0x94, 0x1f, 500, 3500, 100, NA },
+ { "aldo3", 0x90, BIT(2), 0x95, 0x1f, 500, 3500, 100, NA },
+ { "aldo4", 0x90, BIT(3), 0x96, 0x1f, 500, 3500, 100, NA },
+ { "bldo1", 0x90, BIT(4), 0x97, 0x1f, 500, 3500, 100, NA },
+ { "bldo2", 0x90, BIT(5), 0x98, 0x1f, 500, 3500, 100, NA },
+ { "bldo3", 0x90, BIT(6), 0x99, 0x1f, 500, 3500, 100, NA },
+ { "bldo4", 0x90, BIT(7), 0x9a, 0x1f, 500, 3500, 100, NA },
+ { "cldo1", 0x91, BIT(0), 0x9b, 0x1f, 500, 3500, 100, NA },
+ { "cldo2", 0x91, BIT(1), 0x9c, 0x1f, 500, 3500, 100, NA },
+ { "cldo3", 0x91, BIT(2), 0x9d, 0x1f, 500, 3500, 100, NA },
+ { "cldo4", 0x91, BIT(3), 0x9e, 0x1f, 500, 3500, 100, NA },
+ {"cpusldo",0x91, BIT(4), 0x9f, 0x1f, 500, 1400, 50, NA },
+ {" boost", 0x19, BIT(4), 0x1e, 0xf0, 4550, 5510, 64, NA },
+ { }
+};
+
static const struct axp_regulator_plat axp803_regulators[] = {
{ "dcdc1", 0x10, BIT(0), 0x20, 0x1f, 1600, 3400, 100, NA },
{ "dcdc2", 0x10, BIT(1), 0x21, 0x7f, 500, 1300, 10, 70 },
@@ -291,6 +318,7 @@ static const struct axp_regulator_plat *const axp_regulators[] = {
[AXP221_ID] = axp22x_regulators,
[AXP223_ID] = axp22x_regulators,
[AXP313_ID] = axp313_regulators,
+ [AXP717_ID] = axp717_regulators,
[AXP803_ID] = axp803_regulators,
[AXP806_ID] = axp806_regulators,
[AXP809_ID] = axp809_regulators,
diff --git a/drivers/rng/smccc_trng.c b/drivers/rng/smccc_trng.c
index f59b80666b3..1da1affd8e8 100644
--- a/drivers/rng/smccc_trng.c
+++ b/drivers/rng/smccc_trng.c
@@ -135,10 +135,6 @@ static bool smccc_trng_is_supported(void (*invoke_fn)(unsigned long a0, unsigned
{
struct arm_smccc_res res;
- (*invoke_fn)(ARM_SMCCC_ARCH_FEATURES, ARM_SMCCC_TRNG_VERSION, 0, 0, 0, 0, 0, 0, &res);
- if (res.a0 == ARM_SMCCC_RET_NOT_SUPPORTED)
- return false;
-
(*invoke_fn)(ARM_SMCCC_TRNG_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
if (res.a0 & BIT(31))
return false;
diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c
index 3231eb0daf8..e63a2766c76 100644
--- a/drivers/rtc/goldfish_rtc.c
+++ b/drivers/rtc/goldfish_rtc.c
@@ -2,7 +2,9 @@
/*
* Copyright 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
*
- * This driver emulates a real time clock based on timer ticks.
+ * This driver supports the Google Goldfish virtual platform RTC device.
+ * The device is provided by the RISC-V virt machine in QEMU. It exposes
+ * a 64-bit nanosecond timer via two memory-mapped 32-bit registers.
*/
#include <div64.h>
diff --git a/drivers/spi/spi-sunxi.c b/drivers/spi/spi-sunxi.c
index 13725ee7a2d..a7333d8d9c0 100644
--- a/drivers/spi/spi-sunxi.c
+++ b/drivers/spi/spi-sunxi.c
@@ -135,7 +135,6 @@ struct sun4i_spi_variant {
struct sun4i_spi_plat {
struct sun4i_spi_variant *variant;
u32 base;
- u32 max_hz;
};
struct sun4i_spi_priv {
@@ -238,6 +237,13 @@ static void sun4i_spi_set_speed_mode(struct udevice *dev)
u32 reg;
/*
+ * The uclass should take care that this won't happen. But anyway,
+ * avoid a div-by-zero exception.
+ */
+ if (!priv->freq)
+ return;
+
+ /*
* Setup clock divider.
*
* We have two choices there. Either we can use the clock
@@ -401,11 +407,10 @@ static int sun4i_spi_xfer(struct udevice *dev, unsigned int bitlen,
static int sun4i_spi_set_speed(struct udevice *dev, uint speed)
{
- struct sun4i_spi_plat *plat = dev_get_plat(dev);
struct sun4i_spi_priv *priv = dev_get_priv(dev);
- if (speed > plat->max_hz)
- speed = plat->max_hz;
+ if (speed > SUN4I_SPI_MAX_RATE)
+ speed = SUN4I_SPI_MAX_RATE;
if (speed < SUN4I_SPI_MIN_RATE)
speed = SUN4I_SPI_MIN_RATE;
@@ -458,7 +463,6 @@ static int sun4i_spi_probe(struct udevice *bus)
priv->variant = plat->variant;
priv->base = plat->base;
- priv->freq = plat->max_hz;
return 0;
}
@@ -466,16 +470,9 @@ static int sun4i_spi_probe(struct udevice *bus)
static int sun4i_spi_of_to_plat(struct udevice *bus)
{
struct sun4i_spi_plat *plat = dev_get_plat(bus);
- int node = dev_of_offset(bus);
plat->base = dev_read_addr(bus);
plat->variant = (struct sun4i_spi_variant *)dev_get_driver_data(bus);
- plat->max_hz = fdtdec_get_int(gd->fdt_blob, node,
- "spi-max-frequency",
- SUN4I_SPI_DEFAULT_RATE);
-
- if (plat->max_hz > SUN4I_SPI_MAX_RATE)
- plat->max_hz = SUN4I_SPI_MAX_RATE;
return 0;
}
diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
index 8216c289837..06deb23eb99 100644
--- a/drivers/timer/mtk_timer.c
+++ b/drivers/timer/mtk_timer.c
@@ -73,7 +73,8 @@ static int mtk_timer_probe(struct udevice *dev)
return ret;
ret = clk_get_by_index(dev, 1, &parent);
- if (!ret) {
+ /* Skip setting the parent with dummy fixed-clock */
+ if (!ret && parent.dev->driver != DM_DRIVER_GET(fixed_clock)) {
ret = clk_set_parent(&clk, &parent);
if (ret)
return ret;
diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c
index b4e931646b8..cbe06a9e7b6 100644
--- a/drivers/usb/cdns3/core.c
+++ b/drivers/usb/cdns3/core.c
@@ -20,6 +20,7 @@
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/io.h>
+#include <linux/usb/gadget.h>
#include <usb.h>
#include <usb/xhci.h>
@@ -462,15 +463,38 @@ static int cdns3_gadget_remove(struct udevice *dev)
return cdns3_remove(cdns);
}
+static int cdns3_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct cdns3 *cdns = dev_get_priv(dev);
+
+ cdns3_gadget_uboot_handle_interrupt(cdns);
+
+ return 0;
+}
+
+static const struct usb_gadget_generic_ops cdns3_gadget_ops = {
+ .handle_interrupts = cdns3_gadget_handle_interrupts,
+};
+
U_BOOT_DRIVER(cdns_usb3_peripheral) = {
.name = "cdns-usb3-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
.of_match = cdns3_ids,
+ .ops = &cdns3_gadget_ops,
.probe = cdns3_gadget_probe,
.remove = cdns3_gadget_remove,
.priv_auto = sizeof(struct cdns3_gadget_priv),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
+#else
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct cdns3 *cdns = dev_get_priv(dev);
+
+ cdns3_gadget_uboot_handle_interrupt(cdns);
+
+ return 0;
+}
#endif
#if defined(CONFIG_SPL_USB_HOST) || \
diff --git a/drivers/usb/cdns3/gadget-export.h b/drivers/usb/cdns3/gadget-export.h
index 577469eee96..b3fd7c53039 100644
--- a/drivers/usb/cdns3/gadget-export.h
+++ b/drivers/usb/cdns3/gadget-export.h
@@ -25,4 +25,6 @@ static inline void cdns3_gadget_exit(struct cdns3 *cdns) { }
#endif
+void cdns3_gadget_uboot_handle_interrupt(struct cdns3 *cdns);
+
#endif /* __LINUX_CDNS3_GADGET_EXPORT */
diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c
index d11175dc5b6..32b2c412068 100644
--- a/drivers/usb/cdns3/gadget.c
+++ b/drivers/usb/cdns3/gadget.c
@@ -2755,19 +2755,10 @@ int cdns3_gadget_init(struct cdns3 *cdns)
*
* Handles ep0 and gadget interrupt
*/
-static void cdns3_gadget_uboot_handle_interrupt(struct cdns3 *cdns)
+void cdns3_gadget_uboot_handle_interrupt(struct cdns3 *cdns)
{
int ret = cdns3_device_irq_handler(0, cdns);
if (ret == IRQ_WAKE_THREAD)
cdns3_device_thread_irq_handler(0, cdns);
}
-
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct cdns3 *cdns = dev_get_priv(dev);
-
- cdns3_gadget_uboot_handle_interrupt(cdns);
-
- return 0;
-}
diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c
index 8db678eb85d..731ede2fead 100644
--- a/drivers/usb/dwc3/dwc3-generic.c
+++ b/drivers/usb/dwc3/dwc3-generic.c
@@ -194,34 +194,39 @@ static int dwc3_generic_of_to_plat(struct udevice *dev)
}
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+static int dwc3_generic_peripheral_probe(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
- struct dwc3 *dwc3 = &priv->dwc3;
- dwc3_gadget_uboot_handle_interrupt(dwc3);
-
- return 0;
+ return dwc3_generic_probe(dev, priv);
}
-static int dwc3_generic_peripheral_probe(struct udevice *dev)
+static int dwc3_generic_peripheral_remove(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
- return dwc3_generic_probe(dev, priv);
+ return dwc3_generic_remove(dev, priv);
}
-static int dwc3_generic_peripheral_remove(struct udevice *dev)
+static int dwc3_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
+ struct dwc3 *dwc3 = &priv->dwc3;
- return dwc3_generic_remove(dev, priv);
+ dwc3_gadget_uboot_handle_interrupt(dwc3);
+
+ return 0;
}
+static const struct usb_gadget_generic_ops dwc3_gadget_ops = {
+ .handle_interrupts = dwc3_gadget_handle_interrupts,
+};
+
U_BOOT_DRIVER(dwc3_generic_peripheral) = {
.name = "dwc3-generic-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
.of_to_plat = dwc3_generic_of_to_plat,
+ .ops = &dwc3_gadget_ops,
.probe = dwc3_generic_peripheral_probe,
.remove = dwc3_generic_peripheral_remove,
.priv_auto = sizeof(struct dwc3_generic_priv),
diff --git a/drivers/usb/dwc3/dwc3-layerscape.c b/drivers/usb/dwc3/dwc3-layerscape.c
index ff83bf71e89..108b44c67eb 100644
--- a/drivers/usb/dwc3/dwc3-layerscape.c
+++ b/drivers/usb/dwc3/dwc3-layerscape.c
@@ -99,33 +99,38 @@ static int dwc3_layerscape_of_to_plat(struct udevice *dev)
}
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+static int dwc3_layerscape_peripheral_probe(struct udevice *dev)
{
struct dwc3_layerscape_priv *priv = dev_get_priv(dev);
- dwc3_gadget_uboot_handle_interrupt(&priv->dwc3);
-
- return 0;
+ return dwc3_layerscape_probe(dev, priv);
}
-static int dwc3_layerscape_peripheral_probe(struct udevice *dev)
+static int dwc3_layerscape_peripheral_remove(struct udevice *dev)
{
struct dwc3_layerscape_priv *priv = dev_get_priv(dev);
- return dwc3_layerscape_probe(dev, priv);
+ return dwc3_layerscape_remove(dev, priv);
}
-static int dwc3_layerscape_peripheral_remove(struct udevice *dev)
+static int dwc3_layerscape_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3_layerscape_priv *priv = dev_get_priv(dev);
- return dwc3_layerscape_remove(dev, priv);
+ dwc3_gadget_uboot_handle_interrupt(&priv->dwc3);
+
+ return 0;
}
+static const struct usb_gadget_generic_ops dwc3_layerscape_gadget_ops = {
+ .handle_interrupts = dwc3_layerscape_gadget_handle_interrupts,
+};
+
U_BOOT_DRIVER(dwc3_layerscape_peripheral) = {
.name = "dwc3-layerscape-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
.of_to_plat = dwc3_layerscape_of_to_plat,
+ .ops = &dwc3_layerscape_gadget_ops,
.probe = dwc3_layerscape_peripheral_probe,
.remove = dwc3_layerscape_peripheral_remove,
.priv_auto = sizeof(struct dwc3_layerscape_priv),
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 92c7c6d08b7..8f08fda746d 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1606,6 +1606,38 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
return 0;
}
+static struct usb_ep *dwc3_find_ep(struct usb_gadget *gadget, const char *name)
+{
+ struct usb_ep *ep;
+
+ list_for_each_entry(ep, &gadget->ep_list, ep_list)
+ if (!strcmp(ep->name, name))
+ return ep;
+
+ return NULL;
+}
+
+static struct
+usb_ep *dwc3_gadget_match_ep(struct usb_gadget *gadget,
+ struct usb_endpoint_descriptor *desc,
+ struct usb_ss_ep_comp_descriptor *comp_desc)
+{
+ /*
+ * First try standard, common configuration: ep1in-bulk,
+ * ep2out-bulk, ep3in-int to match other udc drivers to avoid
+ * confusion in already deployed software (endpoint numbers
+ * hardcoded in userspace software/drivers)
+ */
+ if (usb_endpoint_is_bulk_in(desc))
+ return dwc3_find_ep(gadget, "ep1in");
+ if (usb_endpoint_is_bulk_out(desc))
+ return dwc3_find_ep(gadget, "ep2out");
+ if (usb_endpoint_is_int_in(desc))
+ return dwc3_find_ep(gadget, "ep3in");
+
+ return NULL;
+}
+
static const struct usb_gadget_ops dwc3_gadget_ops = {
.get_frame = dwc3_gadget_get_frame,
.wakeup = dwc3_gadget_wakeup,
@@ -1613,6 +1645,7 @@ static const struct usb_gadget_ops dwc3_gadget_ops = {
.pullup = dwc3_gadget_pullup,
.udc_start = dwc3_gadget_start,
.udc_stop = dwc3_gadget_stop,
+ .match_ep = dwc3_gadget_match_ep,
};
/* -------------------------------------------------------------------------- */
diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c
index 7bfd285b3aa..a0aa5c25e42 100644
--- a/drivers/usb/eth/asix88179.c
+++ b/drivers/usb/eth/asix88179.c
@@ -629,6 +629,12 @@ static int ax88179_eth_probe(struct udevice *dev)
usb_dev = priv->ueth.pusb_dev;
priv->maxpacketsize = usb_dev->epmaxpacketout[AX_ENDPOINT_OUT];
+ ret = asix_basic_reset(&priv->ueth, priv);
+ if (ret) {
+ printf("Failed to reset ethernet device\n");
+ return ret;
+ }
+
/* Get the MAC address */
ret = asix_read_mac(&priv->ueth, pdata->enetaddr);
if (ret)
diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index 6bd395a6235..7e9dd6f4268 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -941,11 +941,6 @@ int dwc2_udc_handle_interrupt(void)
return 0;
}
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- return dwc2_udc_handle_interrupt();
-}
-
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
struct dwc2_priv_data {
struct clk_bulk clks;
@@ -1173,6 +1168,15 @@ static int dwc2_udc_otg_remove(struct udevice *dev)
return dm_scan_fdt_dev(dev);
}
+static int dwc2_gadget_handle_interrupts(struct udevice *dev)
+{
+ return dwc2_udc_handle_interrupt();
+}
+
+static const struct usb_gadget_generic_ops dwc2_gadget_ops = {
+ .handle_interrupts = dwc2_gadget_handle_interrupts,
+};
+
static const struct udevice_id dwc2_udc_otg_ids[] = {
{ .compatible = "snps,dwc2" },
{ .compatible = "brcm,bcm2835-usb" },
@@ -1185,6 +1189,7 @@ U_BOOT_DRIVER(dwc2_udc_otg) = {
.name = "dwc2-udc-otg",
.id = UCLASS_USB_GADGET_GENERIC,
.of_match = dwc2_udc_otg_ids,
+ .ops = &dwc2_gadget_ops,
.of_to_plat = dwc2_udc_otg_of_to_plat,
.probe = dwc2_udc_otg_probe,
.remove = dwc2_udc_otg_remove,
@@ -1200,4 +1205,9 @@ int dwc2_udc_B_session_valid(struct udevice *dev)
return readl(&usbotg_reg->gotgctl) & B_SESSION_VALID;
}
+#else
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ return dwc2_udc_handle_interrupt();
+}
#endif /* CONFIG_IS_ENABLED(DM_USB_GADGET) */
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index 0a70035ce04..a4da4f72de9 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -12,7 +12,6 @@
#include <linux/errno.h>
#include <linux/usb/gadget.h>
#include <asm/unaligned.h>
-#include "gadget_chips.h"
#define isdigit(c) ('0' <= (c) && (c) <= '9')
@@ -167,18 +166,6 @@ static int ep_matches(
return 1;
}
-static struct usb_ep *
-find_ep(struct usb_gadget *gadget, const char *name)
-{
- struct usb_ep *ep;
-
- list_for_each_entry(ep, &gadget->ep_list, ep_list) {
- if (0 == strcmp(ep->name, name))
- return ep;
- }
- return NULL;
-}
-
/**
* usb_ep_autoconfig - choose an endpoint matching the descriptor
* @gadget: The device to which the endpoint must belong.
@@ -214,76 +201,14 @@ struct usb_ep *usb_ep_autoconfig(
struct usb_endpoint_descriptor *desc
)
{
- struct usb_ep *ep = NULL;
- u8 type;
-
- type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
-
- /* First, apply chip-specific "best usage" knowledge.
- * This might make a good usb_gadget_ops hook ...
- */
- if (gadget_is_net2280(gadget) && type == USB_ENDPOINT_XFER_INT) {
- /* ep-e, ep-f are PIO with only 64 byte fifos */
- ep = find_ep(gadget, "ep-e");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
- ep = find_ep(gadget, "ep-f");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
-
- } else if (gadget_is_goku(gadget)) {
- if (USB_ENDPOINT_XFER_INT == type) {
- /* single buffering is enough */
- ep = find_ep(gadget, "ep3-bulk");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
- } else if (USB_ENDPOINT_XFER_BULK == type
- && (USB_DIR_IN & desc->bEndpointAddress)) {
- /* DMA may be available */
- ep = find_ep(gadget, "ep2-bulk");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
- }
-
- } else if (gadget_is_sh(gadget) && USB_ENDPOINT_XFER_INT == type) {
- /* single buffering is enough; maybe 8 byte fifo is too */
- ep = find_ep(gadget, "ep3in-bulk");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
+ struct usb_ep *ep;
- } else if (gadget_is_mq11xx(gadget) && USB_ENDPOINT_XFER_INT == type) {
- ep = find_ep(gadget, "ep1-bulk");
- if (ep && ep_matches(gadget, ep, desc))
- return ep;
-#ifndef CONFIG_SPL_BUILD
- } else if (gadget_is_dwc3(gadget)) {
- const char *name = NULL;
- /*
- * First try standard, common configuration: ep1in-bulk,
- * ep2out-bulk, ep3in-int to match other udc drivers to avoid
- * confusion in already deployed software (endpoint numbers
- * hardcoded in userspace software/drivers)
- */
- if ((desc->bEndpointAddress & USB_DIR_IN) &&
- type == USB_ENDPOINT_XFER_BULK)
- name = "ep1in";
- else if ((desc->bEndpointAddress & USB_DIR_IN) == 0 &&
- type == USB_ENDPOINT_XFER_BULK)
- name = "ep2out";
- else if ((desc->bEndpointAddress & USB_DIR_IN) &&
- type == USB_ENDPOINT_XFER_INT)
- name = "ep3in";
-
- if (name)
- ep = find_ep(gadget, name);
+ if (gadget->ops->match_ep) {
+ ep = gadget->ops->match_ep(gadget, desc, NULL);
if (ep && ep_matches(gadget, ep, desc))
return ep;
-#endif
}
- if (gadget->ops->match_ep)
- ep = gadget->ops->match_ep(gadget, desc, NULL);
-
/* Second, look at endpoints until an unclaimed one looks usable */
list_for_each_entry(ep, &gadget->ep_list, ep_list) {
if (ep_matches(gadget, ep, desc))
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index b8b29d399b1..b7b7bacb00d 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -22,8 +22,8 @@
#include <malloc.h>
#include <memalign.h>
#include <linux/ctype.h>
+#include <version.h>
-#include "gadget_chips.h"
#include "rndis.h"
#include <dm.h>
@@ -1989,28 +1989,15 @@ static int eth_bind(struct usb_gadget *gadget)
* standard protocol is _strongly_ preferred for interop purposes.
* (By everyone except Microsoft.)
*/
- if (gadget_is_musbhdrc(gadget)) {
+
+ if (IS_ENABLED(CONFIG_USB_MUSB_GADGET) &&
+ !strcmp("musb-hdrc", gadget->name)) {
/* reduce tx dma overhead by avoiding special cases */
zlp = 0;
- } else if (gadget_is_sh(gadget)) {
- /* sh doesn't support multiple interfaces or configs */
- cdc = 0;
- rndis = 0;
}
- gcnum = usb_gadget_controller_number(gadget);
- if (gcnum >= 0)
- device_desc.bcdDevice = cpu_to_le16(0x0300 + gcnum);
- else {
- /*
- * can't assume CDC works. don't want to default to
- * anything less functional on CDC-capable hardware,
- * so we fail in this case.
- */
- pr_err("controller '%s' not recognized",
- gadget->name);
- return -ENODEV;
- }
+ gcnum = (U_BOOT_VERSION_NUM << 4) | U_BOOT_VERSION_NUM_PATCH;
+ device_desc.bcdDevice = cpu_to_le16(gcnum);
/*
* If there's an RNDIS configuration, that's what Windows wants to
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
index b5b5f5d8c11..631969b3405 100644
--- a/drivers/usb/gadget/g_dnl.c
+++ b/drivers/usb/gadget/g_dnl.c
@@ -17,10 +17,10 @@
#include <usb_mass_storage.h>
#include <dfu.h>
#include <thor.h>
+#include <version.h>
#include <env_callback.h>
-#include "gadget_chips.h"
#include "composite.c"
/*
@@ -199,18 +199,6 @@ void g_dnl_clear_detach(void)
g_dnl_detach_request = false;
}
-static int g_dnl_get_bcd_device_number(struct usb_composite_dev *cdev)
-{
- struct usb_gadget *gadget = cdev->gadget;
- int gcnum;
-
- gcnum = usb_gadget_controller_number(gadget);
- if (gcnum > 0)
- gcnum += 0x200;
-
- return g_dnl_get_board_bcd_device_number(gcnum);
-}
-
/**
* Update internal serial number variable when the "serial#" env var changes.
*
@@ -261,7 +249,8 @@ static int g_dnl_bind(struct usb_composite_dev *cdev)
if (ret)
goto error;
- gcnum = g_dnl_get_bcd_device_number(cdev);
+ gcnum = g_dnl_get_board_bcd_device_number((U_BOOT_VERSION_NUM << 4) |
+ U_BOOT_VERSION_NUM_PATCH);
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(gcnum);
else {
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
deleted file mode 100644
index 98156c312d2..00000000000
--- a/drivers/usb/gadget/gadget_chips.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * USB device controllers have lots of quirks. Use these macros in
- * gadget drivers or other code that needs to deal with them, and which
- * autoconfigures instead of using early binding to the hardware.
- *
- * This SHOULD eventually work like the ARM mach_is_*() stuff, driven by
- * some config file that gets updated as new hardware is supported.
- * (And avoiding all runtime comparisons in typical one-choice configs!)
- *
- * NOTE: some of these controller drivers may not be available yet.
- * Some are available on 2.4 kernels; several are available, but not
- * yet pushed in the 2.6 mainline tree.
- *
- * Ported to U-Boot by: Thomas Smits <ts.smits@gmail.com> and
- * Remy Bohmer <linux@bohmer.net>
- */
-#ifdef CONFIG_USB_GADGET_NET2280
-#define gadget_is_net2280(g) (!strcmp("net2280", (g)->name))
-#else
-#define gadget_is_net2280(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_AMD5536UDC
-#define gadget_is_amd5536udc(g) (!strcmp("amd5536udc", (g)->name))
-#else
-#define gadget_is_amd5536udc(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_DUMMY_HCD
-#define gadget_is_dummy(g) (!strcmp("dummy_udc", (g)->name))
-#else
-#define gadget_is_dummy(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_GOKU
-#define gadget_is_goku(g) (!strcmp("goku_udc", (g)->name))
-#else
-#define gadget_is_goku(g) 0
-#endif
-
-/* SH3 UDC -- not yet ported 2.4 --> 2.6 */
-#ifdef CONFIG_USB_GADGET_SUPERH
-#define gadget_is_sh(g) (!strcmp("sh_udc", (g)->name))
-#else
-#define gadget_is_sh(g) 0
-#endif
-
-/* handhelds.org tree (?) */
-#ifdef CONFIG_USB_GADGET_MQ11XX
-#define gadget_is_mq11xx(g) (!strcmp("mq11xx_udc", (g)->name))
-#else
-#define gadget_is_mq11xx(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_OMAP
-#define gadget_is_omap(g) (!strcmp("omap_udc", (g)->name))
-#else
-#define gadget_is_omap(g) 0
-#endif
-
-/* not yet ported 2.4 --> 2.6 */
-#ifdef CONFIG_USB_GADGET_N9604
-#define gadget_is_n9604(g) (!strcmp("n9604_udc", (g)->name))
-#else
-#define gadget_is_n9604(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_ATMEL_USBA
-#define gadget_is_atmel_usba(g) (!strcmp("atmel_usba_udc", (g)->name))
-#else
-#define gadget_is_atmel_usba(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_AT91
-#define gadget_is_at91(g) (!strcmp("at91_udc", (g)->name))
-#else
-#define gadget_is_at91(g) 0
-#endif
-
-/* status unclear */
-#ifdef CONFIG_USB_GADGET_IMX
-#define gadget_is_imx(g) (!strcmp("imx_udc", (g)->name))
-#else
-#define gadget_is_imx(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_FSL_USB2
-#define gadget_is_fsl_usb2(g) (!strcmp("fsl-usb2-udc", (g)->name))
-#else
-#define gadget_is_fsl_usb2(g) 0
-#endif
-
-/* Mentor high speed function controller */
-/* from Montavista kernel (?) */
-#ifdef CONFIG_USB_GADGET_MUSBHSFC
-#define gadget_is_musbhsfc(g) (!strcmp("musbhsfc_udc", (g)->name))
-#else
-#define gadget_is_musbhsfc(g) 0
-#endif
-
-/* Mentor high speed "dual role" controller, in peripheral role */
-#ifdef CONFIG_USB_MUSB_GADGET
-#define gadget_is_musbhdrc(g) (!strcmp("musb-hdrc", (g)->name))
-#else
-#define gadget_is_musbhdrc(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_M66592
-#define gadget_is_m66592(g) (!strcmp("m66592_udc", (g)->name))
-#else
-#define gadget_is_m66592(g) 0
-#endif
-
-#ifdef CONFIG_CI_UDC
-#define gadget_is_ci(g) (!strcmp("ci_udc", (g)->name))
-#else
-#define gadget_is_ci(g) 0
-#endif
-
-#ifdef CONFIG_USB_DWC3_GADGET
-#define gadget_is_dwc3(g) (!strcmp("dwc3-gadget", (g)->name))
-#else
-#define gadget_is_dwc3(g) 0
-#endif
-
-#ifdef CONFIG_USB_CDNS3_GADGET
-#define gadget_is_cdns3(g) (!strcmp("cdns3-gadget", (g)->name))
-#else
-#define gadget_is_cdns3(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_MAX3420
-#define gadget_is_max3420(g) (!strcmp("max3420-udc", (g)->name))
-#else
-#define gadget_is_max3420(g) 0
-#endif
-
-#ifdef CONFIG_USB_MTU3_GADGET
-#define gadget_is_mtu3(g) (!strcmp("mtu3-gadget", (g)->name))
-#else
-#define gadget_is_mtu3(g) 0
-#endif
-
-#ifdef CONFIG_USB_GADGET_DWC2_OTG
-#define gadget_is_dwc2(g) (!strcmp("dwc2-udc", (g)->name))
-#else
-#define gadget_is_dwc2(g) 0
-#endif
-
-/**
- * usb_gadget_controller_number - support bcdDevice id convention
- * @gadget: the controller being driven
- *
- * Return a 2-digit BCD value associated with the peripheral controller,
- * suitable for use as part of a bcdDevice value, or a negative error code.
- *
- * NOTE: this convention is purely optional, and has no meaning in terms of
- * any USB specification. If you want to use a different convention in your
- * gadget driver firmware -- maybe a more formal revision ID -- feel free.
- *
- * Hosts see these bcdDevice numbers, and are allowed (but not encouraged!)
- * to change their behavior accordingly. For example it might help avoiding
- * some chip bug.
- */
-static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
-{
- if (gadget_is_net2280(gadget))
- return 0x01;
- else if (gadget_is_dummy(gadget))
- return 0x02;
- else if (gadget_is_sh(gadget))
- return 0x04;
- else if (gadget_is_goku(gadget))
- return 0x06;
- else if (gadget_is_mq11xx(gadget))
- return 0x07;
- else if (gadget_is_omap(gadget))
- return 0x08;
- else if (gadget_is_n9604(gadget))
- return 0x09;
- else if (gadget_is_at91(gadget))
- return 0x12;
- else if (gadget_is_imx(gadget))
- return 0x13;
- else if (gadget_is_musbhsfc(gadget))
- return 0x14;
- else if (gadget_is_musbhdrc(gadget))
- return 0x15;
- else if (gadget_is_atmel_usba(gadget))
- return 0x17;
- else if (gadget_is_fsl_usb2(gadget))
- return 0x18;
- else if (gadget_is_amd5536udc(gadget))
- return 0x19;
- else if (gadget_is_m66592(gadget))
- return 0x20;
- else if (gadget_is_ci(gadget))
- return 0x21;
- else if (gadget_is_dwc3(gadget))
- return 0x23;
- else if (gadget_is_cdns3(gadget))
- return 0x24;
- else if (gadget_is_max3420(gadget))
- return 0x25;
- else if (gadget_is_mtu3(gadget))
- return 0x26;
- else if (gadget_is_dwc2(gadget))
- return 0x27;
- return -ENOENT;
-}
diff --git a/drivers/usb/gadget/max3420_udc.c b/drivers/usb/gadget/max3420_udc.c
index 5a227c0ffd9..557a1f0644e 100644
--- a/drivers/usb/gadget/max3420_udc.c
+++ b/drivers/usb/gadget/max3420_udc.c
@@ -808,13 +808,6 @@ static void max3420_setup_spi(struct max3420_udc *udc)
spi_wr8(udc, MAX3420_REG_PINCTL, bFDUPSPI);
}
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct max3420_udc *udc = dev_get_priv(dev);
-
- return max3420_irq(udc);
-}
-
static int max3420_udc_probe(struct udevice *dev)
{
struct max3420_udc *udc = dev_get_priv(dev);
@@ -859,6 +852,17 @@ static int max3420_udc_remove(struct udevice *dev)
return 0;
}
+static int max3420_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct max3420_udc *udc = dev_get_priv(dev);
+
+ return max3420_irq(udc);
+}
+
+static const struct usb_gadget_generic_ops max3420_gadget_ops = {
+ .handle_interrupts = max3420_gadget_handle_interrupts,
+};
+
static const struct udevice_id max3420_ids[] = {
{ .compatible = "maxim,max3421-udc" },
{ }
@@ -868,6 +872,7 @@ U_BOOT_DRIVER(max3420_generic_udc) = {
.name = "max3420-udc",
.id = UCLASS_USB_GADGET_GENERIC,
.of_match = max3420_ids,
+ .ops = &max3420_gadget_ops,
.probe = max3420_udc_probe,
.remove = max3420_udc_remove,
.priv_auto = sizeof(struct max3420_udc),
diff --git a/drivers/usb/gadget/udc/udc-uclass.c b/drivers/usb/gadget/udc/udc-uclass.c
index 5dc23a55bb5..fbe62bbce47 100644
--- a/drivers/usb/gadget/udc/udc-uclass.c
+++ b/drivers/usb/gadget/udc/udc-uclass.c
@@ -12,6 +12,25 @@
#include <linux/usb/gadget.h>
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
+static inline const struct usb_gadget_generic_ops *
+usb_gadget_generic_dev_ops(struct udevice *dev)
+{
+ return (const struct usb_gadget_generic_ops *)dev->driver->ops;
+}
+
+int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ const struct usb_gadget_generic_ops *ops;
+
+ ops = usb_gadget_generic_dev_ops(dev);
+ if (!ops)
+ return -EFAULT;
+ if (!ops->handle_interrupts)
+ return -ENOSYS;
+
+ return ops->handle_interrupts(dev);
+}
+
int udc_device_get_by_index(int index, struct udevice **udev)
{
struct udevice *dev = NULL;
@@ -54,6 +73,11 @@ int udc_device_put(struct udevice *udev)
{
return board_usb_cleanup(legacy_index, USB_INIT_DEVICE);
}
+
+__weak int dm_usb_gadget_handle_interrupts(struct udevice *dev)
+{
+ return 0;
+}
#endif
#if CONFIG_IS_ENABLED(DM)
diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c
index e26f0b292ed..f687fe2c430 100644
--- a/drivers/usb/host/usb-sandbox.c
+++ b/drivers/usb/host/usb-sandbox.c
@@ -123,12 +123,7 @@ static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev,
return ret;
}
-#if CONFIG_IS_ENABLED(DM_USB_GADGET)
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- return 0;
-}
-#else
+#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
int usb_gadget_register_driver(struct usb_gadget_driver *driver)
{
struct sandbox_udc *dev = this_controller;
diff --git a/drivers/usb/mtu3/mtu3_plat.c b/drivers/usb/mtu3/mtu3_plat.c
index ca86b58dfcd..f8e14eabfb2 100644
--- a/drivers/usb/mtu3/mtu3_plat.c
+++ b/drivers/usb/mtu3/mtu3_plat.c
@@ -223,15 +223,6 @@ static const struct udevice_id ssusb_of_match[] = {
};
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct mtu3 *mtu = dev_get_priv(dev);
-
- mtu3_irq(0, mtu);
-
- return 0;
-}
-
static int mtu3_gadget_probe(struct udevice *dev)
{
struct ssusb_mtk *ssusb = dev_to_ssusb(dev->parent);
@@ -250,10 +241,24 @@ static int mtu3_gadget_remove(struct udevice *dev)
return 0;
}
+static int mtu3_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct mtu3 *mtu = dev_get_priv(dev);
+
+ mtu3_irq(0, mtu);
+
+ return 0;
+}
+
+static const struct usb_gadget_generic_ops mtu3_gadget_ops = {
+ .handle_interrupts = mtu3_gadget_handle_interrupts,
+};
+
U_BOOT_DRIVER(mtu3_peripheral) = {
.name = "mtu3-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
.of_match = ssusb_of_match,
+ .ops = &mtu3_gadget_ops,
.probe = mtu3_gadget_probe,
.remove = mtu3_gadget_remove,
.priv_auto = sizeof(struct mtu3),
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index c8dd73050b2..96771c28cef 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -46,16 +46,6 @@ static inline void omap2430_low_level_init(struct musb *musb)
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
}
-#ifdef CONFIG_DM_USB_GADGET
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct musb_host_data *host = dev_get_priv(dev);
-
- host->host->isr(0, host->host);
- return 0;
-}
-#endif
-
static int omap2430_musb_init(struct musb *musb)
{
u32 l;
@@ -273,6 +263,21 @@ static int omap2430_musb_remove(struct udevice *dev)
return 0;
}
+#ifndef CONFIG_USB_MUSB_HOST
+static int omap2340_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+
+ host->host->isr(0, host->host);
+
+ return 0;
+}
+
+static const struct usb_gadget_generic_ops omap2340_gadget_ops = {
+ .handle_interrupts = omap2340_gadget_handle_interrupts,
+};
+#endif
+
static const struct udevice_id omap2430_musb_ids[] = {
{ .compatible = "ti,omap3-musb" },
{ .compatible = "ti,omap4-musb" },
@@ -285,6 +290,7 @@ U_BOOT_DRIVER(omap2430_musb) = {
.id = UCLASS_USB,
#else
.id = UCLASS_USB_GADGET_GENERIC,
+ .ops = &omap2340_gadget_ops,
#endif
.of_match = omap2430_musb_ids,
.of_to_plat = omap2430_musb_of_to_plat,
diff --git a/drivers/usb/musb-new/ti-musb.c b/drivers/usb/musb-new/ti-musb.c
index 76e8b88369e..ec1baa9337d 100644
--- a/drivers/usb/musb-new/ti-musb.c
+++ b/drivers/usb/musb-new/ti-musb.c
@@ -233,15 +233,6 @@ static int ti_musb_peripheral_of_to_plat(struct udevice *dev)
}
#endif
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct ti_musb_peripheral *priv = dev_get_priv(dev);
-
- priv->periph->isr(0, priv->periph);
-
- return 0;
-}
-
static int ti_musb_peripheral_probe(struct udevice *dev)
{
struct ti_musb_peripheral *priv = dev_get_priv(dev);
@@ -269,12 +260,26 @@ static int ti_musb_peripheral_remove(struct udevice *dev)
return 0;
}
+static int ti_musb_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct ti_musb_peripheral *priv = dev_get_priv(dev);
+
+ priv->periph->isr(0, priv->periph);
+
+ return 0;
+}
+
+static const struct usb_gadget_generic_ops ti_musb_gadget_ops = {
+ .handle_interrupts = ti_musb_gadget_handle_interrupts,
+};
+
U_BOOT_DRIVER(ti_musb_peripheral) = {
.name = "ti-musb-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
#if CONFIG_IS_ENABLED(OF_CONTROL)
.of_to_plat = ti_musb_peripheral_of_to_plat,
#endif
+ .ops = &ti_musb_gadget_ops,
.probe = ti_musb_peripheral_probe,
.remove = ti_musb_peripheral_remove,
.ops = &musb_usb_ops,
diff --git a/drivers/usb/musb-new/ux500.c b/drivers/usb/musb-new/ux500.c
index 6b4ef3c8578..89dd75b7d05 100644
--- a/drivers/usb/musb-new/ux500.c
+++ b/drivers/usb/musb-new/ux500.c
@@ -91,14 +91,6 @@ static const struct musb_platform_ops ux500_musb_ops = {
.disable = ux500_musb_disable,
};
-int dm_usb_gadget_handle_interrupts(struct udevice *dev)
-{
- struct ux500_glue *glue = dev_get_priv(dev);
-
- glue->mdata.host->isr(0, glue->mdata.host);
- return 0;
-}
-
static int ux500_musb_probe(struct udevice *dev)
{
#ifdef CONFIG_USB_MUSB_HOST
@@ -155,6 +147,19 @@ static int ux500_musb_remove(struct udevice *dev)
return 0;
}
+static int ux500_gadget_handle_interrupts(struct udevice *dev)
+{
+ struct ux500_glue *glue = dev_get_priv(dev);
+
+ glue->mdata.host->isr(0, glue->mdata.host);
+
+ return 0;
+}
+
+static const struct usb_gadget_generic_ops ux500_gadget_ops = {
+ .handle_interrupts = ux500_gadget_handle_interrupts,
+};
+
static const struct udevice_id ux500_musb_ids[] = {
{ .compatible = "stericsson,db8500-musb" },
{ }
@@ -168,6 +173,7 @@ U_BOOT_DRIVER(ux500_musb) = {
.id = UCLASS_USB_GADGET_GENERIC,
#endif
.of_match = ux500_musb_ids,
+ .ops = &ux500_gadget_ops,
.probe = ux500_musb_probe,
.remove = ux500_musb_remove,
#ifdef CONFIG_USB_MUSB_HOST