1
0

Merge tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB/PHY updates from Greg KH:
 "Here is the big set of USB and PHY driver patches for 4.17-rc1.

  Lots of USB typeC work happened this round, with code moving from the
  staging directory into the "real" part of the kernel, as well as new
  infrastructure being added to be able to handle the different types of
  "roles" that typeC requires.

  There is also the normal huge set of USB gadget controller and driver
  updates, along with XHCI changes, and a raft of other tiny fixes all
  over the USB tree. And the PHY driver updates are merged in here as
  well as they interacted with the USB drivers in some places.

  All of these have been in linux-next for a while with no reported
  issues"

* tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (250 commits)
  Revert "USB: serial: ftdi_sio: add Id for Physik Instrumente E-870"
  usb: musb: gadget: misplaced out of bounds check
  usb: chipidea: imx: Fix ULPI on imx53
  usb: chipidea: imx: Cleanup ci_hdrc_imx_platform_flag
  usb: chipidea: usbmisc: small clean up
  usb: chipidea: usbmisc: evdo can be set e/o reset
  usb: chipidea: usbmisc: evdo is only specific to OTG port
  USB: serial: ftdi_sio: add Id for Physik Instrumente E-870
  usb: dwc3: gadget: never call ->complete() from ->ep_queue()
  usb: gadget: udc: core: update usb_ep_queue() documentation
  usb: host: Remove the deprecated ATH79 USB host config options
  usb: roles: Fix return value check in intel_xhci_usb_probe()
  USB: gadget: f_midi: fixing a possible double-free in f_midi
  usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks
  usb: core: Copy parameter string correctly and remove superfluous null check
  USB: announce bcdDevice as well as idVendor, idProduct.
  USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw
  usb: hub: Reduce warning to notice on power loss
  USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator
  USB: serial: cp210x: add ELDAT Easywave RX09 id
  ...
This commit is contained in:
Linus Torvalds
2018-04-04 17:55:35 -07:00
203 changed files with 9282 additions and 3100 deletions

View File

