mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 19:21:28 +02:00
usb: dwc3: dwc3-msm-core: Add DIAG IMEM management into DWC3 MSM
Originally, the PID IMEM field was updated as part of the f_diag driver instance. Since the f_diag, driver has been removed, relocate this logic into DWC3 MSM. Once receiving the pullup enable call, the logic will look up for the diag function, and if present handle writing the PID and device serial number to IMEM. This removes the need for having userspace update/trigger the IMEM update. Change-Id: If6ba232270269001690b3cedd3d0de9bf2d4cebb Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
This commit is contained in:
parent
8166e88dfa
commit
685398da72
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/usb/ch9.h>
|
||||
|
|
@ -44,6 +45,7 @@
|
|||
#include <linux/usb/dwc3-msm.h>
|
||||
#include <linux/usb/role.h>
|
||||
#include <linux/usb/redriver.h>
|
||||
#include <linux/usb/composite.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "gadget.h"
|
||||
|
|
@ -53,6 +55,11 @@
|
|||
|
||||
#define NUM_LOG_PAGES 12
|
||||
|
||||
/* dload specific suppot */
|
||||
#define PID_MAGIC_ID 0x71432909
|
||||
#define SERIAL_NUM_MAGIC_ID 0x61945374
|
||||
#define SERIAL_NUMBER_LENGTH 128
|
||||
|
||||
/* time out to wait for USB cable status notification (in ms)*/
|
||||
#define SM_INIT_TIMEOUT 30000
|
||||
|
||||
|
|
@ -291,6 +298,13 @@ enum usb_gsi_reg {
|
|||
GSI_REG_MAX,
|
||||
};
|
||||
|
||||
struct dload_struct {
|
||||
u32 pid;
|
||||
char serial_number[SERIAL_NUMBER_LENGTH];
|
||||
u32 pid_magic;
|
||||
u32 serial_magic;
|
||||
};
|
||||
|
||||
struct dwc3_hw_ep {
|
||||
struct dwc3_ep *dep;
|
||||
enum usb_hw_ep_mode mode;
|
||||
|
|
@ -590,6 +604,8 @@ struct dwc3_msm {
|
|||
/* unfortunately, dwc3 core doesn't manage multiple dwc3 instances for trace */
|
||||
void *dwc_trace_ipc_log_ctxt;
|
||||
|
||||
static struct dload_struct __iomem *diag_dload;
|
||||
|
||||
static void dwc3_pwr_event_handler(struct dwc3_msm *mdwc);
|
||||
|
||||
static inline void dwc3_msm_ep_writel(void __iomem *base, u32 offset, u32 value)
|
||||
|
|
@ -3127,6 +3143,67 @@ static void dwc3_msm_set_clk_sel(struct dwc3_msm *mdwc)
|
|||
dwc3_msm_switch_utmi(mdwc, 1);
|
||||
}
|
||||
|
||||
static void *gadget_get_drvdata(struct usb_gadget *g)
|
||||
{
|
||||
return g->ep0->driver_data;
|
||||
}
|
||||
|
||||
static int is_diag_enabled(struct usb_composite_dev *cdev)
|
||||
{
|
||||
struct usb_configuration *c;
|
||||
|
||||
list_for_each_entry(c, &cdev->configs, list) {
|
||||
struct usb_function *f;
|
||||
|
||||
f = c->interface[0];
|
||||
if (!strcmp(f->fi->group.cg_item.ci_name, "ffs.diag"))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dwc3_msm_update_imem_pid(struct dwc3 *dwc)
|
||||
{
|
||||
struct usb_composite_dev *cdev = NULL;
|
||||
struct dload_struct local_diag_dload = { 0 };
|
||||
|
||||
if (!diag_dload || !dwc->gadget) {
|
||||
pr_err("%s: diag_dload mem region not defined\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
cdev = gadget_get_drvdata(dwc->gadget);
|
||||
|
||||
if (cdev->desc.idVendor == 0x05c6 && is_diag_enabled(cdev)) {
|
||||
struct usb_gadget_string_container *uc;
|
||||
struct usb_string *s;
|
||||
|
||||
local_diag_dload.pid = cdev->desc.idProduct;
|
||||
local_diag_dload.pid_magic = PID_MAGIC_ID;
|
||||
local_diag_dload.serial_magic = SERIAL_NUM_MAGIC_ID;
|
||||
|
||||
list_for_each_entry(uc, &cdev->gstrings, list) {
|
||||
struct usb_gadget_strings **table;
|
||||
|
||||
table = (struct usb_gadget_strings **)uc->stash;
|
||||
if (!table) {
|
||||
pr_err("%s: can't update dload cookie\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (s = (*table)->strings; s && s->s; s++) {
|
||||
if (s->id == cdev->desc.iSerialNumber) {
|
||||
strscpy(local_diag_dload.serial_number, s->s,
|
||||
SERIAL_NUMBER_LENGTH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy_toio(diag_dload, &local_diag_dload, sizeof(local_diag_dload));
|
||||
}
|
||||
}
|
||||
|
||||
void dwc3_msm_notify_event(struct dwc3 *dwc,
|
||||
enum dwc3_notify_event event, unsigned int value)
|
||||
{
|
||||
|
|
@ -3283,6 +3360,9 @@ void dwc3_msm_notify_event(struct dwc3 *dwc,
|
|||
GSI_EN_MASK, 0);
|
||||
}
|
||||
break;
|
||||
case DWC3_IMEM_UPDATE_PID:
|
||||
dwc3_msm_update_imem_pid(dwc);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(mdwc->dev, "unknown dwc3 event\n");
|
||||
break;
|
||||
|
|
@ -5321,6 +5401,7 @@ static int dwc3_msm_parse_core_params(struct dwc3_msm *mdwc, struct device_node
|
|||
|
||||
static int dwc3_msm_parse_params(struct dwc3_msm *mdwc, struct device_node *node)
|
||||
{
|
||||
struct device_node *diag_node;
|
||||
struct device *dev = mdwc->dev;
|
||||
int ret, size = 0, i;
|
||||
|
||||
|
|
@ -5385,6 +5466,12 @@ static int dwc3_msm_parse_params(struct dwc3_msm *mdwc, struct device_node *node
|
|||
|
||||
mdwc->force_gen1 = of_property_read_bool(node, "qcom,force-gen1");
|
||||
|
||||
diag_node = of_find_compatible_node(NULL, NULL, "qcom,msm-imem-diag-dload");
|
||||
if (!diag_node)
|
||||
pr_warn("diag: failed to find diag_dload imem node\n");
|
||||
|
||||
diag_dload = diag_node ? of_iomap(diag_node, 0) : NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -5690,6 +5777,8 @@ static int dwc3_msm_remove(struct platform_device *pdev)
|
|||
struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
|
||||
int i, ret_pm;
|
||||
|
||||
if (diag_dload)
|
||||
iounmap(diag_dload);
|
||||
usb_role_switch_unregister(mdwc->role_switch);
|
||||
|
||||
if (mdwc->dpdm_nb.notifier_call) {
|
||||
|
|
|
|||
|
|
@ -112,6 +112,10 @@ static int entry_dwc3_gadget_pullup(struct kretprobe_instance *ri,
|
|||
dwc3_msm_notify_event(data->dwc, DWC3_CONTROLLER_PULLUP_ENTER,
|
||||
data->xi0);
|
||||
|
||||
/* Only write PID to IMEM if pullup is being enabled */
|
||||
if (data->xi0)
|
||||
dwc3_msm_notify_event(data->dwc, DWC3_IMEM_UPDATE_PID, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ enum dwc3_notify_event {
|
|||
DWC3_GSI_EVT_BUF_CLEAR,
|
||||
DWC3_GSI_EVT_BUF_FREE,
|
||||
DWC3_CONTROLLER_NOTIFY_CLEAR_DB,
|
||||
DWC3_IMEM_UPDATE_PID,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user