Loading Documentation/devicetree/bindings/usb/msm-dbm.txt +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Required properties : - compatible : should be "qcom,usb-dbm-<dbm version number>" - reg : offset and length of the register set in the memory map. Optional properties : - qcom,reset-ep-after-lpm-resume: If present, dbm requires ep reset after going to lpm Example MSM DBM (Device Bus Manager) device node : dbm_1p4: dbm@f92f8000 { compatible = "qcom,usb-dbm-1p4"; Loading drivers/usb/dwc3/dbm-1_4.c +12 −5 Original line number Diff line number Diff line /* * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -147,7 +147,7 @@ static int soft_reset(bool reset) * @enter_reset - should we enter a reset state or get out of it. * */ static int dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset) static int ep_soft_reset(u8 dbm_ep, bool enter_reset) { pr_debug("%s\n", __func__); Loading Loading @@ -196,7 +196,7 @@ static int ep_config(u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, } /* First, reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, 0); ep_soft_reset(dbm_ep, 0); /* Set ioc bit for dbm_ep if needed */ msm_dbm_write_reg_field(dbm_data->base, DBM_DBG_CNFG, Loading Loading @@ -248,13 +248,13 @@ static int ep_unconfig(u8 usb_ep) msm_dbm_write_reg(dbm_data->base, DBM_EP_CFG(dbm_ep), data); /* Reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, true); ep_soft_reset(dbm_ep, true); /* * 10 usec delay is required before deasserting DBM endpoint reset * according to hardware programming guide. */ udelay(10); dbm_ep_soft_reset(dbm_ep, false); ep_soft_reset(dbm_ep, false); return 0; } Loading Loading @@ -336,6 +336,11 @@ static void set_speed(bool speed) msm_dbm_write_reg(dbm_data->base, DBM_GEN_CFG, speed >> 2); } static bool reset_ep_after_lpm(void) { return false; } static void enable(void) {} Loading Loading @@ -384,6 +389,8 @@ static int msm_dbm_probe(struct platform_device *pdev) dbm->data_fifo_config = data_fifo_config; dbm->set_speed = set_speed; dbm->enable = enable; dbm->ep_soft_reset = ep_soft_reset; dbm->reset_ep_after_lpm = reset_ep_after_lpm; platform_set_drvdata(pdev, dbm); Loading drivers/usb/dwc3/dbm-1_5.c +19 −5 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct dbm_data { int dbm_num_eps; u8 ep_num_mapping[DBM_1_5_NUM_EP]; bool dbm_reset_ep_after_lpm; }; static struct dbm_data *dbm_data; Loading Loading @@ -147,12 +148,12 @@ static int soft_reset(bool reset) * @enter_reset - should we enter a reset state or get out of it. * */ static int dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset) static int ep_soft_reset(u8 dbm_ep, bool enter_reset) { pr_debug("%s\n", __func__); if (dbm_ep >= dbm_data->dbm_num_eps) { pr_err("%s: Invalid DBM ep index\n", __func__); pr_err("Invalid DBM ep index %d\n", dbm_ep); return -ENODEV; } Loading Loading @@ -202,7 +203,7 @@ static int ep_config(u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, } /* First, reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, 0); ep_soft_reset(dbm_ep, 0); /* Set ioc bit for dbm_ep if needed */ msm_dbm_write_reg_field(dbm_data->base, DBM_DBG_CNFG, Loading Loading @@ -254,13 +255,13 @@ static int ep_unconfig(u8 usb_ep) msm_dbm_write_reg(dbm_data->base, DBM_EP_CFG(dbm_ep), data); /* Reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, true); ep_soft_reset(dbm_ep, true); /* * 10 usec delay is required before deasserting DBM endpoint reset * according to hardware programming guide. */ udelay(10); dbm_ep_soft_reset(dbm_ep, false); ep_soft_reset(dbm_ep, false); return 0; } Loading Loading @@ -339,9 +340,17 @@ static void enable(void) msm_dbm_write_reg(dbm_data->base, DBM_DATA_FIFO_SIZE_EN, 0x000000FF); } static bool reset_ep_after_lpm(void) { return dbm_data->dbm_reset_ep_after_lpm; } static int msm_dbm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = pdev->dev.of_node; struct dbm *dbm; struct resource *res; int ret = 0; Loading Loading @@ -374,6 +383,9 @@ static int msm_dbm_probe(struct platform_device *pdev) goto free_dbm_data; } dbm_data->dbm_reset_ep_after_lpm = of_property_read_bool(node, "qcom,reset-ep-after-lpm-resume"); dbm->dev = dev; dbm->soft_reset = soft_reset; Loading @@ -384,6 +396,8 @@ static int msm_dbm_probe(struct platform_device *pdev) dbm->data_fifo_config = data_fifo_config; dbm->set_speed = set_speed; dbm->enable = enable; dbm->ep_soft_reset = ep_soft_reset; dbm->reset_ep_after_lpm = reset_ep_after_lpm; platform_set_drvdata(pdev, dbm); Loading drivers/usb/dwc3/dbm.h +40 −13 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -84,6 +84,12 @@ struct dbm { /* Enable DBM */ void (*enable)(void); /* Reset a USB DBM ep */ int (*ep_soft_reset)(u8 dbm_ep, bool enter_reset); /* Check whether the USB DBM requires ep reset after lpm suspend */ bool (*reset_ep_after_lpm)(void); }; struct dbm *usb_get_dbm_by_phandle(struct device *dev, Loading @@ -92,23 +98,30 @@ int usb_add_dbm(struct dbm *x); #define CHECK_DBM_PTR_INT(dbm) do { \ if (!(dbm)) { \ #define CHECK_DBM_PTR_INT(dbm, func) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return -EPERM; \ } \ } while (0) #define CHECK_DBM_PTR_VOID(dbm) do { \ if (!(dbm)) { \ #define CHECK_DBM_PTR_VOID(dbm, func) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return; \ } \ } while (0) #define CHECK_DBM_PTR_BOOL(dbm, func, ret) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return ret; \ } \ } while (0) static inline int dbm_soft_reset(struct dbm *dbm, bool enter_reset) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, soft_reset); return dbm->soft_reset(enter_reset); } Loading @@ -116,7 +129,7 @@ static inline int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, bool internal_mem, bool ioc) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, ep_config); return dbm->ep_config(usb_ep, bam_pipe, producer, disable_wb, internal_mem, ioc); Loading @@ -124,41 +137,55 @@ static inline int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, static inline int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, ep_unconfig); return dbm->ep_unconfig(usb_ep); } static inline int dbm_get_num_of_eps_configured(struct dbm *dbm) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, get_num_of_eps_configured); return dbm->get_num_of_eps_configured(); } static inline int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi, int size) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, event_buffer_config); return dbm->event_buffer_config(addr_lo, addr_hi, size); } static inline int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, phys_addr_t addr, u32 size, u8 dst_pipe_idx) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, data_fifo_config); return dbm->data_fifo_config(dep_num, addr, size, dst_pipe_idx); } static inline void dbm_set_speed(struct dbm *dbm, bool speed) { CHECK_DBM_PTR_VOID(dbm); CHECK_DBM_PTR_VOID(dbm, set_speed); dbm->set_speed(speed); } static inline void dbm_enable(struct dbm *dbm) { CHECK_DBM_PTR_VOID(dbm); CHECK_DBM_PTR_VOID(dbm, enable); dbm->enable(); } static inline int dbm_ep_soft_reset(struct dbm *dbm, u8 dbm_ep, bool enter_reset) { CHECK_DBM_PTR_INT(dbm, ep_soft_reset); return dbm->ep_soft_reset(dbm_ep, enter_reset); } static inline bool dbm_reset_ep_after_lpm(struct dbm *dbm) { /* Default (backward compatible) setting is false */ CHECK_DBM_PTR_BOOL(dbm, reset_ep_after_lpm, false); return dbm->reset_ep_after_lpm(); } #endif /* __DBM_H */ Loading
Documentation/devicetree/bindings/usb/msm-dbm.txt +4 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,10 @@ Required properties : - compatible : should be "qcom,usb-dbm-<dbm version number>" - reg : offset and length of the register set in the memory map. Optional properties : - qcom,reset-ep-after-lpm-resume: If present, dbm requires ep reset after going to lpm Example MSM DBM (Device Bus Manager) device node : dbm_1p4: dbm@f92f8000 { compatible = "qcom,usb-dbm-1p4"; Loading
drivers/usb/dwc3/dbm-1_4.c +12 −5 Original line number Diff line number Diff line /* * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -147,7 +147,7 @@ static int soft_reset(bool reset) * @enter_reset - should we enter a reset state or get out of it. * */ static int dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset) static int ep_soft_reset(u8 dbm_ep, bool enter_reset) { pr_debug("%s\n", __func__); Loading Loading @@ -196,7 +196,7 @@ static int ep_config(u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, } /* First, reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, 0); ep_soft_reset(dbm_ep, 0); /* Set ioc bit for dbm_ep if needed */ msm_dbm_write_reg_field(dbm_data->base, DBM_DBG_CNFG, Loading Loading @@ -248,13 +248,13 @@ static int ep_unconfig(u8 usb_ep) msm_dbm_write_reg(dbm_data->base, DBM_EP_CFG(dbm_ep), data); /* Reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, true); ep_soft_reset(dbm_ep, true); /* * 10 usec delay is required before deasserting DBM endpoint reset * according to hardware programming guide. */ udelay(10); dbm_ep_soft_reset(dbm_ep, false); ep_soft_reset(dbm_ep, false); return 0; } Loading Loading @@ -336,6 +336,11 @@ static void set_speed(bool speed) msm_dbm_write_reg(dbm_data->base, DBM_GEN_CFG, speed >> 2); } static bool reset_ep_after_lpm(void) { return false; } static void enable(void) {} Loading Loading @@ -384,6 +389,8 @@ static int msm_dbm_probe(struct platform_device *pdev) dbm->data_fifo_config = data_fifo_config; dbm->set_speed = set_speed; dbm->enable = enable; dbm->ep_soft_reset = ep_soft_reset; dbm->reset_ep_after_lpm = reset_ep_after_lpm; platform_set_drvdata(pdev, dbm); Loading
drivers/usb/dwc3/dbm-1_5.c +19 −5 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct dbm_data { int dbm_num_eps; u8 ep_num_mapping[DBM_1_5_NUM_EP]; bool dbm_reset_ep_after_lpm; }; static struct dbm_data *dbm_data; Loading Loading @@ -147,12 +148,12 @@ static int soft_reset(bool reset) * @enter_reset - should we enter a reset state or get out of it. * */ static int dbm_ep_soft_reset(u8 dbm_ep, bool enter_reset) static int ep_soft_reset(u8 dbm_ep, bool enter_reset) { pr_debug("%s\n", __func__); if (dbm_ep >= dbm_data->dbm_num_eps) { pr_err("%s: Invalid DBM ep index\n", __func__); pr_err("Invalid DBM ep index %d\n", dbm_ep); return -ENODEV; } Loading Loading @@ -202,7 +203,7 @@ static int ep_config(u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, } /* First, reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, 0); ep_soft_reset(dbm_ep, 0); /* Set ioc bit for dbm_ep if needed */ msm_dbm_write_reg_field(dbm_data->base, DBM_DBG_CNFG, Loading Loading @@ -254,13 +255,13 @@ static int ep_unconfig(u8 usb_ep) msm_dbm_write_reg(dbm_data->base, DBM_EP_CFG(dbm_ep), data); /* Reset the dbm endpoint */ dbm_ep_soft_reset(dbm_ep, true); ep_soft_reset(dbm_ep, true); /* * 10 usec delay is required before deasserting DBM endpoint reset * according to hardware programming guide. */ udelay(10); dbm_ep_soft_reset(dbm_ep, false); ep_soft_reset(dbm_ep, false); return 0; } Loading Loading @@ -339,9 +340,17 @@ static void enable(void) msm_dbm_write_reg(dbm_data->base, DBM_DATA_FIFO_SIZE_EN, 0x000000FF); } static bool reset_ep_after_lpm(void) { return dbm_data->dbm_reset_ep_after_lpm; } static int msm_dbm_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = pdev->dev.of_node; struct dbm *dbm; struct resource *res; int ret = 0; Loading Loading @@ -374,6 +383,9 @@ static int msm_dbm_probe(struct platform_device *pdev) goto free_dbm_data; } dbm_data->dbm_reset_ep_after_lpm = of_property_read_bool(node, "qcom,reset-ep-after-lpm-resume"); dbm->dev = dev; dbm->soft_reset = soft_reset; Loading @@ -384,6 +396,8 @@ static int msm_dbm_probe(struct platform_device *pdev) dbm->data_fifo_config = data_fifo_config; dbm->set_speed = set_speed; dbm->enable = enable; dbm->ep_soft_reset = ep_soft_reset; dbm->reset_ep_after_lpm = reset_ep_after_lpm; platform_set_drvdata(pdev, dbm); Loading
drivers/usb/dwc3/dbm.h +40 −13 Original line number Diff line number Diff line /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -84,6 +84,12 @@ struct dbm { /* Enable DBM */ void (*enable)(void); /* Reset a USB DBM ep */ int (*ep_soft_reset)(u8 dbm_ep, bool enter_reset); /* Check whether the USB DBM requires ep reset after lpm suspend */ bool (*reset_ep_after_lpm)(void); }; struct dbm *usb_get_dbm_by_phandle(struct device *dev, Loading @@ -92,23 +98,30 @@ int usb_add_dbm(struct dbm *x); #define CHECK_DBM_PTR_INT(dbm) do { \ if (!(dbm)) { \ #define CHECK_DBM_PTR_INT(dbm, func) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return -EPERM; \ } \ } while (0) #define CHECK_DBM_PTR_VOID(dbm) do { \ if (!(dbm)) { \ #define CHECK_DBM_PTR_VOID(dbm, func) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return; \ } \ } while (0) #define CHECK_DBM_PTR_BOOL(dbm, func, ret) do { \ if (!(dbm) || !((dbm)->func)) { \ pr_err("Can't call %s, dbp pointer == NULL\n", __func__); \ return ret; \ } \ } while (0) static inline int dbm_soft_reset(struct dbm *dbm, bool enter_reset) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, soft_reset); return dbm->soft_reset(enter_reset); } Loading @@ -116,7 +129,7 @@ static inline int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, bool producer, bool disable_wb, bool internal_mem, bool ioc) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, ep_config); return dbm->ep_config(usb_ep, bam_pipe, producer, disable_wb, internal_mem, ioc); Loading @@ -124,41 +137,55 @@ static inline int dbm_ep_config(struct dbm *dbm, u8 usb_ep, u8 bam_pipe, static inline int dbm_ep_unconfig(struct dbm *dbm, u8 usb_ep) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, ep_unconfig); return dbm->ep_unconfig(usb_ep); } static inline int dbm_get_num_of_eps_configured(struct dbm *dbm) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, get_num_of_eps_configured); return dbm->get_num_of_eps_configured(); } static inline int dbm_event_buffer_config(struct dbm *dbm, u32 addr_lo, u32 addr_hi, int size) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, event_buffer_config); return dbm->event_buffer_config(addr_lo, addr_hi, size); } static inline int dbm_data_fifo_config(struct dbm *dbm, u8 dep_num, phys_addr_t addr, u32 size, u8 dst_pipe_idx) { CHECK_DBM_PTR_INT(dbm); CHECK_DBM_PTR_INT(dbm, data_fifo_config); return dbm->data_fifo_config(dep_num, addr, size, dst_pipe_idx); } static inline void dbm_set_speed(struct dbm *dbm, bool speed) { CHECK_DBM_PTR_VOID(dbm); CHECK_DBM_PTR_VOID(dbm, set_speed); dbm->set_speed(speed); } static inline void dbm_enable(struct dbm *dbm) { CHECK_DBM_PTR_VOID(dbm); CHECK_DBM_PTR_VOID(dbm, enable); dbm->enable(); } static inline int dbm_ep_soft_reset(struct dbm *dbm, u8 dbm_ep, bool enter_reset) { CHECK_DBM_PTR_INT(dbm, ep_soft_reset); return dbm->ep_soft_reset(dbm_ep, enter_reset); } static inline bool dbm_reset_ep_after_lpm(struct dbm *dbm) { /* Default (backward compatible) setting is false */ CHECK_DBM_PTR_BOOL(dbm, reset_ep_after_lpm, false); return dbm->reset_ep_after_lpm(); } #endif /* __DBM_H */