@@ -21,7 +21,6 @@
struct tcpci {
struct device *dev;
struct i2c_client *client;
struct tcpm_port *port;
@@ -30,6 +29,12 @@ struct tcpci {
bool controls_vbus;
struct tcpc_dev tcpc;
struct tcpci_data *data;
};
struct tcpci_chip {
struct tcpci *tcpci;
struct tcpci_data data;
};
static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc)
@@ -37,8 +42,7 @@ static inline struct tcpci *tcpc_to_tcpci(struct tcpc_dev *tcpc)
return container_of(tcpc, struct tcpci, tcpc);
}
static int tcpci_read16(struct tcpci *tcpci, unsigned int reg,
u16 *val)
static int tcpci_read16(struct tcpci *tcpci, unsigned int reg, u16 *val)
{
return regmap_raw_read(tcpci->regmap, reg, val, sizeof(u16));
}
@@ -98,9 +102,17 @@ static int tcpci_set_cc(struct tcpc_dev *tcpc, enum typec_cc_status cc)
static int tcpci_start_drp_toggling(struct tcpc_dev *tcpc,
enum typec_cc_status cc)
{
int ret;
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
unsigned int reg = TCPC_ROLE_CTRL_DRP;
/* Handle vendor drp toggling */
if (tcpci->data->start_drp_toggling) {
ret = tcpci->data->start_drp_toggling(tcpci, tcpci->data, cc);
if (ret < 0)
return ret;
}
switch (cc) {
default:
case TYPEC_CC_RP_DEF:
@@ -117,7 +129,17 @@ static int tcpci_start_drp_toggling(struct tcpc_dev *tcpc,
break;
}
return regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
if (cc == TYPEC_CC_RD)
reg |= (TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC1_SHIFT) |
(TCPC_ROLE_CTRL_CC_RD << TCPC_ROLE_CTRL_CC2_SHIFT);
else
reg |= (TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC1_SHIFT) |
(TCPC_ROLE_CTRL_CC_RP << TCPC_ROLE_CTRL_CC2_SHIFT);
ret = regmap_write(tcpci->regmap, TCPC_ROLE_CTRL, reg);
if (ret < 0)
return ret;
return regmap_write(tcpci->regmap, TCPC_COMMAND,
TCPC_CMD_LOOK4CONNECTION);
}
static enum typec_cc_status tcpci_to_typec_cc(unsigned int cc, bool sink)
@@ -178,6 +200,13 @@ static int tcpci_set_vconn(struct tcpc_dev *tcpc, bool enable)
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
int ret;
/* Handle vendor set vconn */
if (tcpci->data->set_vconn) {
ret = tcpci->data->set_vconn(tcpci, tcpci->data, enable);
if (ret < 0)
return ret;
}
ret = regmap_write(tcpci->regmap, TCPC_POWER_CTRL,
enable ? TCPC_POWER_CTRL_VCONN_ENABLE : 0);
if (ret < 0)
@@ -323,6 +352,13 @@ static int tcpci_init(struct tcpc_dev *tcpc)
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
/* Handle vendor init */
if (tcpci->data->init) {
ret = tcpci->data->init(tcpci, tcpci->data);
if (ret < 0)
return ret;
}
/* Clear all events */
ret = tcpci_write16(tcpci, TCPC_ALERT, 0xffff);
if (ret < 0)
@@ -344,9 +380,8 @@ static int tcpci_init(struct tcpc_dev *tcpc)
return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg);
}
static irqreturn_t tcpci_irq(int irq, void *dev_id)
irqreturn_t tcpci_irq(struct tcpci *tcpci)
{
struct tcpci *tcpci = dev_id;
u16 status;
tcpci_read16(tcpci, TCPC_ALERT, &status);
@@ -412,6 +447,14 @@ static irqreturn_t tcpci_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
EXPORT_SYMBOL_GPL(tcpci_irq);
static irqreturn_t _tcpci_irq(int irq, void *dev_id)
{
struct tcpci_chip *chip = dev_id;
return tcpci_irq(chip->tcpci);
}
static const struct regmap_config tcpci_regmap_config = {
.reg_bits = 8,
@@ -435,22 +478,18 @@ static int tcpci_parse_config(struct tcpci *tcpci)
return 0;
}
static int tcpci_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
{
struct tcpci *tcpci;
int err;
tcpci = devm_kzalloc(&client->dev, sizeof(*tcpci), GFP_KERNEL);
tcpci = devm_kzalloc(dev, sizeof(*tcpci), GFP_KERNEL);
if (!tcpci)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
tcpci->client = client;
tcpci->dev = &client->dev;
i2c_set_clientdata(client, tcpci);
tcpci->regmap = devm_regmap_init_i2c(client, &tcpci_regmap_config);
if (IS_ERR(tcpci->regmap))
return PTR_ERR(tcpci->regmap);
tcpci->dev = dev;
tcpci->data = data;
tcpci->regmap = data->regmap;
tcpci->tcpc.init = tcpci_init;
tcpci->tcpc.get_vbus = tcpci_get_vbus;
@@ -467,27 +506,63 @@ static int tcpci_probe(struct i2c_client *client,
err = tcpci_parse_config(tcpci);
if (err < 0)
return err;
return ERR_PTR(err);
/* Disable chip interrupts */
tcpci_write16(tcpci, TCPC_ALERT_MASK, 0);
tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
if (PTR_ERR_OR_ZERO(tcpci->port))
return ERR_CAST(tcpci->port);
err = devm_request_threaded_irq(tcpci->dev, client->irq, NULL,
tcpci_irq,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
dev_name(tcpci->dev), tcpci);
return tcpci;
}
EXPORT_SYMBOL_GPL(tcpci_register_port);
void tcpci_unregister_port(struct tcpci *tcpci)
{
tcpm_unregister_port(tcpci->port);
}
EXPORT_SYMBOL_GPL(tcpci_unregister_port);
static int tcpci_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
struct tcpci_chip *chip;
int err;
u16 val = 0;
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->data.regmap = devm_regmap_init_i2c(client, &tcpci_regmap_config);
if (IS_ERR(chip->data.regmap))
return PTR_ERR(chip->data.regmap);
/* Disable chip interrupts before requesting irq */
err = regmap_raw_write(chip->data.regmap, TCPC_ALERT_MASK, &val,
sizeof(u16));
if (err < 0)
return err;
tcpci->port = tcpm_register_port(tcpci->dev, &tcpci->tcpc);
return PTR_ERR_OR_ZERO(tcpci->port);
err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
_tcpci_irq,
IRQF_ONESHOT | IRQF_TRIGGER_LOW,
dev_name(&client->dev), chip);
if (err < 0)
return err;
chip->tcpci = tcpci_register_port(&client->dev, &chip->data);
if (PTR_ERR_OR_ZERO(chip->tcpci))
return PTR_ERR(chip->tcpci);
i2c_set_clientdata(client, chip);
return 0;
}
static int tcpci_remove(struct i2c_client *client)
{
struct tcpci *tcpci = i2c_get_clientdata(client);
struct tcpci_chip *chip = i2c_get_clientdata(client);
tcpm_unregister_port(tcpci->port);
tcpci_unregister_port(chip->tcpci);
return 0;
}

View File

@@ -121,4 +121,18 @@
#define TCPC_VBUS_VOLTAGE_ALARM_HI_CFG 0x76
#define TCPC_VBUS_VOLTAGE_ALARM_LO_CFG 0x78
struct tcpci;
struct tcpci_data {
struct regmap *regmap;
int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,
bool enable);
int (*start_drp_toggling)(struct tcpci *tcpci, struct tcpci_data *data,
enum typec_cc_status cc);
};
struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data);
void tcpci_unregister_port(struct tcpci *tcpci);
irqreturn_t tcpci_irq(struct tcpci *tcpci);
#endif /* __LINUX_USB_TCPCI_H */