Merge "msm: usb_bam: Fix failure of remove by of_platform_depopulate" into msm-4.4

This commit is contained in:
Linux Build Service Account 2017-08-20 01:17:02 -07:00 committed by Gerrit - the friendly Code Review server
commit 1c2f58fb73
2 changed files with 65 additions and 75 deletions

View file

@ -103,7 +103,6 @@ struct usb_bam_sps_type {
struct usb_bam_ctx_type {
struct usb_bam_sps_type usb_bam_sps;
struct resource *io_res;
void __iomem *regs;
int irq;
struct platform_device *usb_bam_pdev;
struct workqueue_struct *usb_bam_wq;
@ -113,6 +112,7 @@ struct usb_bam_ctx_type {
u32 inactivity_timer_ms;
bool is_bam_inactivity;
struct usb_bam_pipe_connect *usb_bam_connections;
struct msm_usb_bam_data *usb_bam_data;
spinlock_t usb_bam_lock;
};
@ -320,8 +320,6 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
{
int ret = 0;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[pipe_connect->bam_type];
struct msm_usb_bam_platform_data *pdata =
ctx->usb_bam_pdev->dev.platform_data;
struct sps_mem_buffer *data_buf = &(pipe_connect->data_mem_buf);
struct sps_mem_buffer *desc_buf = &(pipe_connect->desc_mem_buf);
@ -360,7 +358,7 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
}
data_buf->phys_base = pipe_connect->data_fifo_base_offset +
pdata->usb_bam_fifo_baseaddr;
ctx->usb_bam_data->usb_bam_fifo_baseaddr;
data_buf->size = pipe_connect->data_fifo_size;
data_buf->base = ioremap(data_buf->phys_base, data_buf->size);
if (!data_buf->base) {
@ -372,7 +370,7 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
memset_io(data_buf->base, 0, data_buf->size);
desc_buf->phys_base = pipe_connect->desc_fifo_base_offset +
pdata->usb_bam_fifo_baseaddr;
ctx->usb_bam_data->usb_bam_fifo_baseaddr;
desc_buf->size = pipe_connect->desc_fifo_size;
desc_buf->base = ioremap(desc_buf->phys_base, desc_buf->size);
if (!desc_buf->base) {
@ -1070,7 +1068,6 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
struct usb_bam_pipe_connect *pipe_connect =
&ctx->usb_bam_connections[idx];
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
enum usb_bam_mode cur_mode;
if (pipe_connect->enabled) {
@ -1096,7 +1093,7 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
spin_lock(&ctx->usb_bam_lock);
/* Check if BAM requires RESET before connect and reset of first pipe */
if ((pdata->reset_on_connect == true) &&
if ((ctx->usb_bam_data->reset_on_connect == true) &&
(ctx->pipes_enabled_per_bam == 0)) {
spin_unlock(&ctx->usb_bam_lock);
@ -1596,8 +1593,6 @@ static int ss_usb_cons_release_resource(void)
static void usb_bam_ipa_create_resources(enum usb_ctrl cur_bam)
{
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
struct msm_usb_bam_platform_data *pdata =
ctx->usb_bam_pdev->dev.platform_data;
struct ipa_rm_create_params usb_prod_create_params;
struct ipa_rm_create_params usb_cons_create_params;
int ret;
@ -1606,7 +1601,8 @@ static void usb_bam_ipa_create_resources(enum usb_ctrl cur_bam)
memset(&usb_prod_create_params, 0, sizeof(usb_prod_create_params));
usb_prod_create_params.name = ipa_rm_resource_prod[cur_bam];
usb_prod_create_params.reg_params.notify_cb = usb_prod_notify_cb;
usb_prod_create_params.reg_params.user_data = &pdata->bam_type;
usb_prod_create_params.reg_params.user_data
= &ctx->usb_bam_data->bam_type;
usb_prod_create_params.floor_voltage = IPA_VOLTAGE_SVS;
ret = ipa_rm_create_resource(&usb_prod_create_params);
if (ret) {
@ -2136,16 +2132,14 @@ static int usb_bam_set_ipa_perf(enum usb_ctrl cur_bam,
int ret;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
struct ipa_rm_perf_profile ipa_rm_perf_prof;
struct msm_usb_bam_platform_data *pdata =
ctx->usb_bam_pdev->dev.platform_data;
if (usb_connection_speed == USB_SPEED_SUPER)
ipa_rm_perf_prof.max_supported_bandwidth_mbps =
pdata->max_mbps_superspeed;
ctx->usb_bam_data->max_mbps_superspeed;
else
/* Bam2Bam is supported only for SS and HS (HW limitation) */
ipa_rm_perf_prof.max_supported_bandwidth_mbps =
pdata->max_mbps_highspeed;
ctx->usb_bam_data->max_mbps_highspeed;
/*
* Having a max mbps property in dtsi file is a must
@ -2182,7 +2176,6 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
struct usb_bam_pipe_connect *pipe_connect;
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
struct msm_usb_bam_platform_data *pdata = bam_dev->platform_data;
int ret;
bool bam2bam, is_dpl;
@ -2260,7 +2253,8 @@ int usb_bam_connect_ipa(enum usb_ctrl cur_bam,
/* Check if BAM requires RESET before connect and reset first pipe */
spin_lock(&ctx->usb_bam_lock);
if (pdata->reset_on_connect && !ctx->pipes_enabled_per_bam) {
if (ctx->usb_bam_data->reset_on_connect &&
!ctx->pipes_enabled_per_bam) {
spin_unlock(&ctx->usb_bam_lock);
if (cur_bam == CI_CTRL)
@ -2610,8 +2604,6 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
struct usb_bam_pipe_connect *pipe_connect;
struct device *bam_dev = &ctx->usb_bam_pdev->dev;
int ret;
struct msm_usb_bam_platform_data *pdata =
ctx->usb_bam_pdev->dev.platform_data;
pipe_connect = &ctx->usb_bam_connections[idx];
@ -2639,7 +2631,8 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)
log_event_dbg("%s: success disconnecting pipe %d\n", __func__, idx);
if (pdata->reset_on_disconnect && !ctx->pipes_enabled_per_bam) {
if (ctx->usb_bam_data->reset_on_disconnect
&& !ctx->pipes_enabled_per_bam) {
if (bam_type == CI_CTRL)
msm_hw_bam_disable(1);
@ -2807,10 +2800,10 @@ static void usb_bam_sps_events(enum sps_callback_case sps_cb_case, void *user)
}
}
static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
static struct msm_usb_bam_data *usb_bam_dt_to_data(
struct platform_device *pdev, u32 usb_addr)
{
struct msm_usb_bam_platform_data *pdata;
struct msm_usb_bam_data *usb_bam_data;
struct device_node *node = pdev->dev.of_node;
int rc = 0;
u8 i = 0;
@ -2819,10 +2812,10 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
u32 threshold, max_connections = 0;
static struct usb_bam_pipe_connect *usb_bam_connections;
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
usb_bam_data = devm_kzalloc(&pdev->dev, sizeof(*usb_bam_data),
GFP_KERNEL);
if (!usb_bam_data)
return NULL;
}
rc = of_property_read_u32(node, "qcom,bam-type", &bam);
if (rc) {
@ -2835,7 +2828,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
__func__, bam);
return NULL;
}
pdata->bam_type = bam;
usb_bam_data->bam_type = bam;
rc = of_property_read_u32(node, "qcom,bam-mode", &bam_mode);
if (rc) {
@ -2845,49 +2838,49 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
bam_mode = USB_BAM_DEVICE;
}
pdata->reset_on_connect = of_property_read_bool(node,
usb_bam_data->reset_on_connect = of_property_read_bool(node,
"qcom,reset-bam-on-connect");
pdata->reset_on_disconnect = of_property_read_bool(node,
usb_bam_data->reset_on_disconnect = of_property_read_bool(node,
"qcom,reset-bam-on-disconnect");
rc = of_property_read_u32(node, "qcom,usb-bam-num-pipes",
&pdata->usb_bam_num_pipes);
&usb_bam_data->usb_bam_num_pipes);
if (rc) {
log_event_err("Invalid usb bam num pipes property\n");
return NULL;
}
rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-highspeed",
&pdata->max_mbps_highspeed);
&usb_bam_data->max_mbps_highspeed);
if (rc)
pdata->max_mbps_highspeed = 0;
usb_bam_data->max_mbps_highspeed = 0;
rc = of_property_read_u32(node, "qcom,usb-bam-max-mbps-superspeed",
&pdata->max_mbps_superspeed);
&usb_bam_data->max_mbps_superspeed);
if (rc)
pdata->max_mbps_superspeed = 0;
usb_bam_data->max_mbps_superspeed = 0;
rc = of_property_read_u32(node, "qcom,usb-bam-fifo-baseaddr", &addr);
if (rc)
pr_debug("%s: Invalid usb base address property\n", __func__);
else
pdata->usb_bam_fifo_baseaddr = addr;
usb_bam_data->usb_bam_fifo_baseaddr = addr;
pdata->ignore_core_reset_ack = of_property_read_bool(node,
usb_bam_data->ignore_core_reset_ack = of_property_read_bool(node,
"qcom,ignore-core-reset-ack");
pdata->disable_clk_gating = of_property_read_bool(node,
usb_bam_data->disable_clk_gating = of_property_read_bool(node,
"qcom,disable-clk-gating");
rc = of_property_read_u32(node, "qcom,usb-bam-override-threshold",
&threshold);
if (rc)
pdata->override_threshold = USB_THRESHOLD;
usb_bam_data->override_threshold = USB_THRESHOLD;
else
pdata->override_threshold = threshold;
usb_bam_data->override_threshold = threshold;
pdata->enable_hsusb_bam_on_boot = of_property_read_bool(node,
usb_bam_data->enable_hsusb_bam_on_boot = of_property_read_bool(node,
"qcom,enable-hsusb-bam-on-boot");
for_each_child_of_node(pdev->dev.of_node, node)
@ -2923,7 +2916,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
goto err;
if (usb_bam_connections[i].mem_type == OCI_MEM) {
if (!pdata->usb_bam_fifo_baseaddr) {
if (!usb_bam_data->usb_bam_fifo_baseaddr) {
log_event_err("%s: base address is missing\n",
__func__);
goto err;
@ -3007,7 +3000,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
msm_usb_bam[bam].usb_bam_connections = usb_bam_connections;
msm_usb_bam[bam].max_connections = max_connections;
return pdata;
return usb_bam_data;
err:
log_event_err("%s: failed\n", __func__);
return NULL;
@ -3016,9 +3009,8 @@ err:
static int usb_bam_init(struct platform_device *pdev)
{
int ret;
struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
enum usb_ctrl bam_type = pdata->bam_type;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
enum usb_ctrl bam_type = ctx->usb_bam_data->bam_type;
struct sps_bam_props props;
memset(&props, 0, sizeof(props));
@ -3027,12 +3019,11 @@ static int usb_bam_init(struct platform_device *pdev)
bam_enable_strings[bam_type]);
props.phys_addr = ctx->io_res->start;
props.virt_addr = ctx->regs;
props.virt_size = resource_size(ctx->io_res);
props.irq = ctx->irq;
props.summing_threshold = pdata->override_threshold;
props.event_threshold = pdata->override_threshold;
props.num_pipes = pdata->usb_bam_num_pipes;
props.summing_threshold = ctx->usb_bam_data->override_threshold;
props.event_threshold = ctx->usb_bam_data->override_threshold;
props.num_pipes = ctx->usb_bam_data->usb_bam_num_pipes;
props.callback = usb_bam_sps_events;
props.user = bam_enable_strings[bam_type];
@ -3040,10 +3031,10 @@ static int usb_bam_init(struct platform_device *pdev)
* HSUSB and HSIC Cores don't support RESET ACK signal to BAMs
* Hence, let BAM to ignore acknowledge from USB while resetting PIPE
*/
if (pdata->ignore_core_reset_ack && bam_type != DWC3_CTRL)
if (ctx->usb_bam_data->ignore_core_reset_ack && bam_type != DWC3_CTRL)
props.options = SPS_BAM_NO_EXT_P_RST;
if (pdata->disable_clk_gating)
if (ctx->usb_bam_data->disable_clk_gating)
props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;
/*
@ -3051,7 +3042,8 @@ static int usb_bam_init(struct platform_device *pdev)
* starting peripheral controller to avoid switching USB core mode
* from legacy to BAM with ongoing data transfers.
*/
if (pdata->enable_hsusb_bam_on_boot && bam_type == CI_CTRL) {
if (ctx->usb_bam_data->enable_hsusb_bam_on_boot
&& bam_type == CI_CTRL) {
pr_debug("Register and enable HSUSB BAM\n");
props.options |= SPS_BAM_OPT_ENABLE_AT_BOOT;
}
@ -3068,9 +3060,8 @@ static int usb_bam_init(struct platform_device *pdev)
static int enable_usb_bam(struct platform_device *pdev)
{
int ret;
struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
enum usb_ctrl bam_type = pdata->bam_type;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
enum usb_ctrl bam_type = ctx->usb_bam_data->bam_type;
ret = usb_bam_init(pdev);
if (ret) {
@ -3137,14 +3128,19 @@ void usb_bam_register_panic_hdlr(void)
&usb_bam_panic_blk);
}
static void usb_bam_unregister_panic_hdlr(void)
{
atomic_notifier_chain_unregister(&panic_notifier_list,
&usb_bam_panic_blk);
}
static int usb_bam_probe(struct platform_device *pdev)
{
int ret, i, irq;
struct resource *io_res;
void __iomem *regs;
enum usb_ctrl bam_type;
struct usb_bam_ctx_type *ctx;
struct msm_usb_bam_platform_data *pdata;
struct msm_usb_bam_data *usb_bam_data;
dev_dbg(&pdev->dev, "usb_bam_probe\n");
@ -3160,25 +3156,19 @@ static int usb_bam_probe(struct platform_device *pdev)
return irq;
}
regs = devm_ioremap(&pdev->dev, io_res->start, resource_size(io_res));
if (!regs) {
log_event_err("%s: ioremap failed\n", __func__);
return -ENOMEM;
}
/* specify BAM physical address to be filled in BAM connections */
pdata = usb_bam_dt_to_pdata(pdev, io_res->start);
if (!pdata)
usb_bam_data = usb_bam_dt_to_data(pdev, io_res->start);
if (!usb_bam_data)
return -EINVAL;
pdev->dev.platform_data = pdata;
bam_type = pdata->bam_type;
bam_type = usb_bam_data->bam_type;
ctx = &msm_usb_bam[bam_type];
dev_set_drvdata(&pdev->dev, ctx);
ctx->usb_bam_pdev = pdev;
ctx->irq = irq;
ctx->regs = regs;
ctx->io_res = io_res;
ctx->usb_bam_data = usb_bam_data;
for (i = 0; i < ctx->max_connections; i++) {
ctx->usb_bam_connections[i].enabled = 0;
@ -3319,15 +3309,15 @@ EXPORT_SYMBOL(usb_bam_get_bam_type);
bool msm_usb_bam_enable(enum usb_ctrl bam, bool bam_enable)
{
struct msm_usb_bam_platform_data *pdata;
struct msm_usb_bam_data *usb_bam_data;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam];
if (!ctx->usb_bam_pdev)
return 0;
pdata = ctx->usb_bam_pdev->dev.platform_data;
usb_bam_data = ctx->usb_bam_data;
if ((bam != CI_CTRL) || !(bam_enable ||
pdata->enable_hsusb_bam_on_boot))
usb_bam_data->enable_hsusb_bam_on_boot))
return 0;
msm_hw_bam_disable(1);
@ -3409,10 +3399,10 @@ EXPORT_SYMBOL(msm_bam_hsic_lpm_ok);
static int usb_bam_remove(struct platform_device *pdev)
{
struct msm_usb_bam_platform_data *pdata = pdev->dev.platform_data;
enum usb_ctrl bam_type = pdata->bam_type;
struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam_type];
struct usb_bam_ctx_type *ctx = dev_get_drvdata(&pdev->dev);
usb_bam_unregister_panic_hdlr();
sps_deregister_bam_device(ctx->h_bam);
destroy_workqueue(ctx->usb_bam_wq);
return 0;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2017, 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
@ -191,7 +191,7 @@ struct usb_bam_pipe_connect {
};
/**
* struct msm_usb_bam_platform_data: pipe connection information
* struct msm_usb_bam_data: pipe connection information
* between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
* either src BAM or dst BAM
* @usb_bam_num_pipes: max number of pipes to use.
@ -211,7 +211,7 @@ struct usb_bam_pipe_connect {
* can work at in bam2bam mode when connected to SS host.
* @enable_hsusb_bam_on_boot: Enable HSUSB BAM (non-NDP) on bootup itself
*/
struct msm_usb_bam_platform_data {
struct msm_usb_bam_data {
u8 max_connections;
int usb_bam_num_pipes;
phys_addr_t usb_bam_fifo_baseaddr;