Merge 57ae8a4921 ("Merge tag 'driver-core-5.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core") into android-mainline
Steps on the way to 5.18-rc5 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Icff7be41078012fbe0dce57b5ddde3d95e5ea972
This commit is contained in:
@@ -62,6 +62,7 @@ required:
|
||||
- interrupts
|
||||
- phys
|
||||
- phy-names
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
|
||||
@@ -2429,6 +2429,7 @@ static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
|
||||
{
|
||||
int ret = 0;
|
||||
struct binder_sg_copy *sgc, *tmpsgc;
|
||||
struct binder_ptr_fixup *tmppf;
|
||||
struct binder_ptr_fixup *pf =
|
||||
list_first_entry_or_null(pf_head, struct binder_ptr_fixup,
|
||||
node);
|
||||
@@ -2483,7 +2484,11 @@ static int binder_do_deferred_txn_copies(struct binder_alloc *alloc,
|
||||
list_del(&sgc->node);
|
||||
kfree(sgc);
|
||||
}
|
||||
BUG_ON(!list_empty(pf_head));
|
||||
list_for_each_entry_safe(pf, tmppf, pf_head, node) {
|
||||
BUG_ON(pf->skip_size == 0);
|
||||
list_del(&pf->node);
|
||||
kfree(pf);
|
||||
}
|
||||
BUG_ON(!list_empty(sgc_head));
|
||||
|
||||
return ret > 0 ? -EINVAL : ret;
|
||||
@@ -2620,6 +2625,9 @@ static int binder_translate_fd_array(struct list_head *pf_head,
|
||||
struct binder_proc *proc = thread->proc;
|
||||
int ret;
|
||||
|
||||
if (fda->num_fds == 0)
|
||||
return 0;
|
||||
|
||||
fd_buf_size = sizeof(u32) * fda->num_fds;
|
||||
if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
|
||||
binder_user_error("%d:%d got transaction with invalid number of fds (%lld)\n",
|
||||
|
||||
@@ -675,6 +675,15 @@ const struct cpumask *cpu_coregroup_mask(int cpu)
|
||||
core_mask = &cpu_topology[cpu].llc_sibling;
|
||||
}
|
||||
|
||||
/*
|
||||
* For systems with no shared cpu-side LLC but with clusters defined,
|
||||
* extend core_mask to cluster_siblings. The sched domain builder will
|
||||
* then remove MC as redundant with CLS if SCHED_CLUSTER is enabled.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_SCHED_CLUSTER) &&
|
||||
cpumask_subset(core_mask, &cpu_topology[cpu].cluster_sibling))
|
||||
core_mask = &cpu_topology[cpu].cluster_sibling;
|
||||
|
||||
return core_mask;
|
||||
}
|
||||
|
||||
@@ -692,7 +701,7 @@ void update_siblings_masks(unsigned int cpuid)
|
||||
for_each_online_cpu(cpu) {
|
||||
cpu_topo = &cpu_topology[cpu];
|
||||
|
||||
if (cpuid_topo->llc_id == cpu_topo->llc_id) {
|
||||
if (cpu_topo->llc_id != -1 && cpuid_topo->llc_id == cpu_topo->llc_id) {
|
||||
cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling);
|
||||
cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling);
|
||||
}
|
||||
|
||||
@@ -152,9 +152,19 @@ static struct attribute *default_attrs[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static umode_t topology_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int unused)
|
||||
{
|
||||
if (attr == &dev_attr_ppin.attr && !topology_ppin(kobj_to_dev(kobj)->id))
|
||||
return 0;
|
||||
|
||||
return attr->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group topology_attr_group = {
|
||||
.attrs = default_attrs,
|
||||
.bin_attrs = bin_attrs,
|
||||
.is_visible = topology_is_visible,
|
||||
.name = "topology"
|
||||
};
|
||||
|
||||
|
||||
@@ -1060,6 +1060,7 @@ static int __maybe_unused mhi_pci_freeze(struct device *dev)
|
||||
* the intermediate restore kernel reinitializes MHI device with new
|
||||
* context.
|
||||
*/
|
||||
flush_work(&mhi_pdev->recovery_work);
|
||||
if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) {
|
||||
mhi_power_down(mhi_cntrl, true);
|
||||
mhi_unprepare_after_power_down(mhi_cntrl);
|
||||
@@ -1085,6 +1086,7 @@ static const struct dev_pm_ops mhi_pci_pm_ops = {
|
||||
.resume = mhi_pci_resume,
|
||||
.freeze = mhi_pci_freeze,
|
||||
.thaw = mhi_pci_restore,
|
||||
.poweroff = mhi_pci_freeze,
|
||||
.restore = mhi_pci_restore,
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -745,7 +745,7 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
|
||||
case IIO_EV_DIR_RISING:
|
||||
addr = AD7280A_CELL_OVERVOLTAGE_REG;
|
||||
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
|
||||
1, val);
|
||||
1, value);
|
||||
if (ret)
|
||||
break;
|
||||
st->cell_threshhigh = value;
|
||||
@@ -753,7 +753,7 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
|
||||
case IIO_EV_DIR_FALLING:
|
||||
addr = AD7280A_CELL_UNDERVOLTAGE_REG;
|
||||
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
|
||||
1, val);
|
||||
1, value);
|
||||
if (ret)
|
||||
break;
|
||||
st->cell_threshlow = value;
|
||||
@@ -770,18 +770,18 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
|
||||
case IIO_EV_DIR_RISING:
|
||||
addr = AD7280A_AUX_ADC_OVERVOLTAGE_REG;
|
||||
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
|
||||
1, val);
|
||||
1, value);
|
||||
if (ret)
|
||||
break;
|
||||
st->aux_threshhigh = val;
|
||||
st->aux_threshhigh = value;
|
||||
break;
|
||||
case IIO_EV_DIR_FALLING:
|
||||
addr = AD7280A_AUX_ADC_UNDERVOLTAGE_REG;
|
||||
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
|
||||
1, val);
|
||||
1, value);
|
||||
if (ret)
|
||||
break;
|
||||
st->aux_threshlow = val;
|
||||
st->aux_threshlow = value;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
||||
@@ -471,12 +471,15 @@ static ssize_t calibration_forced_value_store(struct device *dev,
|
||||
ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val));
|
||||
mutex_unlock(&state->lock);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val == 0xff) {
|
||||
dev_err(dev, "forced calibration has failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret ?: len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0);
|
||||
|
||||
@@ -656,7 +656,7 @@ static int ad3552r_reset(struct ad3552r_desc *dac)
|
||||
{
|
||||
struct reg_addr_pool addr;
|
||||
int ret;
|
||||
u16 val;
|
||||
int val;
|
||||
|
||||
dac->gpio_reset = devm_gpiod_get_optional(&dac->spi->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
@@ -809,10 +809,10 @@ static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac,
|
||||
|
||||
gain_child = fwnode_get_named_child_node(child,
|
||||
"custom-output-range-config");
|
||||
if (IS_ERR(gain_child)) {
|
||||
if (!gain_child) {
|
||||
dev_err(dev,
|
||||
"mandatory custom-output-range-config property missing\n");
|
||||
return PTR_ERR(gain_child);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dac->ch_data[ch].range_override = 1;
|
||||
|
||||
@@ -178,7 +178,7 @@ static int ad5446_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (m) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
*val = st->cached_val;
|
||||
*val = st->cached_val >> chan->scan_type.shift;
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = st->vref_mv;
|
||||
|
||||
@@ -522,7 +522,7 @@ static int ad5592r_alloc_channels(struct iio_dev *iio_dev)
|
||||
if (!ret)
|
||||
st->channel_modes[reg] = tmp;
|
||||
|
||||
fwnode_property_read_u32(child, "adi,off-state", &tmp);
|
||||
ret = fwnode_property_read_u32(child, "adi,off-state", &tmp);
|
||||
if (!ret)
|
||||
st->channel_offstate[reg] = tmp;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ static int ltc2688_read_raw(struct iio_dev *indio_dev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = 16;
|
||||
*val2 = 16;
|
||||
return IIO_VAL_FRACTIONAL_LOG2;
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
ret = regmap_read(st->regmap,
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
enum chip_id {
|
||||
@@ -311,6 +312,7 @@ static int dac5571_probe(struct i2c_client *client,
|
||||
const struct dac5571_spec *spec;
|
||||
struct dac5571_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
enum chip_id chip_id;
|
||||
int ret, i;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
|
||||
@@ -326,7 +328,13 @@ static int dac5571_probe(struct i2c_client *client,
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = dac5571_channels;
|
||||
|
||||
spec = &dac5571_spec[id->driver_data];
|
||||
if (dev_fwnode(dev))
|
||||
chip_id = (uintptr_t)device_get_match_data(dev);
|
||||
else
|
||||
chip_id = id->driver_data;
|
||||
|
||||
spec = &dac5571_spec[chip_id];
|
||||
|
||||
indio_dev->num_channels = spec->num_channels;
|
||||
data->spec = spec;
|
||||
|
||||
@@ -385,15 +393,15 @@ static int dac5571_remove(struct i2c_client *i2c)
|
||||
}
|
||||
|
||||
static const struct of_device_id dac5571_of_id[] = {
|
||||
{.compatible = "ti,dac5571"},
|
||||
{.compatible = "ti,dac6571"},
|
||||
{.compatible = "ti,dac7571"},
|
||||
{.compatible = "ti,dac5574"},
|
||||
{.compatible = "ti,dac6574"},
|
||||
{.compatible = "ti,dac7574"},
|
||||
{.compatible = "ti,dac5573"},
|
||||
{.compatible = "ti,dac6573"},
|
||||
{.compatible = "ti,dac7573"},
|
||||
{.compatible = "ti,dac5571", .data = (void *)single_8bit},
|
||||
{.compatible = "ti,dac6571", .data = (void *)single_10bit},
|
||||
{.compatible = "ti,dac7571", .data = (void *)single_12bit},
|
||||
{.compatible = "ti,dac5574", .data = (void *)quad_8bit},
|
||||
{.compatible = "ti,dac6574", .data = (void *)quad_10bit},
|
||||
{.compatible = "ti,dac7574", .data = (void *)quad_12bit},
|
||||
{.compatible = "ti,dac5573", .data = (void *)quad_8bit},
|
||||
{.compatible = "ti,dac6573", .data = (void *)quad_10bit},
|
||||
{.compatible = "ti,dac7573", .data = (void *)quad_12bit},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dac5571_of_id);
|
||||
|
||||
@@ -8,6 +8,7 @@ menu "Filters"
|
||||
config ADMV8818
|
||||
tristate "Analog Devices ADMV8818 High-Pass and Low-Pass Filter"
|
||||
depends on SPI && COMMON_CLK && 64BIT
|
||||
select REGMAP_SPI
|
||||
help
|
||||
Say yes here to build support for Analog Devices ADMV8818
|
||||
2 GHz to 18 GHz, Digitally Tunable, High-Pass and Low-Pass Filter.
|
||||
|
||||
@@ -730,7 +730,7 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi)
|
||||
|
||||
ret = regmap_write(data->regmap, BMI160_REG_CMD, BMI160_CMD_SOFTRESET);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_regulator;
|
||||
|
||||
usleep_range(BMI160_SOFTRESET_USLEEP, BMI160_SOFTRESET_USLEEP + 1);
|
||||
|
||||
@@ -741,29 +741,37 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi)
|
||||
if (use_spi) {
|
||||
ret = regmap_read(data->regmap, BMI160_REG_DUMMY, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_regulator;
|
||||
}
|
||||
|
||||
ret = regmap_read(data->regmap, BMI160_REG_CHIP_ID, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Error reading chip id\n");
|
||||
return ret;
|
||||
goto disable_regulator;
|
||||
}
|
||||
if (val != BMI160_CHIP_ID_VAL) {
|
||||
dev_err(dev, "Wrong chip id, got %x expected %x\n",
|
||||
val, BMI160_CHIP_ID_VAL);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto disable_regulator;
|
||||
}
|
||||
|
||||
ret = bmi160_set_mode(data, BMI160_ACCEL, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_regulator;
|
||||
|
||||
ret = bmi160_set_mode(data, BMI160_GYRO, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto disable_accel;
|
||||
|
||||
return 0;
|
||||
|
||||
disable_accel:
|
||||
bmi160_set_mode(data, BMI160_ACCEL, false);
|
||||
|
||||
disable_regulator:
|
||||
regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bmi160_data_rdy_trigger_set_state(struct iio_trigger *trig,
|
||||
|
||||
@@ -18,12 +18,15 @@ static int inv_icm42600_i2c_bus_setup(struct inv_icm42600_state *st)
|
||||
unsigned int mask, val;
|
||||
int ret;
|
||||
|
||||
/* setup interface registers */
|
||||
ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
|
||||
INV_ICM42600_INTF_CONFIG6_MASK,
|
||||
INV_ICM42600_INTF_CONFIG6_I3C_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* setup interface registers
|
||||
* This register write to REG_INTF_CONFIG6 enables a spike filter that
|
||||
* is impacting the line and can prevent the I2C ACK to be seen by the
|
||||
* controller. So we don't test the return value.
|
||||
*/
|
||||
regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6,
|
||||
INV_ICM42600_INTF_CONFIG6_MASK,
|
||||
INV_ICM42600_INTF_CONFIG6_I3C_EN);
|
||||
|
||||
ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4,
|
||||
INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0);
|
||||
|
||||
@@ -416,6 +416,7 @@ static int ak8975_power_on(const struct ak8975_data *data)
|
||||
if (ret) {
|
||||
dev_warn(&data->client->dev,
|
||||
"Failed to enable specified Vid supply\n");
|
||||
regulator_disable(data->vdd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,13 +70,17 @@
|
||||
#define SX9324_REG_AFE_PH2 0x2a
|
||||
#define SX9324_REG_AFE_PH3 0x2b
|
||||
#define SX9324_REG_AFE_CTRL8 0x2c
|
||||
#define SX9324_REG_AFE_CTRL8_RESFILTN_4KOHM 0x02
|
||||
#define SX9324_REG_AFE_CTRL8_RESERVED 0x10
|
||||
#define SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM 0x02
|
||||
#define SX9324_REG_AFE_CTRL9 0x2d
|
||||
#define SX9324_REG_AFE_CTRL9_AGAIN_1 0x08
|
||||
|
||||
#define SX9324_REG_PROX_CTRL0 0x30
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_MASK GENMASK(5, 3)
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_1 0x80
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_SHIFT 3
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_RSVD 0x0
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_1 0x1
|
||||
#define SX9324_REG_PROX_CTRL0_GAIN_8 0x4
|
||||
#define SX9324_REG_PROX_CTRL0_RAWFILT_MASK GENMASK(2, 0)
|
||||
#define SX9324_REG_PROX_CTRL0_RAWFILT_1P50 0x01
|
||||
#define SX9324_REG_PROX_CTRL1 0x31
|
||||
@@ -379,7 +383,14 @@ static int sx9324_read_gain(struct sx_common_data *data,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = 1 << FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval);
|
||||
regval = FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval);
|
||||
if (regval)
|
||||
regval--;
|
||||
else if (regval == SX9324_REG_PROX_CTRL0_GAIN_RSVD ||
|
||||
regval > SX9324_REG_PROX_CTRL0_GAIN_8)
|
||||
return -EINVAL;
|
||||
|
||||
*val = 1 << regval;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
@@ -725,8 +736,12 @@ static int sx9324_write_gain(struct sx_common_data *data,
|
||||
unsigned int gain, reg;
|
||||
int ret;
|
||||
|
||||
gain = ilog2(val);
|
||||
reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2;
|
||||
|
||||
gain = ilog2(val) + 1;
|
||||
if (val <= 0 || gain > SX9324_REG_PROX_CTRL0_GAIN_8)
|
||||
return -EINVAL;
|
||||
|
||||
gain = FIELD_PREP(SX9324_REG_PROX_CTRL0_GAIN_MASK, gain);
|
||||
|
||||
mutex_lock(&data->mutex);
|
||||
@@ -781,12 +796,15 @@ static const struct sx_common_reg_default sx9324_default_regs[] = {
|
||||
{ SX9324_REG_AFE_PH2, 0x1a },
|
||||
{ SX9324_REG_AFE_PH3, 0x16 },
|
||||
|
||||
{ SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESFILTN_4KOHM },
|
||||
{ SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESERVED |
|
||||
SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM },
|
||||
{ SX9324_REG_AFE_CTRL9, SX9324_REG_AFE_CTRL9_AGAIN_1 },
|
||||
|
||||
{ SX9324_REG_PROX_CTRL0, SX9324_REG_PROX_CTRL0_GAIN_1 |
|
||||
{ SX9324_REG_PROX_CTRL0,
|
||||
SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
|
||||
SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
|
||||
{ SX9324_REG_PROX_CTRL1, SX9324_REG_PROX_CTRL0_GAIN_1 |
|
||||
{ SX9324_REG_PROX_CTRL1,
|
||||
SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT |
|
||||
SX9324_REG_PROX_CTRL0_RAWFILT_1P50 },
|
||||
{ SX9324_REG_PROX_CTRL2, SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K },
|
||||
{ SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES |
|
||||
|
||||
@@ -521,6 +521,7 @@ int sx_common_probe(struct i2c_client *client,
|
||||
return dev_err_probe(dev, ret, "error reading WHOAMI\n");
|
||||
|
||||
ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev));
|
||||
indio_dev->dev.of_node = client->dev.of_node;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
indio_dev->channels = data->chip_info->iio_channels;
|
||||
|
||||
@@ -47,7 +47,6 @@ DEFINE_QNODE(qnm_mnoc_sf, SC7180_MASTER_MNOC_SF_MEM_NOC, 1, 32, SC7180_SLAVE_GEM
|
||||
DEFINE_QNODE(qnm_snoc_gc, SC7180_MASTER_SNOC_GC_MEM_NOC, 1, 8, SC7180_SLAVE_LLCC);
|
||||
DEFINE_QNODE(qnm_snoc_sf, SC7180_MASTER_SNOC_SF_MEM_NOC, 1, 16, SC7180_SLAVE_LLCC);
|
||||
DEFINE_QNODE(qxm_gpu, SC7180_MASTER_GFX3D, 2, 32, SC7180_SLAVE_GEM_NOC_SNOC, SC7180_SLAVE_LLCC);
|
||||
DEFINE_QNODE(ipa_core_master, SC7180_MASTER_IPA_CORE, 1, 8, SC7180_SLAVE_IPA_CORE);
|
||||
DEFINE_QNODE(llcc_mc, SC7180_MASTER_LLCC, 2, 4, SC7180_SLAVE_EBI1);
|
||||
DEFINE_QNODE(qhm_mnoc_cfg, SC7180_MASTER_CNOC_MNOC_CFG, 1, 4, SC7180_SLAVE_SERVICE_MNOC);
|
||||
DEFINE_QNODE(qxm_camnoc_hf0, SC7180_MASTER_CAMNOC_HF0, 2, 32, SC7180_SLAVE_MNOC_HF_MEM_NOC);
|
||||
@@ -129,7 +128,6 @@ DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SC7180_SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4);
|
||||
DEFINE_QNODE(qns_gem_noc_snoc, SC7180_SLAVE_GEM_NOC_SNOC, 1, 8, SC7180_MASTER_GEM_NOC_SNOC);
|
||||
DEFINE_QNODE(qns_llcc, SC7180_SLAVE_LLCC, 1, 16, SC7180_MASTER_LLCC);
|
||||
DEFINE_QNODE(srvc_gemnoc, SC7180_SLAVE_SERVICE_GEM_NOC, 1, 4);
|
||||
DEFINE_QNODE(ipa_core_slave, SC7180_SLAVE_IPA_CORE, 1, 8);
|
||||
DEFINE_QNODE(ebi, SC7180_SLAVE_EBI1, 2, 4);
|
||||
DEFINE_QNODE(qns_mem_noc_hf, SC7180_SLAVE_MNOC_HF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_HF_MEM_NOC);
|
||||
DEFINE_QNODE(qns_mem_noc_sf, SC7180_SLAVE_MNOC_SF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_SF_MEM_NOC);
|
||||
@@ -160,7 +158,6 @@ DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi);
|
||||
DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc);
|
||||
DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf);
|
||||
DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto);
|
||||
DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave);
|
||||
DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aop, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_rt_throttle_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_npu_dma_throttle_cfg, &qhs_npu_dsp_throttle_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_tlmm_1, &qhs_tlmm_2, &qhs_tlmm_3, &qhs_ufs_mem_cfg, &qhs_usb3, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc);
|
||||
DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qhm_mnoc_cfg, &qxm_mdp0, &qxm_rot, &qxm_venus0, &qxm_venus_arm9);
|
||||
DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu);
|
||||
@@ -372,22 +369,6 @@ static struct qcom_icc_desc sc7180_gem_noc = {
|
||||
.num_bcms = ARRAY_SIZE(gem_noc_bcms),
|
||||
};
|
||||
|
||||
static struct qcom_icc_bcm *ipa_virt_bcms[] = {
|
||||
&bcm_ip0,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *ipa_virt_nodes[] = {
|
||||
[MASTER_IPA_CORE] = &ipa_core_master,
|
||||
[SLAVE_IPA_CORE] = &ipa_core_slave,
|
||||
};
|
||||
|
||||
static struct qcom_icc_desc sc7180_ipa_virt = {
|
||||
.nodes = ipa_virt_nodes,
|
||||
.num_nodes = ARRAY_SIZE(ipa_virt_nodes),
|
||||
.bcms = ipa_virt_bcms,
|
||||
.num_bcms = ARRAY_SIZE(ipa_virt_bcms),
|
||||
};
|
||||
|
||||
static struct qcom_icc_bcm *mc_virt_bcms[] = {
|
||||
&bcm_acv,
|
||||
&bcm_mc0,
|
||||
@@ -519,8 +500,6 @@ static const struct of_device_id qnoc_of_match[] = {
|
||||
.data = &sc7180_dc_noc},
|
||||
{ .compatible = "qcom,sc7180-gem-noc",
|
||||
.data = &sc7180_gem_noc},
|
||||
{ .compatible = "qcom,sc7180-ipa-virt",
|
||||
.data = &sc7180_ipa_virt},
|
||||
{ .compatible = "qcom,sc7180-mc-virt",
|
||||
.data = &sc7180_mc_virt},
|
||||
{ .compatible = "qcom,sc7180-mmss-noc",
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "icc-rpmh.h"
|
||||
#include "sdx55.h"
|
||||
|
||||
DEFINE_QNODE(ipa_core_master, SDX55_MASTER_IPA_CORE, 1, 8, SDX55_SLAVE_IPA_CORE);
|
||||
DEFINE_QNODE(llcc_mc, SDX55_MASTER_LLCC, 4, 4, SDX55_SLAVE_EBI_CH0);
|
||||
DEFINE_QNODE(acm_tcu, SDX55_MASTER_TCU_0, 1, 8, SDX55_SLAVE_LLCC, SDX55_SLAVE_MEM_NOC_SNOC, SDX55_SLAVE_MEM_NOC_PCIE_SNOC);
|
||||
DEFINE_QNODE(qnm_snoc_gc, SDX55_MASTER_SNOC_GC_MEM_NOC, 1, 8, SDX55_SLAVE_LLCC);
|
||||
@@ -40,7 +39,6 @@ DEFINE_QNODE(xm_pcie, SDX55_MASTER_PCIE, 1, 8, SDX55_SLAVE_ANOC_SNOC);
|
||||
DEFINE_QNODE(xm_qdss_etr, SDX55_MASTER_QDSS_ETR, 1, 8, SDX55_SLAVE_SNOC_CFG, SDX55_SLAVE_EMAC_CFG, SDX55_SLAVE_USB3, SDX55_SLAVE_AOSS, SDX55_SLAVE_SPMI_FETCHER, SDX55_SLAVE_QDSS_CFG, SDX55_SLAVE_PDM, SDX55_SLAVE_SNOC_MEM_NOC_GC, SDX55_SLAVE_TCSR, SDX55_SLAVE_CNOC_DDRSS, SDX55_SLAVE_SPMI_VGI_COEX, SDX55_SLAVE_QPIC, SDX55_SLAVE_OCIMEM, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_USB3_PHY_CFG, SDX55_SLAVE_AOP, SDX55_SLAVE_BLSP_1, SDX55_SLAVE_SDCC_1, SDX55_SLAVE_CNOC_MSS, SDX55_SLAVE_PCIE_PARF, SDX55_SLAVE_ECC_CFG, SDX55_SLAVE_AUDIO, SDX55_SLAVE_AOSS, SDX55_SLAVE_PRNG, SDX55_SLAVE_CRYPTO_0_CFG, SDX55_SLAVE_TCU, SDX55_SLAVE_CLK_CTL, SDX55_SLAVE_IMEM_CFG);
|
||||
DEFINE_QNODE(xm_sdc1, SDX55_MASTER_SDCC_1, 1, 8, SDX55_SLAVE_AOSS, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_ANOC_SNOC, SDX55_SLAVE_AOP, SDX55_SLAVE_AUDIO);
|
||||
DEFINE_QNODE(xm_usb3, SDX55_MASTER_USB3, 1, 8, SDX55_SLAVE_ANOC_SNOC);
|
||||
DEFINE_QNODE(ipa_core_slave, SDX55_SLAVE_IPA_CORE, 1, 8);
|
||||
DEFINE_QNODE(ebi, SDX55_SLAVE_EBI_CH0, 1, 4);
|
||||
DEFINE_QNODE(qns_llcc, SDX55_SLAVE_LLCC, 1, 16, SDX55_SLAVE_EBI_CH0);
|
||||
DEFINE_QNODE(qns_memnoc_snoc, SDX55_SLAVE_MEM_NOC_SNOC, 1, 8, SDX55_MASTER_MEM_NOC_SNOC);
|
||||
@@ -82,7 +80,6 @@ DEFINE_QNODE(xs_sys_tcu_cfg, SDX55_SLAVE_TCU, 1, 8);
|
||||
DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi);
|
||||
DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc);
|
||||
DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto);
|
||||
DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave);
|
||||
DEFINE_QBCM(bcm_pn0, "PN0", false, &qhm_snoc_cfg);
|
||||
DEFINE_QBCM(bcm_sh3, "SH3", false, &xm_apps_rdwr);
|
||||
DEFINE_QBCM(bcm_sh4, "SH4", false, &qns_memnoc_snoc, &qns_sys_pcie);
|
||||
@@ -219,22 +216,6 @@ static const struct qcom_icc_desc sdx55_system_noc = {
|
||||
.num_bcms = ARRAY_SIZE(system_noc_bcms),
|
||||
};
|
||||
|
||||
static struct qcom_icc_bcm *ipa_virt_bcms[] = {
|
||||
&bcm_ip0,
|
||||
};
|
||||
|
||||
static struct qcom_icc_node *ipa_virt_nodes[] = {
|
||||
[MASTER_IPA_CORE] = &ipa_core_master,
|
||||
[SLAVE_IPA_CORE] = &ipa_core_slave,
|
||||
};
|
||||
|
||||
static const struct qcom_icc_desc sdx55_ipa_virt = {
|
||||
.nodes = ipa_virt_nodes,
|
||||
.num_nodes = ARRAY_SIZE(ipa_virt_nodes),
|
||||
.bcms = ipa_virt_bcms,
|
||||
.num_bcms = ARRAY_SIZE(ipa_virt_bcms),
|
||||
};
|
||||
|
||||
static const struct of_device_id qnoc_of_match[] = {
|
||||
{ .compatible = "qcom,sdx55-mc-virt",
|
||||
.data = &sdx55_mc_virt},
|
||||
@@ -242,8 +223,6 @@ static const struct of_device_id qnoc_of_match[] = {
|
||||
.data = &sdx55_mem_noc},
|
||||
{ .compatible = "qcom,sdx55-system-noc",
|
||||
.data = &sdx55_system_noc},
|
||||
{ .compatible = "qcom,sdx55-ipa-virt",
|
||||
.data = &sdx55_ipa_virt},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qnoc_of_match);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
*/
|
||||
|
||||
#define FM25_SN_LEN 8 /* serial number length */
|
||||
#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
|
||||
|
||||
struct at25_data {
|
||||
struct spi_eeprom chip;
|
||||
struct spi_device *spi;
|
||||
@@ -39,6 +41,7 @@ struct at25_data {
|
||||
struct nvmem_config nvmem_config;
|
||||
struct nvmem_device *nvmem;
|
||||
u8 sernum[FM25_SN_LEN];
|
||||
u8 command[EE_MAXADDRLEN + 1];
|
||||
};
|
||||
|
||||
#define AT25_WREN 0x06 /* latch the write enable */
|
||||
@@ -61,8 +64,6 @@ struct at25_data {
|
||||
|
||||
#define FM25_ID_LEN 9 /* ID length */
|
||||
|
||||
#define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */
|
||||
|
||||
/*
|
||||
* Specs often allow 5ms for a page write, sometimes 20ms;
|
||||
* it's important to recover from write timeouts.
|
||||
@@ -78,7 +79,6 @@ static int at25_ee_read(void *priv, unsigned int offset,
|
||||
{
|
||||
struct at25_data *at25 = priv;
|
||||
char *buf = val;
|
||||
u8 command[EE_MAXADDRLEN + 1];
|
||||
u8 *cp;
|
||||
ssize_t status;
|
||||
struct spi_transfer t[2];
|
||||
@@ -92,12 +92,15 @@ static int at25_ee_read(void *priv, unsigned int offset,
|
||||
if (unlikely(!count))
|
||||
return -EINVAL;
|
||||
|
||||
cp = command;
|
||||
cp = at25->command;
|
||||
|
||||
instr = AT25_READ;
|
||||
if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
|
||||
if (offset >= BIT(at25->addrlen * 8))
|
||||
instr |= AT25_INSTR_BIT3;
|
||||
|
||||
mutex_lock(&at25->lock);
|
||||
|
||||
*cp++ = instr;
|
||||
|
||||
/* 8/16/24-bit address is written MSB first */
|
||||
@@ -116,7 +119,7 @@ static int at25_ee_read(void *priv, unsigned int offset,
|
||||
spi_message_init(&m);
|
||||
memset(t, 0, sizeof(t));
|
||||
|
||||
t[0].tx_buf = command;
|
||||
t[0].tx_buf = at25->command;
|
||||
t[0].len = at25->addrlen + 1;
|
||||
spi_message_add_tail(&t[0], &m);
|
||||
|
||||
@@ -124,8 +127,6 @@ static int at25_ee_read(void *priv, unsigned int offset,
|
||||
t[1].len = count;
|
||||
spi_message_add_tail(&t[1], &m);
|
||||
|
||||
mutex_lock(&at25->lock);
|
||||
|
||||
/*
|
||||
* Read it all at once.
|
||||
*
|
||||
@@ -152,7 +153,7 @@ static int fm25_aux_read(struct at25_data *at25, u8 *buf, uint8_t command,
|
||||
spi_message_init(&m);
|
||||
memset(t, 0, sizeof(t));
|
||||
|
||||
t[0].tx_buf = &command;
|
||||
t[0].tx_buf = at25->command;
|
||||
t[0].len = 1;
|
||||
spi_message_add_tail(&t[0], &m);
|
||||
|
||||
@@ -162,6 +163,8 @@ static int fm25_aux_read(struct at25_data *at25, u8 *buf, uint8_t command,
|
||||
|
||||
mutex_lock(&at25->lock);
|
||||
|
||||
at25->command[0] = command;
|
||||
|
||||
status = spi_sync(at25->spi, &m);
|
||||
dev_dbg(&at25->spi->dev, "read %d aux bytes --> %d\n", len, status);
|
||||
|
||||
|
||||
@@ -414,19 +414,19 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
|
||||
|
||||
ret = clk_prepare_enable(priv->clk_ref);
|
||||
if (ret)
|
||||
goto err_disable_clk_ref;
|
||||
return ret;
|
||||
|
||||
priv->reset = devm_reset_control_array_get_exclusive(dev);
|
||||
if (IS_ERR(priv->reset))
|
||||
return PTR_ERR(priv->reset);
|
||||
if (IS_ERR(priv->reset)) {
|
||||
ret = PTR_ERR(priv->reset);
|
||||
goto err_disable_clk_ref;
|
||||
}
|
||||
|
||||
priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops);
|
||||
if (IS_ERR(priv->phy)) {
|
||||
ret = PTR_ERR(priv->phy);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
|
||||
return ret;
|
||||
dev_err_probe(dev, ret, "failed to create PHY\n");
|
||||
goto err_disable_clk_ref;
|
||||
}
|
||||
|
||||
phy_set_drvdata(priv->phy, priv);
|
||||
@@ -434,8 +434,12 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev)
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev,
|
||||
phy_g12a_usb3_pcie_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto err_disable_clk_ref;
|
||||
}
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
return 0;
|
||||
|
||||
err_disable_clk_ref:
|
||||
clk_disable_unprepare(priv->clk_ref);
|
||||
|
||||
@@ -629,7 +629,8 @@ idle:
|
||||
cleanup:
|
||||
if (error < 0)
|
||||
phy_mdm6600_device_power_off(ddata);
|
||||
|
||||
pm_runtime_disable(ddata->dev);
|
||||
pm_runtime_dont_use_autosuspend(ddata->dev);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
|
||||
return -EINVAL;
|
||||
|
||||
sata_phy->client = of_find_i2c_device_by_node(node);
|
||||
of_node_put(node);
|
||||
if (!sata_phy->client)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
@@ -195,20 +196,21 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
|
||||
sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl");
|
||||
if (IS_ERR(sata_phy->phyclk)) {
|
||||
dev_err(dev, "failed to get clk for PHY\n");
|
||||
return PTR_ERR(sata_phy->phyclk);
|
||||
ret = PTR_ERR(sata_phy->phyclk);
|
||||
goto put_dev;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(sata_phy->phyclk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to enable source clk\n");
|
||||
return ret;
|
||||
goto put_dev;
|
||||
}
|
||||
|
||||
sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops);
|
||||
if (IS_ERR(sata_phy->phy)) {
|
||||
clk_disable_unprepare(sata_phy->phyclk);
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
return PTR_ERR(sata_phy->phy);
|
||||
ret = PTR_ERR(sata_phy->phy);
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
phy_set_drvdata(sata_phy->phy, sata_phy);
|
||||
@@ -216,11 +218,18 @@ static int exynos_sata_phy_probe(struct platform_device *pdev)
|
||||
phy_provider = devm_of_phy_provider_register(dev,
|
||||
of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
clk_disable_unprepare(sata_phy->phyclk);
|
||||
return PTR_ERR(phy_provider);
|
||||
ret = PTR_ERR(phy_provider);
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
clk_disable:
|
||||
clk_disable_unprepare(sata_phy->phyclk);
|
||||
put_dev:
|
||||
put_device(&sata_phy->client->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id exynos_sata_phy_of_match[] = {
|
||||
|
||||
@@ -838,7 +838,7 @@ static int serdes_am654_probe(struct platform_device *pdev)
|
||||
|
||||
clk_err:
|
||||
of_clk_del_provider(node);
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ static int omap_usb2_enable_clocks(struct omap_usb *phy)
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
clk_disable(phy->wkupclk);
|
||||
clk_disable_unprepare(phy->wkupclk);
|
||||
|
||||
err0:
|
||||
return ret;
|
||||
|
||||
@@ -696,6 +696,7 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
|
||||
}
|
||||
|
||||
control_pdev = of_find_device_by_node(control_node);
|
||||
of_node_put(control_node);
|
||||
if (!control_pdev) {
|
||||
dev_err(dev, "Failed to get control device\n");
|
||||
return -EINVAL;
|
||||
|
||||
@@ -155,7 +155,7 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_POWER_SUPPLY
|
||||
const char * const tusb1210_chg_det_states[] = {
|
||||
static const char * const tusb1210_chg_det_states[] = {
|
||||
"CHG_DET_CONNECTING",
|
||||
"CHG_DET_START_DET",
|
||||
"CHG_DET_READ_DET",
|
||||
@@ -537,12 +537,18 @@ static int tusb1210_probe(struct ulpi *ulpi)
|
||||
tusb1210_probe_charger_detect(tusb);
|
||||
|
||||
tusb->phy = ulpi_phy_create(ulpi, &phy_ops);
|
||||
if (IS_ERR(tusb->phy))
|
||||
return PTR_ERR(tusb->phy);
|
||||
if (IS_ERR(tusb->phy)) {
|
||||
ret = PTR_ERR(tusb->phy);
|
||||
goto err_remove_charger;
|
||||
}
|
||||
|
||||
phy_set_drvdata(tusb->phy, tusb);
|
||||
ulpi_set_drvdata(ulpi, tusb);
|
||||
return 0;
|
||||
|
||||
err_remove_charger:
|
||||
tusb1210_remove_charger_detect(tusb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tusb1210_remove(struct ulpi *ulpi)
|
||||
|
||||
@@ -588,7 +588,7 @@ static void pscsi_destroy_device(struct se_device *dev)
|
||||
}
|
||||
|
||||
static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status,
|
||||
unsigned char *req_sense)
|
||||
unsigned char *req_sense, int valid_data)
|
||||
{
|
||||
struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev);
|
||||
struct scsi_device *sd = pdv->pdv_sd;
|
||||
@@ -681,7 +681,7 @@ after_mode_select:
|
||||
* back despite framework assumption that a
|
||||
* check condition means there is no data
|
||||
*/
|
||||
if (sd->type == TYPE_TAPE &&
|
||||
if (sd->type == TYPE_TAPE && valid_data &&
|
||||
cmd->data_direction == DMA_FROM_DEVICE) {
|
||||
/*
|
||||
* is sense data valid, fixed format,
|
||||
@@ -1032,6 +1032,7 @@ static void pscsi_req_done(struct request *req, blk_status_t status)
|
||||
struct se_cmd *cmd = req->end_io_data;
|
||||
struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
|
||||
enum sam_status scsi_status = scmd->result & 0xff;
|
||||
int valid_data = cmd->data_length - scmd->resid_len;
|
||||
u8 *cdb = cmd->priv;
|
||||
|
||||
if (scsi_status != SAM_STAT_GOOD) {
|
||||
@@ -1039,12 +1040,11 @@ static void pscsi_req_done(struct request *req, blk_status_t status)
|
||||
" 0x%02x Result: 0x%08x\n", cmd, cdb[0], scmd->result);
|
||||
}
|
||||
|
||||
pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer);
|
||||
pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer, valid_data);
|
||||
|
||||
switch (host_byte(scmd->result)) {
|
||||
case DID_OK:
|
||||
target_complete_cmd_with_length(cmd, scsi_status,
|
||||
cmd->data_length - scmd->resid_len);
|
||||
target_complete_cmd_with_length(cmd, scsi_status, valid_data);
|
||||
break;
|
||||
default:
|
||||
pr_debug("PSCSI Host Byte exception at cmd: %p CDB:"
|
||||
|
||||
+281
-206
@@ -73,6 +73,8 @@ module_param(debug, int, 0600);
|
||||
*/
|
||||
#define MAX_MRU 1500
|
||||
#define MAX_MTU 1500
|
||||
/* SOF, ADDR, CTRL, LEN1, LEN2, ..., FCS, EOF */
|
||||
#define PROT_OVERHEAD 7
|
||||
#define GSM_NET_TX_TIMEOUT (HZ*10)
|
||||
|
||||
/*
|
||||
@@ -219,7 +221,6 @@ struct gsm_mux {
|
||||
int encoding;
|
||||
u8 control;
|
||||
u8 fcs;
|
||||
u8 received_fcs;
|
||||
u8 *txframe; /* TX framing buffer */
|
||||
|
||||
/* Method for the receiver side */
|
||||
@@ -231,6 +232,7 @@ struct gsm_mux {
|
||||
int initiator; /* Did we initiate connection */
|
||||
bool dead; /* Has the mux been shut down */
|
||||
struct gsm_dlci *dlci[NUM_DLCI];
|
||||
int old_c_iflag; /* termios c_iflag value before attach */
|
||||
bool constipated; /* Asked by remote to shut up */
|
||||
|
||||
spinlock_t tx_lock;
|
||||
@@ -271,10 +273,6 @@ static DEFINE_SPINLOCK(gsm_mux_lock);
|
||||
|
||||
static struct tty_driver *gsm_tty_driver;
|
||||
|
||||
/* Save dlci open address */
|
||||
static int addr_open[256] = { 0 };
|
||||
/* Save dlci open count */
|
||||
static int addr_cnt;
|
||||
/*
|
||||
* This section of the driver logic implements the GSM encodings
|
||||
* both the basic and the 'advanced'. Reliable transport is not
|
||||
@@ -369,6 +367,7 @@ static const u8 gsm_fcs8[256] = {
|
||||
#define GOOD_FCS 0xCF
|
||||
|
||||
static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
|
||||
static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
|
||||
|
||||
/**
|
||||
* gsm_fcs_add - update FCS
|
||||
@@ -832,7 +831,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci)
|
||||
break;
|
||||
case 2: /* Unstructed with modem bits.
|
||||
Always one byte as we never send inline break data */
|
||||
*dp++ = gsm_encode_modem(dlci);
|
||||
*dp++ = (gsm_encode_modem(dlci) << 1) | EA;
|
||||
break;
|
||||
}
|
||||
WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len);
|
||||
@@ -916,6 +915,66 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_dlci_modem_output - try and push modem status out of a DLCI
|
||||
* @gsm: mux
|
||||
* @dlci: the DLCI to pull modem status from
|
||||
* @brk: break signal
|
||||
*
|
||||
* Push an empty frame in to the transmit queue to update the modem status
|
||||
* bits and to transmit an optional break.
|
||||
*
|
||||
* Caller must hold the tx_lock of the mux.
|
||||
*/
|
||||
|
||||
static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
|
||||
u8 brk)
|
||||
{
|
||||
u8 *dp = NULL;
|
||||
struct gsm_msg *msg;
|
||||
int size = 0;
|
||||
|
||||
/* for modem bits without break data */
|
||||
switch (dlci->adaption) {
|
||||
case 1: /* Unstructured */
|
||||
break;
|
||||
case 2: /* Unstructured with modem bits. */
|
||||
size++;
|
||||
if (brk > 0)
|
||||
size++;
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unsupported adaption %d\n", __func__,
|
||||
dlci->adaption);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
|
||||
if (!msg) {
|
||||
pr_err("%s: gsm_data_alloc error", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dp = msg->data;
|
||||
switch (dlci->adaption) {
|
||||
case 1: /* Unstructured */
|
||||
break;
|
||||
case 2: /* Unstructured with modem bits. */
|
||||
if (brk == 0) {
|
||||
*dp++ = (gsm_encode_modem(dlci) << 1) | EA;
|
||||
} else {
|
||||
*dp++ = gsm_encode_modem(dlci) << 1;
|
||||
*dp++ = (brk << 4) | 2 | EA; /* Length, Break, EA */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Handled above */
|
||||
break;
|
||||
}
|
||||
|
||||
__gsm_data_queue(dlci, msg);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_dlci_data_sweep - look for data to send
|
||||
* @gsm: the GSM mux
|
||||
@@ -1093,7 +1152,6 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
|
||||
{
|
||||
unsigned int addr = 0;
|
||||
unsigned int modem = 0;
|
||||
unsigned int brk = 0;
|
||||
struct gsm_dlci *dlci;
|
||||
int len = clen;
|
||||
int slen;
|
||||
@@ -1123,17 +1181,8 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen)
|
||||
return;
|
||||
}
|
||||
len--;
|
||||
if (len > 0) {
|
||||
while (gsm_read_ea(&brk, *dp++) == 0) {
|
||||
len--;
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
modem <<= 7;
|
||||
modem |= (brk & 0x7f);
|
||||
}
|
||||
tty = tty_port_tty_get(&dlci->port);
|
||||
gsm_process_modem(tty, dlci, modem, slen);
|
||||
gsm_process_modem(tty, dlci, modem, slen - len);
|
||||
if (tty) {
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
@@ -1193,7 +1242,6 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen)
|
||||
}
|
||||
|
||||
static void gsm_dlci_begin_close(struct gsm_dlci *dlci);
|
||||
static void gsm_dlci_close(struct gsm_dlci *dlci);
|
||||
|
||||
/**
|
||||
* gsm_control_message - DLCI 0 control processing
|
||||
@@ -1212,28 +1260,15 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
|
||||
{
|
||||
u8 buf[1];
|
||||
unsigned long flags;
|
||||
struct gsm_dlci *dlci;
|
||||
int i;
|
||||
int address;
|
||||
|
||||
switch (command) {
|
||||
case CMD_CLD: {
|
||||
if (addr_cnt > 0) {
|
||||
for (i = 0; i < addr_cnt; i++) {
|
||||
address = addr_open[i];
|
||||
dlci = gsm->dlci[address];
|
||||
gsm_dlci_close(dlci);
|
||||
addr_open[i] = 0;
|
||||
}
|
||||
}
|
||||
struct gsm_dlci *dlci = gsm->dlci[0];
|
||||
/* Modem wishes to close down */
|
||||
dlci = gsm->dlci[0];
|
||||
if (dlci) {
|
||||
dlci->dead = true;
|
||||
gsm->dead = true;
|
||||
gsm_dlci_close(dlci);
|
||||
addr_cnt = 0;
|
||||
gsm_response(gsm, 0, UA|PF);
|
||||
gsm_dlci_begin_close(dlci);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1326,11 +1361,12 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command,
|
||||
|
||||
static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl)
|
||||
{
|
||||
struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1, gsm->ftype);
|
||||
struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 2, gsm->ftype);
|
||||
if (msg == NULL)
|
||||
return;
|
||||
msg->data[0] = (ctrl->cmd << 1) | 2 | EA; /* command */
|
||||
memcpy(msg->data + 1, ctrl->data, ctrl->len);
|
||||
msg->data[0] = (ctrl->cmd << 1) | CR | EA; /* command */
|
||||
msg->data[1] = (ctrl->len << 1) | EA;
|
||||
memcpy(msg->data + 2, ctrl->data, ctrl->len);
|
||||
gsm_data_queue(gsm->dlci[0], msg);
|
||||
}
|
||||
|
||||
@@ -1353,7 +1389,6 @@ static void gsm_control_retransmit(struct timer_list *t)
|
||||
spin_lock_irqsave(&gsm->control_lock, flags);
|
||||
ctrl = gsm->pending_cmd;
|
||||
if (ctrl) {
|
||||
gsm->cretries--;
|
||||
if (gsm->cretries == 0) {
|
||||
gsm->pending_cmd = NULL;
|
||||
ctrl->error = -ETIMEDOUT;
|
||||
@@ -1362,6 +1397,7 @@ static void gsm_control_retransmit(struct timer_list *t)
|
||||
wake_up(&gsm->event);
|
||||
return;
|
||||
}
|
||||
gsm->cretries--;
|
||||
gsm_control_transmit(gsm, ctrl);
|
||||
mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
|
||||
}
|
||||
@@ -1402,7 +1438,7 @@ retry:
|
||||
|
||||
/* If DLCI0 is in ADM mode skip retries, it won't respond */
|
||||
if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
|
||||
gsm->cretries = 1;
|
||||
gsm->cretries = 0;
|
||||
else
|
||||
gsm->cretries = gsm->n2;
|
||||
|
||||
@@ -1450,20 +1486,22 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control)
|
||||
|
||||
static void gsm_dlci_close(struct gsm_dlci *dlci)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
del_timer(&dlci->t1);
|
||||
if (debug & 8)
|
||||
pr_debug("DLCI %d goes closed.\n", dlci->addr);
|
||||
dlci->state = DLCI_CLOSED;
|
||||
if (dlci->addr != 0) {
|
||||
tty_port_tty_hangup(&dlci->port, false);
|
||||
spin_lock_irqsave(&dlci->lock, flags);
|
||||
kfifo_reset(&dlci->fifo);
|
||||
spin_unlock_irqrestore(&dlci->lock, flags);
|
||||
/* Ensure that gsmtty_open() can return. */
|
||||
tty_port_set_initialized(&dlci->port, 0);
|
||||
wake_up_interruptible(&dlci->port.open_wait);
|
||||
} else
|
||||
dlci->gsm->dead = true;
|
||||
/* Unregister gsmtty driver,report gsmtty dev remove uevent for user */
|
||||
tty_unregister_device(gsm_tty_driver, dlci->addr);
|
||||
wake_up(&dlci->gsm->event);
|
||||
/* A DLCI 0 close is a MUX termination so we need to kick that
|
||||
back to userspace somehow */
|
||||
@@ -1485,8 +1523,9 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
|
||||
dlci->state = DLCI_OPEN;
|
||||
if (debug & 8)
|
||||
pr_debug("DLCI %d goes open.\n", dlci->addr);
|
||||
/* Register gsmtty driver,report gsmtty dev add uevent for user */
|
||||
tty_register_device(gsm_tty_driver, dlci->addr, NULL);
|
||||
/* Send current modem state */
|
||||
if (dlci->addr)
|
||||
gsm_modem_update(dlci, 0);
|
||||
wake_up(&dlci->gsm->event);
|
||||
}
|
||||
|
||||
@@ -1623,6 +1662,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen)
|
||||
tty = tty_port_tty_get(port);
|
||||
if (tty) {
|
||||
gsm_process_modem(tty, dlci, modem, slen);
|
||||
tty_wakeup(tty);
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
fallthrough;
|
||||
@@ -1793,19 +1833,7 @@ static void gsm_queue(struct gsm_mux *gsm)
|
||||
struct gsm_dlci *dlci;
|
||||
u8 cr;
|
||||
int address;
|
||||
int i, j, k, address_tmp;
|
||||
/* We have to sneak a look at the packet body to do the FCS.
|
||||
A somewhat layering violation in the spec */
|
||||
|
||||
if ((gsm->control & ~PF) == UI)
|
||||
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
|
||||
if (gsm->encoding == 0) {
|
||||
/* WARNING: gsm->received_fcs is used for
|
||||
gsm->encoding = 0 only.
|
||||
In this case it contain the last piece of data
|
||||
required to generate final CRC */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs);
|
||||
}
|
||||
if (gsm->fcs != GOOD_FCS) {
|
||||
gsm->bad_fcs++;
|
||||
if (debug & 4)
|
||||
@@ -1836,11 +1864,6 @@ static void gsm_queue(struct gsm_mux *gsm)
|
||||
else {
|
||||
gsm_response(gsm, address, UA|PF);
|
||||
gsm_dlci_open(dlci);
|
||||
/* Save dlci open address */
|
||||
if (address) {
|
||||
addr_open[addr_cnt] = address;
|
||||
addr_cnt++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DISC|PF:
|
||||
@@ -1851,35 +1874,9 @@ static void gsm_queue(struct gsm_mux *gsm)
|
||||
return;
|
||||
}
|
||||
/* Real close complete */
|
||||
if (!address) {
|
||||
if (addr_cnt > 0) {
|
||||
for (i = 0; i < addr_cnt; i++) {
|
||||
address = addr_open[i];
|
||||
dlci = gsm->dlci[address];
|
||||
gsm_dlci_close(dlci);
|
||||
addr_open[i] = 0;
|
||||
}
|
||||
}
|
||||
dlci = gsm->dlci[0];
|
||||
gsm_dlci_close(dlci);
|
||||
addr_cnt = 0;
|
||||
gsm_response(gsm, 0, UA|PF);
|
||||
} else {
|
||||
gsm_response(gsm, address, UA|PF);
|
||||
gsm_dlci_close(dlci);
|
||||
/* clear dlci address */
|
||||
for (j = 0; j < addr_cnt; j++) {
|
||||
address_tmp = addr_open[j];
|
||||
if (address_tmp == address) {
|
||||
for (k = j; k < addr_cnt; k++)
|
||||
addr_open[k] = addr_open[k+1];
|
||||
addr_cnt--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gsm_response(gsm, address, UA|PF);
|
||||
gsm_dlci_close(dlci);
|
||||
break;
|
||||
case UA:
|
||||
case UA|PF:
|
||||
if (cr == 0 || dlci == NULL)
|
||||
break;
|
||||
@@ -1993,19 +1990,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
break;
|
||||
case GSM_DATA: /* Data */
|
||||
gsm->buf[gsm->count++] = c;
|
||||
if (gsm->count == gsm->len)
|
||||
if (gsm->count == gsm->len) {
|
||||
/* Calculate final FCS for UI frames over all data */
|
||||
if ((gsm->control & ~PF) != UIH) {
|
||||
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf,
|
||||
gsm->count);
|
||||
}
|
||||
gsm->state = GSM_FCS;
|
||||
}
|
||||
break;
|
||||
case GSM_FCS: /* FCS follows the packet */
|
||||
gsm->received_fcs = c;
|
||||
gsm_queue(gsm);
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
|
||||
gsm->state = GSM_SSOF;
|
||||
break;
|
||||
case GSM_SSOF:
|
||||
if (c == GSM0_SOF) {
|
||||
gsm->state = GSM_SEARCH;
|
||||
break;
|
||||
}
|
||||
gsm->state = GSM_SEARCH;
|
||||
if (c == GSM0_SOF)
|
||||
gsm_queue(gsm);
|
||||
else
|
||||
gsm->bad_size++;
|
||||
break;
|
||||
default:
|
||||
pr_debug("%s: unhandled state: %d\n", __func__, gsm->state);
|
||||
@@ -2023,12 +2026,35 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
|
||||
static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
{
|
||||
/* handle XON/XOFF */
|
||||
if ((c & ISO_IEC_646_MASK) == XON) {
|
||||
gsm->constipated = true;
|
||||
return;
|
||||
} else if ((c & ISO_IEC_646_MASK) == XOFF) {
|
||||
gsm->constipated = false;
|
||||
/* Kick the link in case it is idling */
|
||||
gsm_data_kick(gsm, NULL);
|
||||
return;
|
||||
}
|
||||
if (c == GSM1_SOF) {
|
||||
/* EOF is only valid in frame if we have got to the data state
|
||||
and received at least one byte (the FCS) */
|
||||
if (gsm->state == GSM_DATA && gsm->count) {
|
||||
/* Extract the FCS */
|
||||
/* EOF is only valid in frame if we have got to the data state */
|
||||
if (gsm->state == GSM_DATA) {
|
||||
if (gsm->count < 1) {
|
||||
/* Missing FSC */
|
||||
gsm->malformed++;
|
||||
gsm->state = GSM_START;
|
||||
return;
|
||||
}
|
||||
/* Remove the FCS from data */
|
||||
gsm->count--;
|
||||
if ((gsm->control & ~PF) != UIH) {
|
||||
/* Calculate final FCS for UI frames over all
|
||||
* data but FCS
|
||||
*/
|
||||
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf,
|
||||
gsm->count);
|
||||
}
|
||||
/* Add the FCS itself to test against GOOD_FCS */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]);
|
||||
gsm->len = gsm->count;
|
||||
gsm_queue(gsm);
|
||||
@@ -2037,7 +2063,8 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
}
|
||||
/* Any partial frame was a runt so go back to start */
|
||||
if (gsm->state != GSM_START) {
|
||||
gsm->malformed++;
|
||||
if (gsm->state != GSM_SEARCH)
|
||||
gsm->malformed++;
|
||||
gsm->state = GSM_START;
|
||||
}
|
||||
/* A SOF in GSM_START means we are still reading idling or
|
||||
@@ -2106,74 +2133,43 @@ static void gsm_error(struct gsm_mux *gsm)
|
||||
gsm->io_error++;
|
||||
}
|
||||
|
||||
static int gsm_disconnect(struct gsm_mux *gsm)
|
||||
{
|
||||
struct gsm_dlci *dlci = gsm->dlci[0];
|
||||
struct gsm_control *gc;
|
||||
|
||||
if (!dlci)
|
||||
return 0;
|
||||
|
||||
/* In theory disconnecting DLCI 0 is sufficient but for some
|
||||
modems this is apparently not the case. */
|
||||
gc = gsm_control_send(gsm, CMD_CLD, NULL, 0);
|
||||
if (gc)
|
||||
gsm_control_wait(gsm, gc);
|
||||
|
||||
del_timer_sync(&gsm->t2_timer);
|
||||
/* Now we are sure T2 has stopped */
|
||||
|
||||
gsm_dlci_begin_close(dlci);
|
||||
wait_event_interruptible(gsm->event,
|
||||
dlci->state == DLCI_CLOSED);
|
||||
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_cleanup_mux - generic GSM protocol cleanup
|
||||
* @gsm: our mux
|
||||
* @disc: disconnect link?
|
||||
*
|
||||
* Clean up the bits of the mux which are the same for all framing
|
||||
* protocols. Remove the mux from the mux table, stop all the timers
|
||||
* and then shut down each device hanging up the channels as we go.
|
||||
*/
|
||||
|
||||
static void gsm_cleanup_mux(struct gsm_mux *gsm)
|
||||
static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc)
|
||||
{
|
||||
int i;
|
||||
struct gsm_dlci *dlci = gsm->dlci[0];
|
||||
struct gsm_msg *txq, *ntxq;
|
||||
|
||||
gsm->dead = true;
|
||||
|
||||
spin_lock(&gsm_mux_lock);
|
||||
for (i = 0; i < MAX_MUX; i++) {
|
||||
if (gsm_mux[i] == gsm) {
|
||||
gsm_mux[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&gsm_mux_lock);
|
||||
/* open failed before registering => nothing to do */
|
||||
if (i == MAX_MUX)
|
||||
return;
|
||||
|
||||
del_timer_sync(&gsm->t2_timer);
|
||||
/* Now we are sure T2 has stopped */
|
||||
if (dlci)
|
||||
dlci->dead = true;
|
||||
|
||||
/* Free up any link layer users */
|
||||
mutex_lock(&gsm->mutex);
|
||||
for (i = 0; i < NUM_DLCI; i++)
|
||||
|
||||
if (dlci) {
|
||||
if (disc && dlci->state != DLCI_CLOSED) {
|
||||
gsm_dlci_begin_close(dlci);
|
||||
wait_event(gsm->event, dlci->state == DLCI_CLOSED);
|
||||
}
|
||||
dlci->dead = true;
|
||||
}
|
||||
|
||||
/* Finish outstanding timers, making sure they are done */
|
||||
del_timer_sync(&gsm->t2_timer);
|
||||
|
||||
/* Free up any link layer users and finally the control channel */
|
||||
for (i = NUM_DLCI - 1; i >= 0; i--)
|
||||
if (gsm->dlci[i])
|
||||
gsm_dlci_release(gsm->dlci[i]);
|
||||
mutex_unlock(&gsm->mutex);
|
||||
/* Now wipe the queues */
|
||||
tty_ldisc_flush(gsm->tty);
|
||||
list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
|
||||
kfree(txq);
|
||||
INIT_LIST_HEAD(&gsm->tx_list);
|
||||
@@ -2191,7 +2187,6 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
|
||||
static int gsm_activate_mux(struct gsm_mux *gsm)
|
||||
{
|
||||
struct gsm_dlci *dlci;
|
||||
int i = 0;
|
||||
|
||||
timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
|
||||
init_waitqueue_head(&gsm->event);
|
||||
@@ -2203,18 +2198,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
|
||||
else
|
||||
gsm->receive = gsm1_receive;
|
||||
|
||||
spin_lock(&gsm_mux_lock);
|
||||
for (i = 0; i < MAX_MUX; i++) {
|
||||
if (gsm_mux[i] == NULL) {
|
||||
gsm->num = i;
|
||||
gsm_mux[i] = gsm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&gsm_mux_lock);
|
||||
if (i == MAX_MUX)
|
||||
return -EBUSY;
|
||||
|
||||
dlci = gsm_dlci_alloc(gsm, 0);
|
||||
if (dlci == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -2230,6 +2213,15 @@ static int gsm_activate_mux(struct gsm_mux *gsm)
|
||||
*/
|
||||
static void gsm_free_mux(struct gsm_mux *gsm)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_MUX; i++) {
|
||||
if (gsm == gsm_mux[i]) {
|
||||
gsm_mux[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_destroy(&gsm->mutex);
|
||||
kfree(gsm->txframe);
|
||||
kfree(gsm->buf);
|
||||
kfree(gsm);
|
||||
@@ -2249,12 +2241,20 @@ static void gsm_free_muxr(struct kref *ref)
|
||||
|
||||
static inline void mux_get(struct gsm_mux *gsm)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gsm_mux_lock, flags);
|
||||
kref_get(&gsm->ref);
|
||||
spin_unlock_irqrestore(&gsm_mux_lock, flags);
|
||||
}
|
||||
|
||||
static inline void mux_put(struct gsm_mux *gsm)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gsm_mux_lock, flags);
|
||||
kref_put(&gsm->ref, gsm_free_muxr);
|
||||
spin_unlock_irqrestore(&gsm_mux_lock, flags);
|
||||
}
|
||||
|
||||
static inline unsigned int mux_num_to_base(struct gsm_mux *gsm)
|
||||
@@ -2275,6 +2275,7 @@ static inline unsigned int mux_line_to_num(unsigned int line)
|
||||
|
||||
static struct gsm_mux *gsm_alloc_mux(void)
|
||||
{
|
||||
int i;
|
||||
struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL);
|
||||
if (gsm == NULL)
|
||||
return NULL;
|
||||
@@ -2283,7 +2284,7 @@ static struct gsm_mux *gsm_alloc_mux(void)
|
||||
kfree(gsm);
|
||||
return NULL;
|
||||
}
|
||||
gsm->txframe = kmalloc(2 * MAX_MRU + 2, GFP_KERNEL);
|
||||
gsm->txframe = kmalloc(2 * (MAX_MTU + PROT_OVERHEAD - 1), GFP_KERNEL);
|
||||
if (gsm->txframe == NULL) {
|
||||
kfree(gsm->buf);
|
||||
kfree(gsm);
|
||||
@@ -2304,6 +2305,26 @@ static struct gsm_mux *gsm_alloc_mux(void)
|
||||
gsm->mtu = 64;
|
||||
gsm->dead = true; /* Avoid early tty opens */
|
||||
|
||||
/* Store the instance to the mux array or abort if no space is
|
||||
* available.
|
||||
*/
|
||||
spin_lock(&gsm_mux_lock);
|
||||
for (i = 0; i < MAX_MUX; i++) {
|
||||
if (!gsm_mux[i]) {
|
||||
gsm_mux[i] = gsm;
|
||||
gsm->num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&gsm_mux_lock);
|
||||
if (i == MAX_MUX) {
|
||||
mutex_destroy(&gsm->mutex);
|
||||
kfree(gsm->txframe);
|
||||
kfree(gsm->buf);
|
||||
kfree(gsm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gsm;
|
||||
}
|
||||
|
||||
@@ -2339,7 +2360,7 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
|
||||
/* Check the MRU/MTU range looks sane */
|
||||
if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
|
||||
return -EINVAL;
|
||||
if (c->n2 < 3)
|
||||
if (c->n2 > 255)
|
||||
return -EINVAL;
|
||||
if (c->encapsulation > 1) /* Basic, advanced, no I */
|
||||
return -EINVAL;
|
||||
@@ -2370,19 +2391,11 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
|
||||
|
||||
/*
|
||||
* Close down what is needed, restart and initiate the new
|
||||
* configuration
|
||||
* configuration. On the first time there is no DLCI[0]
|
||||
* and closing or cleaning up is not necessary.
|
||||
*/
|
||||
|
||||
if (gsm->initiator && (need_close || need_restart)) {
|
||||
int ret;
|
||||
|
||||
ret = gsm_disconnect(gsm);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (need_restart)
|
||||
gsm_cleanup_mux(gsm);
|
||||
if (need_close || need_restart)
|
||||
gsm_cleanup_mux(gsm, true);
|
||||
|
||||
gsm->initiator = c->initiator;
|
||||
gsm->mru = c->mru;
|
||||
@@ -2450,25 +2463,26 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
|
||||
int ret, i;
|
||||
|
||||
gsm->tty = tty_kref_get(tty);
|
||||
/* Turn off tty XON/XOFF handling to handle it explicitly. */
|
||||
gsm->old_c_iflag = tty->termios.c_iflag;
|
||||
tty->termios.c_iflag &= (IXON | IXOFF);
|
||||
ret = gsm_activate_mux(gsm);
|
||||
if (ret != 0)
|
||||
tty_kref_put(gsm->tty);
|
||||
else {
|
||||
/* Don't register device 0 - this is the control channel and not
|
||||
a usable tty interface */
|
||||
if (gsm->initiator) {
|
||||
base = mux_num_to_base(gsm); /* Base for this MUX */
|
||||
for (i = 1; i < NUM_DLCI; i++) {
|
||||
struct device *dev;
|
||||
base = mux_num_to_base(gsm); /* Base for this MUX */
|
||||
for (i = 1; i < NUM_DLCI; i++) {
|
||||
struct device *dev;
|
||||
|
||||
dev = tty_register_device(gsm_tty_driver,
|
||||
dev = tty_register_device(gsm_tty_driver,
|
||||
base + i, NULL);
|
||||
if (IS_ERR(dev)) {
|
||||
for (i--; i >= 1; i--)
|
||||
tty_unregister_device(gsm_tty_driver,
|
||||
base + i);
|
||||
return PTR_ERR(dev);
|
||||
}
|
||||
if (IS_ERR(dev)) {
|
||||
for (i--; i >= 1; i--)
|
||||
tty_unregister_device(gsm_tty_driver,
|
||||
base + i);
|
||||
return PTR_ERR(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2490,11 +2504,10 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
|
||||
int i;
|
||||
|
||||
WARN_ON(tty != gsm->tty);
|
||||
if (gsm->initiator) {
|
||||
for (i = 1; i < NUM_DLCI; i++)
|
||||
tty_unregister_device(gsm_tty_driver, base + i);
|
||||
}
|
||||
gsm_cleanup_mux(gsm);
|
||||
for (i = 1; i < NUM_DLCI; i++)
|
||||
tty_unregister_device(gsm_tty_driver, base + i);
|
||||
/* Restore tty XON/XOFF handling. */
|
||||
gsm->tty->termios.c_iflag = gsm->old_c_iflag;
|
||||
tty_kref_put(gsm->tty);
|
||||
gsm->tty = NULL;
|
||||
}
|
||||
@@ -2559,6 +2572,12 @@ static void gsmld_close(struct tty_struct *tty)
|
||||
{
|
||||
struct gsm_mux *gsm = tty->disc_data;
|
||||
|
||||
/* The ldisc locks and closes the port before calling our close. This
|
||||
* means we have no way to do a proper disconnect. We will not bother
|
||||
* to do one.
|
||||
*/
|
||||
gsm_cleanup_mux(gsm, false);
|
||||
|
||||
gsmld_detach_gsm(tty, gsm);
|
||||
|
||||
gsmld_flush_buffer(tty);
|
||||
@@ -2597,7 +2616,7 @@ static int gsmld_open(struct tty_struct *tty)
|
||||
|
||||
ret = gsmld_attach_gsm(tty, gsm);
|
||||
if (ret != 0) {
|
||||
gsm_cleanup_mux(gsm);
|
||||
gsm_cleanup_mux(gsm, false);
|
||||
mux_put(gsm);
|
||||
}
|
||||
return ret;
|
||||
@@ -2954,26 +2973,78 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
|
||||
|
||||
#define TX_SIZE 512
|
||||
|
||||
static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
|
||||
/**
|
||||
* gsm_modem_upd_via_data - send modem bits via convergence layer
|
||||
* @dlci: channel
|
||||
* @brk: break signal
|
||||
*
|
||||
* Send an empty frame to signal mobile state changes and to transmit the
|
||||
* break signal for adaption 2.
|
||||
*/
|
||||
|
||||
static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
|
||||
{
|
||||
u8 modembits[5];
|
||||
struct gsm_mux *gsm = dlci->gsm;
|
||||
unsigned long flags;
|
||||
|
||||
if (dlci->state != DLCI_OPEN || dlci->adaption != 2)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&gsm->tx_lock, flags);
|
||||
gsm_dlci_modem_output(gsm, dlci, brk);
|
||||
spin_unlock_irqrestore(&gsm->tx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_modem_upd_via_msc - send modem bits via control frame
|
||||
* @dlci: channel
|
||||
* @brk: break signal
|
||||
*/
|
||||
|
||||
static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
|
||||
{
|
||||
u8 modembits[3];
|
||||
struct gsm_control *ctrl;
|
||||
int len = 2;
|
||||
|
||||
if (brk)
|
||||
len++;
|
||||
if (dlci->gsm->encoding != 0)
|
||||
return 0;
|
||||
|
||||
modembits[0] = len << 1 | EA; /* Data bytes */
|
||||
modembits[1] = dlci->addr << 2 | 3; /* DLCI, EA, 1 */
|
||||
modembits[2] = gsm_encode_modem(dlci) << 1 | EA;
|
||||
if (brk)
|
||||
modembits[3] = brk << 4 | 2 | EA; /* Valid, EA */
|
||||
ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len + 1);
|
||||
modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */
|
||||
if (!brk) {
|
||||
modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
|
||||
} else {
|
||||
modembits[1] = gsm_encode_modem(dlci) << 1;
|
||||
modembits[2] = (brk << 4) | 2 | EA; /* Length, Break, EA */
|
||||
len++;
|
||||
}
|
||||
ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len);
|
||||
if (ctrl == NULL)
|
||||
return -ENOMEM;
|
||||
return gsm_control_wait(dlci->gsm, ctrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_modem_update - send modem status line state
|
||||
* @dlci: channel
|
||||
* @brk: break signal
|
||||
*/
|
||||
|
||||
static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk)
|
||||
{
|
||||
if (dlci->adaption == 2) {
|
||||
/* Send convergence layer type 2 empty data frame. */
|
||||
gsm_modem_upd_via_data(dlci, brk);
|
||||
return 0;
|
||||
} else if (dlci->gsm->encoding == 0) {
|
||||
/* Send as MSC control message. */
|
||||
return gsm_modem_upd_via_msc(dlci, brk);
|
||||
}
|
||||
|
||||
/* Modem status lines are not supported. */
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
static int gsm_carrier_raised(struct tty_port *port)
|
||||
{
|
||||
struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
|
||||
@@ -3006,7 +3077,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff)
|
||||
modem_tx &= ~(TIOCM_DTR | TIOCM_RTS);
|
||||
if (modem_tx != dlci->modem_tx) {
|
||||
dlci->modem_tx = modem_tx;
|
||||
gsmtty_modem_update(dlci, 0);
|
||||
gsm_modem_update(dlci, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3155,13 +3226,17 @@ static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty)
|
||||
static void gsmtty_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct gsm_dlci *dlci = tty->driver_data;
|
||||
unsigned long flags;
|
||||
|
||||
if (dlci->state == DLCI_CLOSED)
|
||||
return;
|
||||
/* Caution needed: If we implement reliable transport classes
|
||||
then the data being transmitted can't simply be junked once
|
||||
it has first hit the stack. Until then we can just blow it
|
||||
away */
|
||||
spin_lock_irqsave(&dlci->lock, flags);
|
||||
kfifo_reset(&dlci->fifo);
|
||||
spin_unlock_irqrestore(&dlci->lock, flags);
|
||||
/* Need to unhook this DLCI from the transmit queue logic */
|
||||
}
|
||||
|
||||
@@ -3193,7 +3268,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty,
|
||||
|
||||
if (modem_tx != dlci->modem_tx) {
|
||||
dlci->modem_tx = modem_tx;
|
||||
return gsmtty_modem_update(dlci, 0);
|
||||
return gsm_modem_update(dlci, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3254,7 +3329,7 @@ static void gsmtty_throttle(struct tty_struct *tty)
|
||||
dlci->modem_tx &= ~TIOCM_RTS;
|
||||
dlci->throttled = true;
|
||||
/* Send an MSC with RTS cleared */
|
||||
gsmtty_modem_update(dlci, 0);
|
||||
gsm_modem_update(dlci, 0);
|
||||
}
|
||||
|
||||
static void gsmtty_unthrottle(struct tty_struct *tty)
|
||||
@@ -3266,7 +3341,7 @@ static void gsmtty_unthrottle(struct tty_struct *tty)
|
||||
dlci->modem_tx |= TIOCM_RTS;
|
||||
dlci->throttled = false;
|
||||
/* Send an MSC with RTS set */
|
||||
gsmtty_modem_update(dlci, 0);
|
||||
gsm_modem_update(dlci, 0);
|
||||
}
|
||||
|
||||
static int gsmtty_break_ctl(struct tty_struct *tty, int state)
|
||||
@@ -3284,7 +3359,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
|
||||
if (encode > 0x0F)
|
||||
encode = 0x0F; /* Best effort */
|
||||
}
|
||||
return gsmtty_modem_update(dlci, encode);
|
||||
return gsm_modem_update(dlci, encode);
|
||||
}
|
||||
|
||||
static void gsmtty_cleanup(struct tty_struct *tty)
|
||||
|
||||
@@ -2667,7 +2667,7 @@ enum pci_board_num_t {
|
||||
pbn_panacom2,
|
||||
pbn_panacom4,
|
||||
pbn_plx_romulus,
|
||||
pbn_endrun_2_4000000,
|
||||
pbn_endrun_2_3906250,
|
||||
pbn_oxsemi,
|
||||
pbn_oxsemi_1_3906250,
|
||||
pbn_oxsemi_2_3906250,
|
||||
@@ -3195,10 +3195,10 @@ static struct pciserial_board pci_boards[] = {
|
||||
* signal now many ports are available
|
||||
* 2 port 952 Uart support
|
||||
*/
|
||||
[pbn_endrun_2_4000000] = {
|
||||
[pbn_endrun_2_3906250] = {
|
||||
.flags = FL_BASE0,
|
||||
.num_ports = 2,
|
||||
.base_baud = 4000000,
|
||||
.base_baud = 3906250,
|
||||
.uart_offset = 0x200,
|
||||
.first_offset = 0x1000,
|
||||
},
|
||||
@@ -4115,7 +4115,7 @@ static const struct pci_device_id serial_pci_tbl[] = {
|
||||
*/
|
||||
{ PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
pbn_endrun_2_4000000 },
|
||||
pbn_endrun_2_3906250 },
|
||||
/*
|
||||
* Quatech cards. These actually have configurable clocks but for
|
||||
* now we just use the default.
|
||||
|
||||
@@ -1675,11 +1675,11 @@ static void serial8250_start_tx(struct uart_port *port)
|
||||
struct uart_8250_port *up = up_to_u8250p(port);
|
||||
struct uart_8250_em485 *em485 = up->em485;
|
||||
|
||||
serial8250_rpm_get_tx(up);
|
||||
|
||||
if (!port->x_char && uart_circ_empty(&port->state->xmit))
|
||||
return;
|
||||
|
||||
serial8250_rpm_get_tx(up);
|
||||
|
||||
if (em485 &&
|
||||
em485->active_timer == &em485->start_tx_timer)
|
||||
return;
|
||||
@@ -3329,7 +3329,7 @@ static void serial8250_console_restore(struct uart_8250_port *up)
|
||||
|
||||
serial8250_set_divisor(port, baud, quot, frac);
|
||||
serial_port_out(port, UART_LCR, up->lcr);
|
||||
serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS);
|
||||
serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1255,13 +1255,18 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
|
||||
|
||||
static void pl011_rs485_tx_stop(struct uart_amba_port *uap)
|
||||
{
|
||||
/*
|
||||
* To be on the safe side only time out after twice as many iterations
|
||||
* as fifo size.
|
||||
*/
|
||||
const int MAX_TX_DRAIN_ITERS = uap->port.fifosize * 2;
|
||||
struct uart_port *port = &uap->port;
|
||||
int i = 0;
|
||||
u32 cr;
|
||||
|
||||
/* Wait until hardware tx queue is empty */
|
||||
while (!pl011_tx_empty(port)) {
|
||||
if (i == port->fifosize) {
|
||||
if (i > MAX_TX_DRAIN_ITERS) {
|
||||
dev_warn(port->dev,
|
||||
"timeout while draining hardware tx queue\n");
|
||||
break;
|
||||
@@ -2052,7 +2057,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
* with the given baud rate. We use this as the poll interval when we
|
||||
* wait for the tx queue to empty.
|
||||
*/
|
||||
uap->rs485_tx_drain_interval = (bits * 1000 * 1000) / baud;
|
||||
uap->rs485_tx_drain_interval = DIV_ROUND_UP(bits * 1000 * 1000, baud);
|
||||
|
||||
pl011_setup_status_masks(port, termios);
|
||||
|
||||
|
||||
@@ -1448,7 +1448,7 @@ static int imx_uart_startup(struct uart_port *port)
|
||||
imx_uart_writel(sport, ucr1, UCR1);
|
||||
|
||||
ucr4 = imx_uart_readl(sport, UCR4) & ~(UCR4_OREN | UCR4_INVR);
|
||||
if (!sport->dma_is_enabled)
|
||||
if (!dma_is_inited)
|
||||
ucr4 |= UCR4_OREN;
|
||||
if (sport->inverted_rx)
|
||||
ucr4 |= UCR4_INVR;
|
||||
|
||||
@@ -1238,12 +1238,10 @@ static void sc16is7xx_shutdown(struct uart_port *port)
|
||||
|
||||
/* Disable all interrupts */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0);
|
||||
/* Disable TX/RX, clear auto RS485 and RTS invert */
|
||||
/* Disable TX/RX */
|
||||
sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG,
|
||||
SC16IS7XX_EFCR_RXDISABLE_BIT |
|
||||
SC16IS7XX_EFCR_TXDISABLE_BIT |
|
||||
SC16IS7XX_EFCR_AUTO_RS485_BIT |
|
||||
SC16IS7XX_EFCR_RTS_INVERT_BIT,
|
||||
SC16IS7XX_EFCR_TXDISABLE_BIT,
|
||||
SC16IS7XX_EFCR_RXDISABLE_BIT |
|
||||
SC16IS7XX_EFCR_TXDISABLE_BIT);
|
||||
|
||||
|
||||
@@ -2684,6 +2684,7 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
|
||||
struct usb_request *request;
|
||||
struct cdns3_request *priv_req;
|
||||
struct cdns3_trb *trb = NULL;
|
||||
struct cdns3_trb trb_tmp;
|
||||
int ret;
|
||||
int val;
|
||||
|
||||
@@ -2693,8 +2694,10 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
|
||||
if (request) {
|
||||
priv_req = to_cdns3_request(request);
|
||||
trb = priv_req->trb;
|
||||
if (trb)
|
||||
if (trb) {
|
||||
trb_tmp = *trb;
|
||||
trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE);
|
||||
}
|
||||
}
|
||||
|
||||
writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd);
|
||||
@@ -2709,7 +2712,7 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep)
|
||||
|
||||
if (request) {
|
||||
if (trb)
|
||||
trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE);
|
||||
*trb = trb_tmp;
|
||||
|
||||
cdns3_rearm_transfer(priv_ep, 1);
|
||||
}
|
||||
|
||||
@@ -1209,12 +1209,16 @@ static int do_proc_control(struct usb_dev_state *ps,
|
||||
|
||||
usb_unlock_device(dev);
|
||||
i = usbfs_start_wait_urb(urb, tmo, &actlen);
|
||||
|
||||
/* Linger a bit, prior to the next control message. */
|
||||
if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
|
||||
msleep(200);
|
||||
usb_lock_device(dev);
|
||||
snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen);
|
||||
if (!i && actlen) {
|
||||
if (copy_to_user(ctrl->data, tbuf, actlen)) {
|
||||
ret = -EFAULT;
|
||||
goto recv_fault;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1231,6 +1235,10 @@ static int do_proc_control(struct usb_dev_state *ps,
|
||||
|
||||
usb_unlock_device(dev);
|
||||
i = usbfs_start_wait_urb(urb, tmo, &actlen);
|
||||
|
||||
/* Linger a bit, prior to the next control message. */
|
||||
if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
|
||||
msleep(200);
|
||||
usb_lock_device(dev);
|
||||
snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0);
|
||||
}
|
||||
@@ -1242,10 +1250,6 @@ static int do_proc_control(struct usb_dev_state *ps,
|
||||
}
|
||||
ret = (i < 0 ? i : actlen);
|
||||
|
||||
recv_fault:
|
||||
/* Linger a bit, prior to the next control message. */
|
||||
if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
|
||||
msleep(200);
|
||||
done:
|
||||
kfree(dr);
|
||||
usb_free_urb(urb);
|
||||
|
||||
@@ -404,6 +404,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
|
||||
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
|
||||
|
||||
/* Realtek Semiconductor Corp. Mass Storage Device (Multicard Reader)*/
|
||||
{ USB_DEVICE(0x0bda, 0x0151), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* Realtek hub in Dell WD19 (Type-C) */
|
||||
{ USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
@@ -507,6 +510,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
/* DJI CineSSD */
|
||||
{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* VCOM device */
|
||||
{ USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* INTEL VALUE SSD */
|
||||
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
|
||||
+29
-5
@@ -274,7 +274,8 @@ int dwc3_core_soft_reset(struct dwc3 *dwc)
|
||||
|
||||
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
|
||||
reg |= DWC3_DCTL_CSFTRST;
|
||||
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
|
||||
reg &= ~DWC3_DCTL_RUN_STOP;
|
||||
dwc3_gadget_dctl_write_safe(dwc, reg);
|
||||
|
||||
/*
|
||||
* For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit
|
||||
@@ -1377,10 +1378,10 @@ static void dwc3_get_properties(struct dwc3 *dwc)
|
||||
u8 lpm_nyet_threshold;
|
||||
u8 tx_de_emphasis;
|
||||
u8 hird_threshold;
|
||||
u8 rx_thr_num_pkt_prd;
|
||||
u8 rx_max_burst_prd;
|
||||
u8 tx_thr_num_pkt_prd;
|
||||
u8 tx_max_burst_prd;
|
||||
u8 rx_thr_num_pkt_prd = 0;
|
||||
u8 rx_max_burst_prd = 0;
|
||||
u8 tx_thr_num_pkt_prd = 0;
|
||||
u8 tx_max_burst_prd = 0;
|
||||
u8 tx_fifo_resize_max_num;
|
||||
const char *usb_psy_name;
|
||||
int ret;
|
||||
@@ -1690,21 +1691,44 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
/*
|
||||
* Clocks are optional, but new DT platforms should support all
|
||||
* clocks as required by the DT-binding.
|
||||
* Some devices have different clock names in legacy device trees,
|
||||
* check for them to retain backwards compatibility.
|
||||
*/
|
||||
dwc->bus_clk = devm_clk_get_optional(dev, "bus_early");
|
||||
if (IS_ERR(dwc->bus_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
|
||||
"could not get bus clock\n");
|
||||
|
||||
if (dwc->bus_clk == NULL) {
|
||||
dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk");
|
||||
if (IS_ERR(dwc->bus_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->bus_clk),
|
||||
"could not get bus clock\n");
|
||||
}
|
||||
|
||||
dwc->ref_clk = devm_clk_get_optional(dev, "ref");
|
||||
if (IS_ERR(dwc->ref_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
|
||||
"could not get ref clock\n");
|
||||
|
||||
if (dwc->ref_clk == NULL) {
|
||||
dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk");
|
||||
if (IS_ERR(dwc->ref_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->ref_clk),
|
||||
"could not get ref clock\n");
|
||||
}
|
||||
|
||||
dwc->susp_clk = devm_clk_get_optional(dev, "suspend");
|
||||
if (IS_ERR(dwc->susp_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
|
||||
"could not get suspend clock\n");
|
||||
|
||||
if (dwc->susp_clk == NULL) {
|
||||
dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk");
|
||||
if (IS_ERR(dwc->susp_clk))
|
||||
return dev_err_probe(dev, PTR_ERR(dwc->susp_clk),
|
||||
"could not get suspend clock\n");
|
||||
}
|
||||
}
|
||||
|
||||
ret = reset_control_deassert(dwc->reset);
|
||||
|
||||
@@ -584,16 +584,15 @@ int dwc3_drd_init(struct dwc3 *dwc)
|
||||
{
|
||||
int ret, irq;
|
||||
|
||||
if (ROLE_SWITCH &&
|
||||
device_property_read_bool(dwc->dev, "usb-role-switch"))
|
||||
return dwc3_setup_role_switch(dwc);
|
||||
|
||||
dwc->edev = dwc3_get_extcon(dwc);
|
||||
if (IS_ERR(dwc->edev))
|
||||
return PTR_ERR(dwc->edev);
|
||||
|
||||
if (ROLE_SWITCH &&
|
||||
device_property_read_bool(dwc->dev, "usb-role-switch")) {
|
||||
ret = dwc3_setup_role_switch(dwc);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (dwc->edev) {
|
||||
if (dwc->edev) {
|
||||
dwc->edev_nb.notifier_call = dwc3_drd_notifier;
|
||||
ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST,
|
||||
&dwc->edev_nb);
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#define PCI_DEVICE_ID_INTEL_ADLM 0x54ee
|
||||
#define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1
|
||||
#define PCI_DEVICE_ID_INTEL_RPLS 0x7a61
|
||||
#define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1
|
||||
#define PCI_DEVICE_ID_INTEL_MTL 0x7e7e
|
||||
#define PCI_DEVICE_ID_INTEL_TGL 0x9a15
|
||||
#define PCI_DEVICE_ID_AMD_MR 0x163a
|
||||
|
||||
@@ -456,6 +458,12 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLP),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_swnode, },
|
||||
|
||||
|
||||
@@ -3274,6 +3274,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
||||
const struct dwc3_event_depevt *event,
|
||||
struct dwc3_request *req, int status)
|
||||
{
|
||||
int request_status;
|
||||
int ret;
|
||||
|
||||
if (req->request.num_mapped_sgs)
|
||||
@@ -3294,7 +3295,35 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
||||
req->needs_extra_trb = false;
|
||||
}
|
||||
|
||||
dwc3_gadget_giveback(dep, req, status);
|
||||
/*
|
||||
* The event status only reflects the status of the TRB with IOC set.
|
||||
* For the requests that don't set interrupt on completion, the driver
|
||||
* needs to check and return the status of the completed TRBs associated
|
||||
* with the request. Use the status of the last TRB of the request.
|
||||
*/
|
||||
if (req->request.no_interrupt) {
|
||||
struct dwc3_trb *trb;
|
||||
|
||||
trb = dwc3_ep_prev_trb(dep, dep->trb_dequeue);
|
||||
switch (DWC3_TRB_SIZE_TRBSTS(trb->size)) {
|
||||
case DWC3_TRBSTS_MISSED_ISOC:
|
||||
/* Isoc endpoint only */
|
||||
request_status = -EXDEV;
|
||||
break;
|
||||
case DWC3_TRB_STS_XFER_IN_PROG:
|
||||
/* Applicable when End Transfer with ForceRM=0 */
|
||||
case DWC3_TRBSTS_SETUP_PENDING:
|
||||
/* Control endpoint only */
|
||||
case DWC3_TRBSTS_OK:
|
||||
default:
|
||||
request_status = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
request_status = status;
|
||||
}
|
||||
|
||||
dwc3_gadget_giveback(dep, req, request_status);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -1521,6 +1521,8 @@ static void configfs_composite_unbind(struct usb_gadget *gadget)
|
||||
usb_ep_autoconfig_reset(cdev->gadget);
|
||||
spin_lock_irqsave(&gi->spinlock, flags);
|
||||
cdev->gadget = NULL;
|
||||
cdev->deactivations = 0;
|
||||
gadget->deactivated = false;
|
||||
set_gadget_data(gadget, NULL);
|
||||
spin_unlock_irqrestore(&gi->spinlock, flags);
|
||||
}
|
||||
|
||||
@@ -264,6 +264,8 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect)
|
||||
buf->state = UVC_BUF_STATE_ERROR;
|
||||
vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR);
|
||||
}
|
||||
queue->buf_used = 0;
|
||||
|
||||
/* This must be protected by the irqlock spinlock to avoid race
|
||||
* conditions between uvc_queue_buffer and the disconnection event that
|
||||
* could result in an interruptible wait in uvc_dequeue_buffer. Do not
|
||||
|
||||
@@ -1103,6 +1103,26 @@ static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
/* Clear wakeup signal locked in zhaoxin platform when device plug in. */
|
||||
static void ehci_zx_wakeup_clear(struct ehci_hcd *ehci)
|
||||
{
|
||||
u32 __iomem *reg = &ehci->regs->port_status[4];
|
||||
u32 t1 = ehci_readl(ehci, reg);
|
||||
|
||||
t1 &= (u32)~0xf0000;
|
||||
t1 |= PORT_TEST_FORCE;
|
||||
ehci_writel(ehci, t1, reg);
|
||||
t1 = ehci_readl(ehci, reg);
|
||||
msleep(1);
|
||||
t1 &= (u32)~0xf0000;
|
||||
ehci_writel(ehci, t1, reg);
|
||||
ehci_readl(ehci, reg);
|
||||
msleep(1);
|
||||
t1 = ehci_readl(ehci, reg);
|
||||
ehci_writel(ehci, t1 | PORT_CSC, reg);
|
||||
ehci_readl(ehci, reg);
|
||||
}
|
||||
|
||||
/* suspend/resume, section 4.3 */
|
||||
|
||||
/* These routines handle the generic parts of controller suspend/resume */
|
||||
@@ -1154,6 +1174,9 @@ int ehci_resume(struct usb_hcd *hcd, bool force_reset)
|
||||
if (ehci->shutdown)
|
||||
return 0; /* Controller is dead */
|
||||
|
||||
if (ehci->zx_wakeup_clear_needed)
|
||||
ehci_zx_wakeup_clear(ehci);
|
||||
|
||||
/*
|
||||
* If CF is still set and reset isn't forced
|
||||
* then we maintained suspend power.
|
||||
|
||||
@@ -231,6 +231,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
|
||||
ehci->is_aspeed = 1;
|
||||
}
|
||||
break;
|
||||
case PCI_VENDOR_ID_ZHAOXIN:
|
||||
if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90)
|
||||
ehci->zx_wakeup_clear_needed = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* optional debug port, normally in the first BAR */
|
||||
|
||||
@@ -220,6 +220,7 @@ struct ehci_hcd { /* one per controller */
|
||||
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
|
||||
unsigned spurious_oc:1;
|
||||
unsigned is_aspeed:1;
|
||||
unsigned zx_wakeup_clear_needed:1;
|
||||
|
||||
/* required for usb32 quirk */
|
||||
#define OHCI_CTRL_HCFS (3 << 6)
|
||||
|
||||
@@ -1434,7 +1434,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
}
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex],
|
||||
msecs_to_jiffies(100)))
|
||||
msecs_to_jiffies(500)))
|
||||
xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n",
|
||||
hcd->self.busnum, wIndex + 1);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13
|
||||
#define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138
|
||||
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e
|
||||
#define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed
|
||||
|
||||
#define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639
|
||||
#define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9
|
||||
@@ -266,7 +267,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI))
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI ||
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI))
|
||||
xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW;
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
|
||||
|
||||
@@ -3141,6 +3141,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
|
||||
if (event_loop++ < TRBS_PER_SEGMENT / 2)
|
||||
continue;
|
||||
xhci_update_erst_dequeue(xhci, event_ring_deq);
|
||||
event_ring_deq = xhci->event_ring->dequeue;
|
||||
|
||||
/* ring is half-full, force isoc trbs to interrupt more often */
|
||||
if (xhci->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
|
||||
|
||||
@@ -1034,13 +1034,13 @@ static int tegra_xusb_unpowergate_partitions(struct tegra_xusb *tegra)
|
||||
int rc;
|
||||
|
||||
if (tegra->use_genpd) {
|
||||
rc = pm_runtime_get_sync(tegra->genpd_dev_ss);
|
||||
rc = pm_runtime_resume_and_get(tegra->genpd_dev_ss);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "failed to enable XUSB SS partition\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = pm_runtime_get_sync(tegra->genpd_dev_host);
|
||||
rc = pm_runtime_resume_and_get(tegra->genpd_dev_host);
|
||||
if (rc < 0) {
|
||||
dev_err(dev, "failed to enable XUSB Host partition\n");
|
||||
pm_runtime_put_sync(tegra->genpd_dev_ss);
|
||||
|
||||
@@ -781,6 +781,17 @@ void xhci_shutdown(struct usb_hcd *hcd)
|
||||
if (xhci->quirks & XHCI_SPURIOUS_REBOOT)
|
||||
usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev));
|
||||
|
||||
/* Don't poll the roothubs after shutdown. */
|
||||
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
|
||||
__func__, hcd->self.busnum);
|
||||
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
||||
del_timer_sync(&hcd->rh_timer);
|
||||
|
||||
if (xhci->shared_hcd) {
|
||||
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
|
||||
del_timer_sync(&xhci->shared_hcd->rh_timer);
|
||||
}
|
||||
|
||||
spin_lock_irq(&xhci->lock);
|
||||
xhci_halt(xhci);
|
||||
/* Workaround for spurious wakeups at shutdown with HSW */
|
||||
|
||||
@@ -186,16 +186,16 @@ static int eud_probe(struct platform_device *pdev)
|
||||
|
||||
chip->dev = &pdev->dev;
|
||||
|
||||
ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip);
|
||||
if (ret)
|
||||
return dev_err_probe(chip->dev, ret,
|
||||
"failed to add role switch release action\n");
|
||||
|
||||
chip->role_sw = usb_role_switch_get(&pdev->dev);
|
||||
if (IS_ERR(chip->role_sw))
|
||||
return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw),
|
||||
"failed to get role switch\n");
|
||||
|
||||
ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip);
|
||||
if (ret)
|
||||
return dev_err_probe(chip->dev, ret,
|
||||
"failed to add role switch release action\n");
|
||||
|
||||
chip->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(chip->base))
|
||||
return PTR_ERR(chip->base);
|
||||
|
||||
@@ -71,6 +71,7 @@ static void destroy_priv(struct kref *kref)
|
||||
|
||||
dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n");
|
||||
usb_put_dev(priv->usbdev);
|
||||
priv->usbdev = NULL;
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
@@ -736,7 +737,6 @@ static int uss720_probe(struct usb_interface *intf,
|
||||
parport_announce_port(pp);
|
||||
|
||||
usb_set_intfdata(intf, pp);
|
||||
usb_put_dev(usbdev);
|
||||
return 0;
|
||||
|
||||
probe_abort:
|
||||
@@ -754,7 +754,6 @@ static void uss720_disconnect(struct usb_interface *intf)
|
||||
usb_set_intfdata(intf, NULL);
|
||||
if (pp) {
|
||||
priv = pp->private_data;
|
||||
priv->usbdev = NULL;
|
||||
priv->pp = NULL;
|
||||
dev_dbg(&intf->dev, "parport_remove_port\n");
|
||||
parport_remove_port(pp);
|
||||
|
||||
@@ -21,10 +21,8 @@ static inline struct ssusb_mtk *otg_sx_to_ssusb(struct otg_switch_mtk *otg_sx)
|
||||
|
||||
static void toggle_opstate(struct ssusb_mtk *ssusb)
|
||||
{
|
||||
if (!ssusb->otg_switch.is_u3_drd) {
|
||||
mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION);
|
||||
mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN);
|
||||
}
|
||||
mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION);
|
||||
mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN);
|
||||
}
|
||||
|
||||
/* only port0 supports dual-role mode */
|
||||
|
||||
@@ -268,6 +268,13 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus");
|
||||
if (PTR_ERR(nop->vbus_draw) == -ENODEV)
|
||||
nop->vbus_draw = NULL;
|
||||
if (IS_ERR(nop->vbus_draw))
|
||||
return dev_err_probe(dev, PTR_ERR(nop->vbus_draw),
|
||||
"could not get vbus regulator\n");
|
||||
|
||||
nop->dev = dev;
|
||||
nop->phy.dev = nop->dev;
|
||||
nop->phy.label = "nop-xceiv";
|
||||
|
||||
@@ -194,6 +194,8 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
|
||||
{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
|
||||
{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
|
||||
{ USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */
|
||||
{ USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */
|
||||
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
|
||||
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
|
||||
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
|
||||
|
||||
@@ -432,6 +432,8 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define CINTERION_PRODUCT_CLS8 0x00b0
|
||||
#define CINTERION_PRODUCT_MV31_MBIM 0x00b3
|
||||
#define CINTERION_PRODUCT_MV31_RMNET 0x00b7
|
||||
#define CINTERION_PRODUCT_MV32_WA 0x00f1
|
||||
#define CINTERION_PRODUCT_MV32_WB 0x00f2
|
||||
|
||||
/* Olivetti products */
|
||||
#define OLIVETTI_VENDOR_ID 0x0b3c
|
||||
@@ -1217,6 +1219,10 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1057, 0xff), /* Telit FN980 */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1058, 0xff), /* Telit FN980 (PCIe) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */
|
||||
@@ -1233,6 +1239,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */
|
||||
.driver_info = RSVD(0) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||
@@ -1969,6 +1977,10 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = RSVD(3)},
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
|
||||
.driver_info = RSVD(0)},
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),
|
||||
.driver_info = RSVD(3)},
|
||||
{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff),
|
||||
.driver_info = RSVD(3)},
|
||||
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
|
||||
.driver_info = RSVD(4) },
|
||||
{ USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
|
||||
|
||||
@@ -584,9 +584,8 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,
|
||||
switch (command) {
|
||||
case WHITEHEAT_GET_DTR_RTS:
|
||||
info = usb_get_serial_port_data(port);
|
||||
memcpy(&info->mcr, command_info->result_buffer,
|
||||
sizeof(struct whiteheat_dr_info));
|
||||
break;
|
||||
info->mcr = command_info->result_buffer[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
|
||||
@@ -56,6 +56,7 @@ config TYPEC_RT1719
|
||||
tristate "Richtek RT1719 Sink Only Type-C controller driver"
|
||||
depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH
|
||||
depends on I2C
|
||||
depends on POWER_SUPPLY
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say Y or M here if your system has Richtek RT1719 sink only
|
||||
|
||||
@@ -949,6 +949,8 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
|
||||
role == TYPEC_HOST))
|
||||
goto out_unlock;
|
||||
|
||||
reinit_completion(&con->complete);
|
||||
|
||||
command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num);
|
||||
command |= UCSI_SET_UOR_ROLE(role);
|
||||
command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS;
|
||||
@@ -956,14 +958,18 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role)
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
mutex_unlock(&con->lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&con->complete,
|
||||
msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS)))
|
||||
ret = -ETIMEDOUT;
|
||||
msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS)))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&con->lock);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
|
||||
@@ -985,6 +991,8 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
|
||||
if (cur_role == role)
|
||||
goto out_unlock;
|
||||
|
||||
reinit_completion(&con->complete);
|
||||
|
||||
command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num);
|
||||
command |= UCSI_SET_PDR_ROLE(role);
|
||||
command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS;
|
||||
@@ -992,11 +1000,13 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role)
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
|
||||
mutex_unlock(&con->lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&con->complete,
|
||||
msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto out_unlock;
|
||||
}
|
||||
msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS)))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
mutex_lock(&con->lock);
|
||||
|
||||
/* Something has gone wrong while swapping the role */
|
||||
if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) !=
|
||||
|
||||
+6
-1
@@ -1406,7 +1406,12 @@ static void __kernfs_remove(struct kernfs_node *kn)
|
||||
*/
|
||||
void kernfs_remove(struct kernfs_node *kn)
|
||||
{
|
||||
struct kernfs_root *root = kernfs_root(kn);
|
||||
struct kernfs_root *root;
|
||||
|
||||
if (!kn)
|
||||
return;
|
||||
|
||||
root = kernfs_root(kn);
|
||||
|
||||
down_write(&root->kernfs_rwsem);
|
||||
__kernfs_remove(kn);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define BDO_MODE_CARRIER2 (5 << 28)
|
||||
#define BDO_MODE_CARRIER3 (6 << 28)
|
||||
#define BDO_MODE_EYE (7 << 28)
|
||||
#define BDO_MODE_TESTDATA (8 << 28)
|
||||
#define BDO_MODE_TESTDATA (8U << 28)
|
||||
|
||||
#define BDO_MODE_MASK(mode) ((mode) & 0xf0000000)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user