[PATCH v11 34/56] Input: atmel_mxt_ts - implement I2C retries
From: Nick Dyer Some maXTouch chips (eg mXT1386) will not respond on the first I2C request when they are in a sleep state. It must be retried after a delay for the chip to wake up. Signed-off-by: Nick Dyer Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 63fd7a2cd03c3a572a5db39c52f4856819e1835d) [gdavis: Forward port and fix conflicts.] Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 45 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index ab4eceac8fe7..152069c3e15d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -217,6 +217,7 @@ enum t100_type { #define MXT_CRC_TIMEOUT1000/* msec */ #define MXT_FW_RESET_TIME 3000/* msec */ #define MXT_FW_CHG_TIMEOUT 300 /* msec */ +#define MXT_WAKEUP_TIME25 /* msec */ #define MXT_REGULATOR_DELAY150 /* msec */ #define MXT_CHG_DELAY 100 /* msec */ #define MXT_POWERON_DELAY 150 /* msec */ @@ -721,6 +722,7 @@ static int __mxt_read_chunk(struct i2c_client *client, struct i2c_msg xfer[2]; u8 buf[2]; int ret; + bool retry = false; buf[0] = reg & 0xff; buf[1] = (reg >> 8) & 0xff; @@ -737,17 +739,22 @@ static int __mxt_read_chunk(struct i2c_client *client, xfer[1].len = len; xfer[1].buf = val; - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret == 2) { - ret = 0; - } else { - if (ret >= 0) - ret = -EIO; - dev_err(>dev, "%s: i2c transfer failed (%d)\n", - __func__, ret); +retry_read: + ret = i2c_transfer(client->adapter, xfer, ARRAY_SIZE(xfer)); + if (ret != ARRAY_SIZE(xfer)) { + if (!retry) { + dev_dbg(>dev, "%s: i2c retry\n", __func__); + msleep(MXT_WAKEUP_TIME); + retry = true; + goto retry_read; + } else { + dev_err(>dev, "%s: i2c transfer failed (%d)\n", + __func__, ret); + return -EIO; + } } - return ret; + return 0; } static int __mxt_read_reg(struct i2c_client *client, @@ -778,6 +785,7 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, u8 *buf; size_t count; int ret; + bool retry = false; count = len + 2; buf = kmalloc(count, GFP_KERNEL); @@ -788,14 +796,21 @@ static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len, buf[1] = (reg >> 8) & 0xff; memcpy([2], val, len); +retry_write: ret = i2c_master_send(client, buf, count); - if (ret == count) { - ret = 0; - } else { - if (ret >= 0) + if (ret != count) { + if (!retry) { + dev_dbg(>dev, "%s: i2c retry\n", __func__); + msleep(MXT_WAKEUP_TIME); + retry = true; + goto retry_write; + } else { + dev_err(>dev, "%s: i2c send failed (%d)\n", + __func__, ret); ret = -EIO; - dev_err(>dev, "%s: i2c send failed (%d)\n", - __func__, ret); + } + } else { + ret = 0; } kfree(buf); -- 2.17.1
[PATCH v11 24/56] dt-bindings: input: atmel: support to specify input name
Support to specify input name Signed-off-by: Jiada Wang --- Documentation/devicetree/bindings/input/atmel,maxtouch.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 4705d7753c54..f084afa1660e 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -43,6 +43,8 @@ Optional properties for main touchpad device: - atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This will be downloaded from the firmware loader on probe to the device. +- atmel,input_name: Override name of input device from the default. + Example: touch@4b { -- 2.17.1
[PATCH v11 25/56] Input: atmel_mxt_ts - add config checksum attribute to sysfs
From: karl tsou Add config checksum attribute to sysfs Signed-off-by: karl tsou Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 03477477ddbe5dcad42853ab3f84166a8f807acf) [gdavis: Forward port and fix conflicts.] Signed-off-by: George G. Davis [jiada: Add commit description Rename mxt_config_crc_show to config_crc_show Replace DEVICE_ATTR with DEVICE_ATTR_RO] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index affd2bf32969..780850343089 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3124,6 +3124,15 @@ static int mxt_configure_objects(struct mxt_data *data, return error; } +/* Configuration crc check sum is returned as hex xx */ +static ssize_t config_crc_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct mxt_data *data = dev_get_drvdata(dev); + + return scnprintf(buf, PAGE_SIZE, "%06x\n", data->config_crc); +} + /* Firmware Version is returned as Major.Minor.Build */ static ssize_t fw_version_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -3477,12 +3486,14 @@ static DEVICE_ATTR_RO(fw_version); static DEVICE_ATTR_RO(hw_version); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); static DEVICE_ATTR_WO(update_cfg); +static DEVICE_ATTR_RO(config_crc); static struct attribute *mxt_attrs[] = { _attr_fw_version.attr, _attr_hw_version.attr, _attr_object.attr, _attr_update_cfg.attr, + _attr_config_crc.attr, NULL }; -- 2.17.1
[PATCH v11 33/56] Input: atmel_mxt_ts - delay enabling IRQ when not using regulators
The path of enabling the IRQ in the probe function is not safe in level triggered operation, if it was already powered up and there is a message waiting on the device (eg finger down) because the object table has not yet been read. This forces the ISR into a hard loop. Delay enabling the interrupt until it is first needed, by set flag IRQ_NOAUTOEN. Signed-off-by: Jiada Wang CC: Dmitry Osipenko --- drivers/input/touchscreen/atmel_mxt_ts.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 7c9a738e633a..ab4eceac8fe7 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3822,6 +3822,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) return error; } + irq_set_status_flags(client->irq, IRQ_NOAUTOEN); error = devm_request_threaded_irq(>dev, client->irq, NULL, mxt_interrupt, IRQF_ONESHOT, client->name, data); @@ -3831,17 +3832,19 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) } if (data->suspend_mode == MXT_SUSPEND_REGULATOR) { + enable_irq(data->irq); + error = mxt_probe_regulators(data); if (error) return error; + + disable_irq(data->irq); } else if (data->reset_gpio) { msleep(MXT_RESET_GPIO_TIME); gpiod_set_value(data->reset_gpio, 1); msleep(MXT_RESET_INVALID_CHG); } - disable_irq(data->irq); - error = mxt_initialize(data); if (error) return error; -- 2.17.1
[PATCH v11 35/56] Input: atmel_mxt_ts - orientation is not present in hover
From: Nick Dyer When in hover, the orientation information is not sent Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 0c885d5bd276bd9240c43aa046fc407cbe2ae864) Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 152069c3e15d..1027ebbc3978 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1027,10 +1027,6 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) distance = MXT_DISTANCE_HOVERING; hover = true; active = true; - - if (data->t100_aux_vect) - orientation = message[data->t100_aux_vect]; - break; case MXT_T100_TYPE_FINGER: -- 2.17.1
[PATCH v11 32/56] Input: atmel_mxt_ts - make bootloader interrupt driven
From: Nick Dyer Make bootloader interrupt driven Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 67a3eea0cfc724c3c2a7410ac064f74227c7c6ef) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: Replace two use msecs_to_jiffies() instead of HZ, remove check of >flash->work don't poll to call mxt_check_bootloader() in mxt_check_bootloader()] Reported-by: kbuild test robot Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 127 ++- 1 file changed, 57 insertions(+), 70 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 0d77ae455fde..7c9a738e633a 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -219,6 +220,7 @@ enum t100_type { #define MXT_REGULATOR_DELAY150 /* msec */ #define MXT_CHG_DELAY 100 /* msec */ #define MXT_POWERON_DELAY 150 /* msec */ +#define MXT_BOOTLOADER_WAIT36E5/* 1 minute */ /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa @@ -300,6 +302,7 @@ struct mxt_fw_frame { /* Firmware update context */ struct mxt_flash { + struct mxt_data *data; const struct firmware *fw; struct mxt_fw_frame *frame; loff_t pos; @@ -307,8 +310,8 @@ struct mxt_flash { unsigned int count; unsigned int retry; u8 previous; - bool complete; - bool wait; + struct completion flash_completion; + struct delayed_work work; }; /* Each client has this additional data */ @@ -357,6 +360,7 @@ struct mxt_data { char *cfg_name; const char *pcfg_name; const char *input_name; + struct mxt_flash *flash; /* Cached parameters from object table */ u16 T5_address; @@ -601,35 +605,19 @@ static int mxt_write_firmware_frame(struct mxt_data *data, struct mxt_flash *f) f->frame_size); } -static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) +static int mxt_check_bootloader(struct mxt_data *data) { struct device *dev = >client->dev; + struct mxt_flash *f = data->flash; u8 state; int ret; - if (f->wait) { - /* -* In application update mode, the interrupt -* line signals state transitions. We must wait for the -* CHG assertion before reading the status byte. -* Once the status byte has been read, the line is deasserted. -*/ - ret = mxt_wait_for_completion(data, >chg_completion, - MXT_FW_CHG_TIMEOUT); - if (ret) { - /* -* TODO: handle -ERESTARTSYS better by terminating -* fw update process before returning to userspace -* by writing length 0x000 to device (iff we are in -* WAITING_FRAME_DATA state). -*/ - dev_warn(dev, "Update wait error %d\n", ret); - return ret; - } + /* Handle interrupt after download/flash process */ + if (f->pos >= f->fw->size) { + complete(>flash_completion); + return 0; } - f->wait = false; - ret = mxt_bootloader_read(data, , 1); if (ret) return ret; @@ -644,7 +632,6 @@ static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) ret = mxt_send_bootloader_cmd(data, true); if (ret) return ret; - f->wait = true; break; @@ -658,14 +645,11 @@ static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) if (ret) return ret; - f->wait = true; - break; case MXT_FRAME_CRC_CHECK: if (f->previous != MXT_WAITING_FRAME_DATA) goto unexpected; - f->wait = true; break; case MXT_FRAME_CRC_PASS: @@ -676,16 +660,13 @@ static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) f->retry = 0; f->pos += f->frame_size; f->count++; - f->wait = true; - if (f->pos >= f->fw->size) { - f->complete = true; + if (f->pos >= f->fw->size) dev_info(dev, "Sent %u frames, %zu bytes\n", f->count, f->fw->size); -
[PATCH v11 28/56] Input: atmel_mxt_ts - refactor code to enter bootloader into separate func
From: Nick Dyer Refactor code to enter bootloader into separate func Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit bedd706a32522b946467e15f4f4f24de86a1b4d7) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: Squash change from ndyer/linux/for-upstream commit d691d3ee6c6de84b38464a42 3207b3e23cb9dc3a - Input: atmel_mxt_ts - check firmware format before entering bootloader Add commit description] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 43 +++- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index bb4fc13defea..674763dddcd3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3253,23 +3253,10 @@ static int mxt_check_firmware_format(struct device *dev, return -EINVAL; } -static int mxt_load_fw(struct device *dev) +static int mxt_enter_bootloader(struct mxt_data *data) { - struct mxt_data *data = dev_get_drvdata(dev); - struct mxt_flash f = { 0, }; int ret; - ret = request_firmware(, data->fw_name, dev); - if (ret) { - dev_err(dev, "Unable to open firmware %s\n", data->fw_name); - return ret; - } - - /* Check for incorrect enc file */ - ret = mxt_check_firmware_format(dev, f.fw); - if (ret) - goto release_firmware; - if (data->suspended) { if (data->suspend_mode == MXT_SUSPEND_REGULATOR) mxt_regulator_enable(data); @@ -3287,14 +3274,14 @@ static int mxt_load_fw(struct device *dev) ret = mxt_t6_command(data, MXT_COMMAND_RESET, MXT_BOOT_VALUE, false); if (ret) - goto release_firmware; + return ret; msleep(MXT_RESET_TIME); /* Do not need to scan since we know family ID */ ret = mxt_lookup_bootloader_address(data, 0); if (ret) - goto release_firmware; + return ret; mxt_sysfs_remove(data); mxt_free_input_device(data); @@ -3305,6 +3292,30 @@ static int mxt_load_fw(struct device *dev) reinit_completion(>bl_completion); + return 0; +} + +static int mxt_load_fw(struct device *dev) +{ + struct mxt_data *data = dev_get_drvdata(dev); + struct mxt_flash f = { 0, }; + int ret; + + ret = request_firmware(, data->fw_name, dev); + if (ret) { + dev_err(dev, "Unable to open firmware %s\n", data->fw_name); + return ret; + } + + /* Check for incorrect enc file */ + ret = mxt_check_firmware_format(dev, f.fw); + if (ret) + goto release_firmware; + + ret = mxt_enter_bootloader(data); + if (ret) + goto release_firmware; + ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); if (ret) { /* Bootloader may still be unlocked from previous attempt */ -- 2.17.1
[PATCH v11 31/56] Input: atmel_mxt_ts - rename bl_completion to chg_completion
From: Nick Dyer Rename bl_completion to chg_completion Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit dda8453bfb44216645ede798918a314d4fca2481) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: call complete(>chg_completion) only when in_bootloader is TRUE Add commit description] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4d2240971387..0d77ae455fde 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -383,9 +383,6 @@ struct mxt_data { u8 T100_reportid_max; u16 T107_address; - /* for fw update in bootloader */ - struct completion bl_completion; - /* for reset handling */ struct completion reset_completion; @@ -397,6 +394,9 @@ struct mxt_data { enum mxt_suspend_mode suspend_mode; + /* for power up handling */ + struct completion chg_completion; + /* Indicates whether device is in suspend */ bool suspended; @@ -614,7 +614,7 @@ static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) * CHG assertion before reading the status byte. * Once the status byte has been read, the line is deasserted. */ - ret = mxt_wait_for_completion(data, >bl_completion, + ret = mxt_wait_for_completion(data, >chg_completion, MXT_FW_CHG_TIMEOUT); if (ret) { /* @@ -1415,8 +1415,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) struct mxt_data *data = dev_id; if (data->in_bootloader) { - /* bootloader state transition completion */ - complete(>bl_completion); + complete(>chg_completion); return IRQ_HANDLED; } @@ -2180,9 +2179,9 @@ static void mxt_regulator_enable(struct mxt_data *data) msleep(MXT_CHG_DELAY); retry_wait: - reinit_completion(>bl_completion); + reinit_completion(>chg_completion); data->in_bootloader = true; - error = mxt_wait_for_completion(data, >bl_completion, + error = mxt_wait_for_completion(data, >chg_completion, MXT_POWERON_DELAY); if (error == -EINTR) goto retry_wait; @@ -3342,7 +3341,7 @@ static int mxt_enter_bootloader(struct mxt_data *data) enable_irq(data->irq); } - reinit_completion(>bl_completion); + reinit_completion(>chg_completion); return 0; } @@ -3378,7 +3377,7 @@ static int mxt_load_fw(struct device *dev) } /* Wait for flash. */ - ret = mxt_wait_for_completion(data, >bl_completion, + ret = mxt_wait_for_completion(data, >chg_completion, MXT_FW_RESET_TIME); if (ret) goto disable_irq; @@ -3389,7 +3388,7 @@ static int mxt_load_fw(struct device *dev) * the CHG line after bootloading has finished, so ignore potential * errors. */ - mxt_wait_for_completion(data, >bl_completion, MXT_FW_RESET_TIME); + mxt_wait_for_completion(data, >chg_completion, MXT_FW_RESET_TIME); data->in_bootloader = false; disable_irq: @@ -3811,7 +3810,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) data->irq = client->irq; i2c_set_clientdata(client, data); - init_completion(>bl_completion); + init_completion(>chg_completion); init_completion(>reset_completion); init_completion(>crc_completion); -- 2.17.1
[PATCH v11 26/56] Input: atmel_mxt_ts - rename mxt_object_show to object_show
Rename mxt_object_show() to object_show(), so that object attr can also use DEVICE_ATTR_[RO|WO] to align with other attrs. Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 780850343089..c3dd6c486c12 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3171,8 +3171,8 @@ static ssize_t mxt_show_instance(char *buf, int count, return count; } -static ssize_t mxt_object_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t object_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mxt_data *data = dev_get_drvdata(dev); struct mxt_object *object; @@ -3484,7 +3484,7 @@ static const struct attribute_group mxt_fw_attr_group = { static DEVICE_ATTR_RO(fw_version); static DEVICE_ATTR_RO(hw_version); -static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); +static DEVICE_ATTR_RO(object); static DEVICE_ATTR_WO(update_cfg); static DEVICE_ATTR_RO(config_crc); -- 2.17.1
[PATCH v11 30/56] Input: atmel_mxt_ts - improve bootloader state machine handling
From: Nick Dyer The code is much clearer if we switch on the actual state the bootloader is in, rather than the state we want it to be in, and allows the removal of a goto retry tangle. Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 463e15ee95ee6e6274017ff645839dbe34d75c99) [gdavis: Squash fix from George G. Davis: - input: atmel_mxt_ts - Fix 'mxt_send_bootloader_cmd' was not declared warning] Signed-off-by: George G. Davis [jiada: only wait on some status change, cleanup code style] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 165 +-- 1 file changed, 95 insertions(+), 70 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index e2538c2dd3f7..4d2240971387 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -306,6 +306,9 @@ struct mxt_flash { size_t frame_size; unsigned int count; unsigned int retry; + u8 previous; + bool complete; + bool wait; }; /* Each client has this additional data */ @@ -584,15 +587,27 @@ static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address) return 0; } -static int mxt_check_bootloader(struct mxt_data *data, unsigned int state, - bool wait) +static int mxt_send_bootloader_cmd(struct mxt_data *data, bool unlock); + +static int mxt_write_firmware_frame(struct mxt_data *data, struct mxt_flash *f) +{ + f->frame = (struct mxt_fw_frame *)(f->fw->data + f->pos); + + /* Take account of CRC bytes */ + f->frame_size = __be16_to_cpu(f->frame->size) + 2U; + + /* Write one frame to device */ + return mxt_bootloader_write(data, f->fw->data + f->pos, + f->frame_size); +} + +static int mxt_check_bootloader(struct mxt_data *data, struct mxt_flash *f) { struct device *dev = >client->dev; - u8 val; + u8 state; int ret; -recheck: - if (wait) { + if (f->wait) { /* * In application update mode, the interrupt * line signals state transitions. We must wait for the @@ -608,40 +623,96 @@ static int mxt_check_bootloader(struct mxt_data *data, unsigned int state, * by writing length 0x000 to device (iff we are in * WAITING_FRAME_DATA state). */ - dev_err(dev, "Update wait error %d\n", ret); + dev_warn(dev, "Update wait error %d\n", ret); return ret; } } - ret = mxt_bootloader_read(data, , 1); + f->wait = false; + + ret = mxt_bootloader_read(data, , 1); if (ret) return ret; + /* Remove don't care bits */ + if (state & ~MXT_BOOT_STATUS_MASK) + state &= ~MXT_BOOT_STATUS_MASK; + switch (state) { case MXT_WAITING_BOOTLOAD_CMD: + dev_info(dev, "Unlocking bootloader\n"); + ret = mxt_send_bootloader_cmd(data, true); + if (ret) + return ret; + f->wait = true; + + break; + case MXT_WAITING_FRAME_DATA: - case MXT_APP_CRC_FAIL: - val &= ~MXT_BOOT_STATUS_MASK; + if (f->previous != MXT_WAITING_BOOTLOAD_CMD && + f->previous != MXT_FRAME_CRC_PASS && + f->previous != MXT_FRAME_CRC_FAIL) + goto unexpected; + + ret = mxt_write_firmware_frame(data, f); + if (ret) + return ret; + + f->wait = true; + + break; + + case MXT_FRAME_CRC_CHECK: + if (f->previous != MXT_WAITING_FRAME_DATA) + goto unexpected; + f->wait = true; break; + case MXT_FRAME_CRC_PASS: - if (val == MXT_FRAME_CRC_CHECK) { - goto recheck; - } else if (val == MXT_FRAME_CRC_FAIL) { - dev_err(dev, "Bootloader CRC fail\n"); - return -EINVAL; + if (f->previous != MXT_FRAME_CRC_CHECK) + goto unexpected; + + /* Next frame */ + f->retry = 0; + f->pos += f->frame_size; + f->count++; + f->wait = true; + + if (f->pos >= f->fw->size) { + f->complete = true; + dev_info(dev, "Sent %u frames, %zu bytes\n", + f->count, f->fw->size); + } else if (f->count % 50 == 0) { + dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n", + f->count, f->pos, f->fw->size); +
[PATCH v11 23/56] Input: atmel_mxt_ts - allow input name to be specified in platform data
From: Nick Dyer Android systems identify the input device and map to IDC file by using the input device name. To avoid unnecessary deltas to the driver file, allow this to be set from the platform data. Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit cbf94a7bda754d2e1899d9f50313a0bccc91422d) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: Separate Documentation/ portion change to another commit] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 85b903b8d5c9..affd2bf32969 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -337,6 +337,7 @@ struct mxt_data { char *fw_name; char *cfg_name; const char *pcfg_name; + const char *input_name; /* Cached parameters from object table */ u16 T5_address; @@ -2413,7 +2414,11 @@ static int mxt_initialize_input_device(struct mxt_data *data) if (!input_dev) return -ENOMEM; - input_dev->name = "Atmel maXTouch Touchscreen"; + if (data->input_name) + input_dev->name = data->input_name; + else + input_dev->name = "Atmel maXTouch Touchscreen"; + input_dev->phys = data->phys; input_dev->id.bustype = BUS_I2C; input_dev->dev.parent = dev; @@ -3649,6 +3654,8 @@ static int mxt_parse_device_properties(struct mxt_data *data) device_property_read_string(dev, "atmel,cfg_name", >pcfg_name); + device_property_read_string(dev, "atmel,input_name", >input_name); + if (device_property_present(dev, keymap_property)) { n_keys = device_property_count_u32(dev, keymap_property); if (n_keys <= 0) { -- 2.17.1
[PATCH v11 22/56] dt-bindings: input: atmel: provide name of configuration file
Add support to set name of configuration file Signed-off-by: Jiada Wang --- Documentation/devicetree/bindings/input/atmel,maxtouch.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 530312fc7a99..4705d7753c54 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -40,6 +40,9 @@ Optional properties for main touchpad device: - vdd: vdd: phandle to Power supply regulator - avdd: phandle to Analog Power supply regulator +- atmel,cfg_name: Provide name of configuration file in OBP_RAW format. This +will be downloaded from the firmware loader on probe to the device. + Example: touch@4b { -- 2.17.1
[PATCH v11 20/56] Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs
From: Nick Dyer There may be multiple maXTouch chips on a single device which will require different configuration files. Add a platform data value for the configuration filename. Add sysfs entry to write configuration file if the platform data is not set. Split out the object initialisation code from mxt_initialize() into mxt_configure_objects() to allow this. Signed-off-by: Nick Dyer Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 71a2a4d1954460b949a16b607f72bafab294ca79) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [gdavis: Squash fix from Vladimir Zapolskiy: - Input: atmel_mxt_ts - fix error paths in mxt_configure_objects()] Signed-off-by: Vladimir Zapolskiy [jiada: Separate Documentation/ portion change to another commit Rename mxt_update_cfg_store to update_cfg_store Replace DEVICE_ATTR with DEVICE_ATTR_WO Allow to fallback to legacy cfg name "maxtouch.cfg", if atmel,cfg_name isn't specified in device-tree] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 85 ++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 720574417219..503e70603a67 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -335,6 +335,8 @@ struct mxt_data { struct regulator *reg_vdd; struct regulator *reg_avdd; char *fw_name; + char *cfg_name; + const char *pcfg_name; /* Cached parameters from object table */ u16 T5_address; @@ -377,6 +379,9 @@ struct mxt_data { /* Indicates whether device is in suspend */ bool suspended; + + /* Indicates whether device is updating configuration */ + bool updating_config; }; struct mxt_vb2_buffer { @@ -2578,8 +2583,11 @@ static int mxt_initialize(struct mxt_data *data) if (error) return error; - error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, - >dev, GFP_KERNEL, data, + error = request_firmware_nowait(THIS_MODULE, true, + data->cfg_name ? + data->cfg_name : MXT_CFG_NAME, + >dev, + GFP_KERNEL, data, mxt_config_cb); if (error) { dev_err(>dev, "Failed to invoke firmware loader: %d\n", @@ -3081,19 +3089,21 @@ static int mxt_configure_objects(struct mxt_data *data, error = mxt_init_t7_power_cfg(data); if (error) { dev_err(dev, "Failed to initialize power cfg\n"); - return error; + goto err_free_object_table; } if (cfg) { error = mxt_update_cfg(data, cfg); - if (error) + if (error) { dev_warn(dev, "Error %d updating config\n", error); + goto err_free_object_table; + } } if (data->multitouch) { error = mxt_initialize_input_device(data); if (error) - return error; + goto err_free_object_table; } else { dev_warn(dev, "No touch object detected\n"); } @@ -3101,6 +3111,10 @@ static int mxt_configure_objects(struct mxt_data *data, mxt_debug_init(data); return 0; + +err_free_object_table: + mxt_free_object_table(data); + return error; } /* Firmware Version is returned as Major.Minor.Build */ @@ -3392,6 +3406,55 @@ static ssize_t update_fw_store(struct device *dev, return count; } +static ssize_t update_cfg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct mxt_data *data = dev_get_drvdata(dev); + const struct firmware *cfg; + int ret; + + ret = mxt_update_file_name(dev, >cfg_name, buf, count); + if (ret) + return ret; + + ret = request_firmware(, data->cfg_name, dev); + if (ret < 0) { + dev_err(dev, "Failure to request config file %s\n", + data->cfg_name); + ret = -ENOENT; + goto out; + } + + data->updating_config = true; + + mxt_free_input_device(data); + + if (data->suspended) { + if (data->suspend_mode == MXT_SUSPEND_REGULATOR) { + enable_irq(data->irq); + mxt_regulator_enable(data); + } else if (data->suspend_mode ==
[PATCH v11 27/56] Input: atmel_mxt_ts - refactor firmware flash to extract context into struct
From: Nick Dyer Refactor firmware flash to extract context into struct Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 1bbe20ff3dcd6612e7942c495929eae5c138ece2) Signed-off-by: George G. Davis [jiada: Add commit description] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 59 +++- 1 file changed, 36 insertions(+), 23 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index c3dd6c486c12..bb4fc13defea 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -292,6 +292,22 @@ struct mxt_cfg { struct mxt_info info; }; +/* Firmware frame structure */ +struct mxt_fw_frame { + __be16 size; + u8 data[]; +}; + +/* Firmware update context */ +struct mxt_flash { + const struct firmware *fw; + struct mxt_fw_frame *frame; + loff_t pos; + size_t frame_size; + unsigned int count; + unsigned int retry; +}; + /* Each client has this additional data */ struct mxt_data { struct i2c_client *client; @@ -3240,21 +3256,17 @@ static int mxt_check_firmware_format(struct device *dev, static int mxt_load_fw(struct device *dev) { struct mxt_data *data = dev_get_drvdata(dev); - const struct firmware *fw = NULL; - unsigned int frame_size; - unsigned int pos = 0; - unsigned int retry = 0; - unsigned int frame = 0; + struct mxt_flash f = { 0, }; int ret; - ret = request_firmware(, data->fw_name, dev); + ret = request_firmware(, data->fw_name, dev); if (ret) { dev_err(dev, "Unable to open firmware %s\n", data->fw_name); return ret; } /* Check for incorrect enc file */ - ret = mxt_check_firmware_format(dev, fw); + ret = mxt_check_firmware_format(dev, f.fw); if (ret) goto release_firmware; @@ -3308,41 +3320,42 @@ static int mxt_load_fw(struct device *dev) goto disable_irq; } - while (pos < fw->size) { + while (f.pos < f.fw->size) { + f.frame = (struct mxt_fw_frame *)(f.fw->data + f.pos); + ret = mxt_check_bootloader(data, MXT_WAITING_FRAME_DATA, true); if (ret) goto disable_irq; - frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1)); - /* Take account of CRC bytes */ - frame_size += 2; + f.frame_size = __be16_to_cpu(f.frame->size) + 2U; /* Write one frame to device */ - ret = mxt_bootloader_write(data, fw->data + pos, frame_size); + ret = mxt_bootloader_write(data, f.fw->data + f.pos, + f.frame_size); if (ret) goto disable_irq; ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS, true); if (ret) { - retry++; + f.retry++; /* Back off by 20ms per retry */ - msleep(retry * 20); + msleep(f.retry * 20); - if (retry > 20) { + if (f.retry > 20) { dev_err(dev, "Retry count exceeded\n"); goto disable_irq; } } else { - retry = 0; - pos += frame_size; - frame++; + f.retry = 0; + f.pos += f.frame_size; + f.count++; } - if (frame % 50 == 0) - dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n", - frame, pos, fw->size); + if (f.count % 50 == 0) + dev_dbg(dev, "Sent %u frames, %lld/%zu bytes\n", + f.count, f.pos, f.fw->size); } /* Wait for flash. */ @@ -3351,7 +3364,7 @@ static int mxt_load_fw(struct device *dev) if (ret) goto disable_irq; - dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos); + dev_dbg(dev, "Sent %u frames, %lld bytes\n", f.count, f.pos); /* * Wait for device to reset. Some bootloader versions do not assert @@ -3365,7 +3378,7 @@ static int mxt_load_fw(struct device *dev) disable_irq: disable_irq(data->irq); release_firmware: - release_firmware(fw); + release_firmware(f.fw); return ret; } -- 2.17.1
[PATCH v11 21/56] Input: atmel_mxt_ts - check data->input_dev is not null in mxt_input_sync()
From: Janus Cheng * Symptom: if update_fw and update_cfg, kernel panic occurs. * Reproducibility: 10% * Root Cause: - If update_fw, the T6 will send a CFG_ERR message periodically. - After that, update_cfg process begin, the mxt_update_cfg_store() will invoke mxt_free_input_device() and nullify data->input_dev. - The CFG_ERR message will trigger mxt_interrupt(), and mxt_input_sync() will be invoked by mxt_process_messages_t44(). And mxt_input_sync() references a NULL data->input_dev and kernel panic occurs. TrackerRMS TKT-004235 Signed-off-by: Janus Cheng Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit c909ada856861f305653b127db3ea0fa60264331) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 503e70603a67..85b903b8d5c9 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -838,9 +838,11 @@ static void mxt_input_button(struct mxt_data *data, u8 *message) static void mxt_input_sync(struct mxt_data *data) { - input_mt_report_pointer_emulation(data->input_dev, - data->t19_num_keys); - input_sync(data->input_dev); + if (data->input_dev) { + input_mt_report_pointer_emulation(data->input_dev, + data->t19_num_keys); + input_sync(data->input_dev); + } } static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) -- 2.17.1
[PATCH v11 29/56] Input: atmel_mxt_ts - combine bootloader version query with probe
From: Nick Dyer This removes some complexity from the bootloader state machine, and means that we always output some debug about the version as soon as we start talking to the bootloader. Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit a2d141f170c80fea6663af98aab0be32abc0ddb0) Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 45 +++- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 674763dddcd3..e2538c2dd3f7 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -559,47 +559,31 @@ static int mxt_probe_bootloader(struct mxt_data *data, bool alt_address) { struct device *dev = >client->dev; int error; - u8 val; - bool crc_failure; + u8 buf[3]; + bool crc_failure, extended_id; error = mxt_lookup_bootloader_address(data, alt_address); if (error) return error; - error = mxt_bootloader_read(data, , 1); + /* Check bootloader status and version information */ + error = mxt_bootloader_read(data, buf, sizeof(buf)); if (error) return error; - /* Check app crc fail mode */ - crc_failure = (val & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; + crc_failure = (buf[0] & ~MXT_BOOT_STATUS_MASK) == MXT_APP_CRC_FAIL; + extended_id = buf[0] & MXT_BOOT_EXTENDED_ID; - dev_err(dev, "Detected bootloader, status:%02X%s\n", - val, crc_failure ? ", APP_CRC_FAIL" : ""); + dev_info(dev, "Found bootloader addr:%02x ID:%u%s%u%s\n", +data->bootloader_addr, +extended_id ? (buf[1] & MXT_BOOT_ID_MASK) : buf[0], +extended_id ? " version:" : "", +extended_id ? buf[2] : 0, +crc_failure ? ", APP_CRC_FAIL" : ""); return 0; } -static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val) -{ - struct device *dev = >client->dev; - u8 buf[3]; - - if (val & MXT_BOOT_EXTENDED_ID) { - if (mxt_bootloader_read(data, [0], 3) != 0) { - dev_err(dev, "%s: i2c failure\n", __func__); - return val; - } - - dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]); - - return buf[0]; - } else { - dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK); - - return val; - } -} - static int mxt_check_bootloader(struct mxt_data *data, unsigned int state, bool wait) { @@ -633,9 +617,6 @@ static int mxt_check_bootloader(struct mxt_data *data, unsigned int state, if (ret) return ret; - if (state == MXT_WAITING_BOOTLOAD_CMD) - val = mxt_get_bootloader_version(data, val); - switch (state) { case MXT_WAITING_BOOTLOAD_CMD: case MXT_WAITING_FRAME_DATA: @@ -3279,7 +3260,7 @@ static int mxt_enter_bootloader(struct mxt_data *data) msleep(MXT_RESET_TIME); /* Do not need to scan since we know family ID */ - ret = mxt_lookup_bootloader_address(data, 0); + ret = mxt_probe_bootloader(data, 0); if (ret) return ret; -- 2.17.1
[PATCH v11 18/56] Input: atmel_mxt_ts: Rename mxt_hw_version_show to hw_version_show
Rename mxt_hw_version_show to hw_version_show to address checkpatch warning Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index b2a37a9597f3..cec823de4096 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3114,8 +3114,8 @@ static ssize_t fw_version_show(struct device *dev, } /* Hardware Version is returned as FamilyID.VariantID */ -static ssize_t mxt_hw_version_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t hw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mxt_data *data = dev_get_drvdata(dev); struct mxt_info *info = data->info; @@ -3404,7 +3404,7 @@ static const struct attribute_group mxt_fw_attr_group = { }; static DEVICE_ATTR_RO(fw_version); -static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); +static DEVICE_ATTR_RO(hw_version); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); static struct attribute *mxt_attrs[] = { -- 2.17.1
[PATCH v11 16/56] Input: atmel_mxt_ts - allow specification of firmware file name
From: Nick Dyer On platforms which have multiple device instances using this driver, the firmware may be different on each device. This patch makes the user give the name of the firmware file when flashing. This also prevents accidental triggering of the firmware load process. Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 76ebb7cee971cb42dfb0a3a9224403b8b09abcf1) [gdavis: Forward port and fix conflicts.] Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 43 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index f8783e37436f..0e30ff372a43 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -33,8 +33,7 @@ #include #include -/* Firmware files */ -#define MXT_FW_NAME"maxtouch.fw" +/* Configuration file */ #define MXT_CFG_NAME "maxtouch.cfg" #define MXT_CFG_MAGIC "OBP_RAW V1" @@ -335,6 +334,7 @@ struct mxt_data { bool use_retrigen_workaround; struct regulator *reg_vdd; struct regulator *reg_avdd; + char *fw_name; /* Cached parameters from object table */ u16 T5_address; @@ -3207,7 +3207,7 @@ static int mxt_check_firmware_format(struct device *dev, return -EINVAL; } -static int mxt_load_fw(struct device *dev, const char *fn) +static int mxt_load_fw(struct device *dev) { struct mxt_data *data = dev_get_drvdata(dev); const struct firmware *fw = NULL; @@ -3217,9 +3217,9 @@ static int mxt_load_fw(struct device *dev, const char *fn) unsigned int frame = 0; int ret; - ret = request_firmware(, fn, dev); + ret = request_firmware(, data->fw_name, dev); if (ret) { - dev_err(dev, "Unable to open firmware %s\n", fn); + dev_err(dev, "Unable to open firmware %s\n", data->fw_name); return ret; } @@ -3339,6 +3339,33 @@ static int mxt_load_fw(struct device *dev, const char *fn) return ret; } +static int mxt_update_file_name(struct device *dev, char **file_name, + const char *buf, size_t count) +{ + char *file_name_tmp; + + /* Simple sanity check */ + if (count > 64) { + dev_warn(dev, "File name too long\n"); + return -EINVAL; + } + + file_name_tmp = krealloc(*file_name, count + 1, GFP_KERNEL); + if (!file_name_tmp) + return -ENOMEM; + + *file_name = file_name_tmp; + memcpy(*file_name, buf, count); + + /* Echo into the sysfs entry may append newline at the end of buf */ + if (buf[count - 1] == '\n') + (*file_name)[count - 1] = '\0'; + else + (*file_name)[count] = '\0'; + + return 0; +} + static ssize_t mxt_update_fw_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -3346,7 +3373,11 @@ static ssize_t mxt_update_fw_store(struct device *dev, struct mxt_data *data = dev_get_drvdata(dev); int error; - error = mxt_load_fw(dev, MXT_FW_NAME); + error = mxt_update_file_name(dev, >fw_name, buf, count); + if (error) + return error; + + error = mxt_load_fw(dev); if (error) { dev_err(dev, "The firmware update failed(%d)\n", error); count = error; -- 2.17.1
[PATCH v11 19/56] Input: atmel_mxt_ts: rename mxt_update_fw_store to update_fw_store
Rename mxt_update_fw_store to update_fw_store, to address checkpatch warning. Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index cec823de4096..720574417219 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3366,9 +3366,9 @@ static int mxt_update_file_name(struct device *dev, char **file_name, return 0; } -static ssize_t mxt_update_fw_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t update_fw_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct mxt_data *data = dev_get_drvdata(dev); int error; @@ -3392,7 +3392,7 @@ static ssize_t mxt_update_fw_store(struct device *dev, return count; } -static DEVICE_ATTR(update_fw, 0200, NULL, mxt_update_fw_store); +static DEVICE_ATTR_WO(update_fw); static struct attribute *mxt_fw_attrs[] = { _attr_update_fw.attr, -- 2.17.1
[PATCH v11 17/56] Input: atmel_mxt_ts: Rename mxt_fw_version_show to fw_version_show
Rename mxt_fw_version_show to fw_version_show to address checkpatch warning Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 0e30ff372a43..b2a37a9597f3 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3104,8 +3104,8 @@ static int mxt_configure_objects(struct mxt_data *data, } /* Firmware Version is returned as Major.Minor.Build */ -static ssize_t mxt_fw_version_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mxt_data *data = dev_get_drvdata(dev); struct mxt_info *info = data->info; @@ -3403,7 +3403,7 @@ static const struct attribute_group mxt_fw_attr_group = { .attrs = mxt_fw_attrs, }; -static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL); +static DEVICE_ATTR_RO(fw_version); static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); -- 2.17.1
[PATCH v11 15/56] Input: atmel_mxt_ts - report failures in suspend/resume
From: Nick Dyer This patch reports failures in suspend/resume Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 93a57575403d) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: Fix compilation warning Add commit description] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 51 ++-- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index ef8baf64659e..f8783e37436f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -3425,10 +3425,12 @@ static void mxt_reset_slots(struct mxt_data *data) mxt_input_sync(data); } -static void mxt_start(struct mxt_data *data) +static int mxt_start(struct mxt_data *data) { + int ret = 0; + if (!data->suspended || data->in_bootloader) - return; + return 0; switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: @@ -3453,28 +3455,42 @@ static void mxt_start(struct mxt_data *data) */ mxt_process_messages_until_invalid(data); - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + ret = mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); + if (ret) + return ret; /* Recalibrate since chip has been in deep sleep */ - mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + ret = mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + if (ret) + return ret; + + ret = mxt_acquire_irq(data); + if (ret) + return ret; - mxt_acquire_irq(data); break; } data->suspended = false; + + return 0; } -static void mxt_stop(struct mxt_data *data) +static int mxt_stop(struct mxt_data *data) { + int ret; + if (data->suspended || data->in_bootloader) - return; + return 0; switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: /* Touch disable */ - mxt_write_object(data, + ret = mxt_write_object(data, MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0); + if (ret) + return ret; + break; case MXT_SUSPEND_REGULATOR: @@ -3487,29 +3503,40 @@ static void mxt_stop(struct mxt_data *data) default: disable_irq(data->irq); - mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + ret = mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + if (ret) + return ret; mxt_reset_slots(data); break; } data->suspended = true; + return 0; } static int mxt_input_open(struct input_dev *dev) { struct mxt_data *data = input_get_drvdata(dev); + int ret; - mxt_start(data); + ret = mxt_start(data); - return 0; + if (ret) + dev_err(>client->dev, "%s failed rc=%d\n", __func__, ret); + + return ret; } static void mxt_input_close(struct input_dev *dev) { struct mxt_data *data = input_get_drvdata(dev); + int ret; - mxt_stop(data); + ret = mxt_stop(data); + + if (ret) + dev_err(>client->dev, "%s failed rc=%d\n", __func__, ret); } static int mxt_parse_device_properties(struct mxt_data *data) -- 2.17.1
[PATCH v11 14/56] Input: atmel_mxt_ts - add regulator control support
From: Nick Dyer Allow the driver to optionally manage enabling/disable power to the touch controller itself. If the regulators are not present then use the deep sleep power mode instead. For a correct power on sequence, it is required that we have control over the RESET line. Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 14052b61bb66c2f2283c00e733e131be7a9b8bfc) [gdavis: Resolve forward port conflicts due to v4.14-rc1 commmit f657b00df22e ("Input: atmel_mxt_ts - add support for reset line") and applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [gdavis: Squash fixes from Dirk Behme: - Input: atmel_mxt_ts - in failure case disable the regulator - Input: atmel_mxt_ts - disable only enabled regulators - Input: atmel_mxt_ts - use devm_regulator_get()] Signed-off-by: Dirk Behme [jiada: Replace white-spaces with tab for MXT_CHG_DELAY separate Documentation/ and include/dt-bindings/ portion change to another commit] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 130 +-- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 9aafed92db9c..ef8baf64659e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -26,10 +26,12 @@ #include #include #include +#include #include #include #include #include +#include /* Firmware files */ #define MXT_FW_NAME"maxtouch.fw" @@ -215,6 +217,9 @@ enum t100_type { #define MXT_CRC_TIMEOUT1000/* msec */ #define MXT_FW_RESET_TIME 3000/* msec */ #define MXT_FW_CHG_TIMEOUT 300 /* msec */ +#define MXT_REGULATOR_DELAY150 /* msec */ +#define MXT_CHG_DELAY 100 /* msec */ +#define MXT_POWERON_DELAY 150 /* msec */ /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa @@ -275,11 +280,6 @@ enum v4l_dbg_inputs { MXT_V4L_INPUT_MAX, }; -enum mxt_suspend_mode { - MXT_SUSPEND_DEEP_SLEEP = 0, - MXT_SUSPEND_T9_CTRL = 1, -}; - /* Config update context */ struct mxt_cfg { u8 *raw; @@ -333,6 +333,8 @@ struct mxt_data { u8 stylus_aux_pressure; u8 stylus_aux_peak; bool use_retrigen_workaround; + struct regulator *reg_vdd; + struct regulator *reg_avdd; /* Cached parameters from object table */ u16 T5_address; @@ -2073,6 +2075,94 @@ static int mxt_read_info_block(struct mxt_data *data) return error; } +static void mxt_regulator_enable(struct mxt_data *data) +{ + int error; + + if (!data->reg_vdd || !data->reg_avdd) + return; + + gpiod_set_value(data->reset_gpio, 0); + + error = regulator_enable(data->reg_vdd); + if (error) + return; + + error = regulator_enable(data->reg_avdd); + if (error) { + regulator_disable(data->reg_vdd); + return; + } + + /* +* According to maXTouch power sequencing specification, RESET line +* must be kept low until some time after regulators come up to +* voltage +*/ + msleep(MXT_REGULATOR_DELAY); + gpiod_set_value(data->reset_gpio, 1); + msleep(MXT_CHG_DELAY); + +retry_wait: + reinit_completion(>bl_completion); + data->in_bootloader = true; + error = mxt_wait_for_completion(data, >bl_completion, + MXT_POWERON_DELAY); + if (error == -EINTR) + goto retry_wait; + + data->in_bootloader = false; +} + +static void mxt_regulator_disable(struct mxt_data *data) +{ + if (!data->reg_vdd || !data->reg_avdd) + return; + + if (regulator_is_enabled(data->reg_vdd)) + regulator_disable(data->reg_vdd); + if (regulator_is_enabled(data->reg_avdd)) + regulator_disable(data->reg_avdd); +} + +static int mxt_probe_regulators(struct mxt_data *data) +{ + struct device *dev = >client->dev; + int error; + + /* Must have reset GPIO to use regulator support */ + if (!data->reset_gpio) { + error = -EINVAL; + goto fail; + } + + data->reg_vdd = devm_regulator_get(dev, "vdd"); + if (IS_ERR(data->reg_vdd)) { + error = PTR_ERR(data->reg_vdd); + dev_err(dev, "Error %d getting vdd regulator\n", error); + goto fail; + } + + data->reg_avdd = devm_regulator_get(dev, "avdd"); + if (IS_ERR(data->reg_avdd)) { + error = PTR_ERR(data->reg_avdd); + dev_err(dev, "Error %d getting avdd regulator\n", error); + goto fail_release; +
[PATCH v11 11/56] Input: atmel_mxt_ts - add debug for T92 gesture and T93 touch seq msgs
From: Karl Tsou output T92 gesture and T93 touch sequence messages. Signed-off-by: Karl Tsou Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit cb98986f8342107bf4a536aed4160b20839e97c1) Signed-off-by: George G. Davis Reported-by: kbuild test robot [jiada: changed dev_debug() to dev_info()] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 40 1 file changed, 40 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 63db8b66eb67..6126bb8a7acc 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -71,6 +71,8 @@ #define MXT_SPT_MESSAGECOUNT_T44 44 #define MXT_SPT_CTECONFIG_T46 46 #define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71 +#define MXT_PROCI_SYMBOLGESTUREPROCESSOR 92 +#define MXT_PROCI_TOUCHSEQUENCELOGGER 93 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100 #define MXT_PROCI_ACTIVESTYLUS_T107107 @@ -349,6 +351,10 @@ struct mxt_data { u8 T42_reportid_max; u16 T44_address; u8 T48_reportid; + u16 T92_address; + u8 T92_reportid; + u16 T93_address; + u8 T93_reportid; u8 T100_reportid_min; u8 T100_reportid_max; u16 T107_address; @@ -1113,6 +1119,24 @@ static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg) return 0; } +static void mxt_proc_t92_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = >client->dev; + u8 status = msg[1]; + + dev_info(dev, "T92 long stroke LSTR=%d %d\n", +(status & 0x80) ? 1 : 0, +status & 0x0F); +} + +static void mxt_proc_t93_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = >client->dev; + u8 status = msg[1]; + + dev_info(dev, "T93 report double tap %d\n", status); +} + static int mxt_proc_message(struct mxt_data *data, u8 *message) { u8 report_id = message[0]; @@ -1145,6 +1169,10 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) } else if (report_id >= data->T15_reportid_min && report_id <= data->T15_reportid_max) { mxt_proc_t15_messages(data, message); + } else if (report_id == data->T92_reportid) { + mxt_proc_t92_messages(data, message); + } else if (report_id == data->T93_reportid) { + mxt_proc_t93_messages(data, message); } else { mxt_dump_message(data, message); } @@ -1814,6 +1842,10 @@ static void mxt_free_object_table(struct mxt_data *data) data->T42_reportid_max = 0; data->T44_address = 0; data->T48_reportid = 0; + data->T92_reportid = 0; + data->T92_address = 0; + data->T93_reportid = 0; + data->T93_address = 0; data->T100_reportid_min = 0; data->T100_reportid_max = 0; data->max_reportid = 0; @@ -1906,6 +1938,14 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_PROCG_NOISESUPPRESSION_T48: data->T48_reportid = min_id; break; + case MXT_PROCI_SYMBOLGESTUREPROCESSOR: + data->T92_reportid = min_id; + data->T92_address = object->start_address; + break; + case MXT_PROCI_TOUCHSEQUENCELOGGER: + data->T93_reportid = min_id; + data->T93_address = object->start_address; + break; case MXT_TOUCH_MULTITOUCHSCREEN_T100: data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100; data->T100_reportid_min = min_id; -- 2.17.1
[PATCH v11 10/56] Input: atmel_mxt_ts - implement support for T107 active stylus
From: Nick Dyer This patch implements support for T107 active stylus Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 20e357dd9acf8c2040068c8b22d6bc1401a1893f) [gdavis: Forward port and fix conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 117 ++- 1 file changed, 113 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index ba58cdd5b76d..63db8b66eb67 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -72,6 +72,7 @@ #define MXT_SPT_CTECONFIG_T46 46 #define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100 +#define MXT_PROCI_ACTIVESTYLUS_T107107 /* MXT_GEN_MESSAGE_T5 object */ #define MXT_RPTID_NOMSG0xff @@ -181,6 +182,7 @@ struct t37_debug { enum t100_type { MXT_T100_TYPE_FINGER= 1, MXT_T100_TYPE_PASSIVE_STYLUS= 2, + MXT_T100_TYPE_ACTIVE_STYLUS = 3, MXT_T100_TYPE_HOVERING_FINGER = 4, MXT_T100_TYPE_GLOVE = 5, MXT_T100_TYPE_LARGE_TOUCH = 6, @@ -192,6 +194,16 @@ enum t100_type { #define MXT_TOUCH_MAJOR_DEFAULT1 #define MXT_PRESSURE_DEFAULT 1 +/* Gen2 Active Stylus */ +#define MXT_T107_STYLUS_STYAUX 42 +#define MXT_T107_STYLUS_STYAUX_PRESSUREBIT(0) +#define MXT_T107_STYLUS_STYAUX_PEAKBIT(4) + +#define MXT_T107_STYLUS_HOVER BIT(0) +#define MXT_T107_STYLUS_TIPSWITCH BIT(1) +#define MXT_T107_STYLUS_BUTTON0BIT(2) +#define MXT_T107_STYLUS_BUTTON1BIT(3) + /* Delay times */ #define MXT_BACKUP_TIME50 /* msec */ #define MXT_RESET_GPIO_TIME20 /* msec */ @@ -313,10 +325,12 @@ struct mxt_data { struct t7_config t7_cfg; struct mxt_dbg dbg; struct gpio_desc *reset_gpio; - bool use_retrigen_workaround; unsigned long t15_keystatus; int t15_num_keys; const unsigned int *t15_keymap; + u8 stylus_aux_pressure; + u8 stylus_aux_peak; + bool use_retrigen_workaround; /* Cached parameters from object table */ u16 T5_address; @@ -337,6 +351,7 @@ struct mxt_data { u8 T48_reportid; u8 T100_reportid_min; u8 T100_reportid_max; + u16 T107_address; /* for fw update in bootloader */ struct completion bl_completion; @@ -908,6 +923,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) u8 major = 0; u8 pressure = 0; u8 orientation = 0; + bool active = false; + bool hover = false; id = message[0] - data->T100_reportid_min - 2; @@ -926,6 +943,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) case MXT_T100_TYPE_HOVERING_FINGER: tool = MT_TOOL_FINGER; distance = MXT_DISTANCE_HOVERING; + hover = true; + active = true; if (data->t100_aux_vect) orientation = message[data->t100_aux_vect]; @@ -936,6 +955,8 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) case MXT_T100_TYPE_GLOVE: tool = MT_TOOL_FINGER; distance = MXT_DISTANCE_ACTIVE_TOUCH; + hover = false; + active = true; if (data->t100_aux_area) major = message[data->t100_aux_area]; @@ -950,6 +971,9 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) case MXT_T100_TYPE_PASSIVE_STYLUS: tool = MT_TOOL_PEN; + distance = MXT_DISTANCE_ACTIVE_TOUCH; + hover = false; + active = true; /* * Passive stylus is reported with size zero so @@ -962,6 +986,31 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) break; + case MXT_T100_TYPE_ACTIVE_STYLUS: + /* Report input buttons */ + input_report_key(input_dev, BTN_STYLUS, +message[6] & MXT_T107_STYLUS_BUTTON0); + input_report_key(input_dev, BTN_STYLUS2, +message[6] & MXT_T107_STYLUS_BUTTON1); + + /* stylus in range, but position unavailable */ + if (!(message[6] & MXT_T107_STYLUS_HOVER)) +
[PATCH v11 00/56] atmel_mxt_ts misc
This patch-set forward ports Nick Dyer's work in ndyer/linux github repository as long as some other features and fixes Balasubramani Vivekanandan (2): Input: atmel_mxt_ts: Limit the max bytes transferred in an i2c transaction Input: atmel_mxt_ts: use gpiod_set_value_cansleep for reset pin Dean Jenkins (1): Input: atmel_mxt_ts: return error from mxt_process_messages_until_invalid() Deepak Das (6): Input: Atmel: improve error handling in mxt_start() Input: Atmel: improve error handling in mxt_initialize() Input: Atmel: improve error handling in mxt_update_cfg() Input: Atmel: Improve error handling in mxt_initialize_input_device() Input: Atmel: handle ReportID "0x00" while processing T5 messages Input: Atmel: use T44 object to process T5 messages George G. Davis (1): input: atmel_mxt_ts: export GPIO reset line via sysfs Janus Cheng (1): Input: atmel_mxt_ts - check data->input_dev is not null in mxt_input_sync() Jiada Wang (12): Input: introduce input_mt_report_slot_inactive dt-bindings: input: atmel: add suspend mode support Input: atmel_mxt_ts: Rename mxt_fw_version_show to fw_version_show Input: atmel_mxt_ts: Rename mxt_hw_version_show to hw_version_show Input: atmel_mxt_ts: rename mxt_update_fw_store to update_fw_store dt-bindings: input: atmel: provide name of configuration file dt-bindings: input: atmel: support to specify input name Input: atmel_mxt_ts - rename mxt_object_show to object_show Input: atmel_mxt_ts - delay enabling IRQ when not using regulators Input: atmel_mxt_ts - eliminate data->raw_info_block input: atmel_mxt_ts: don't disable IRQ before remove of mxt_fw_attr_group Input: atmel_mxt_ts - Fix compilation warning Karl Tsou (1): Input: atmel_mxt_ts - add debug for T92 gesture and T93 touch seq msgs Kautuk Consul (2): Input: atmel_mxt_ts - Change call-points of mxt_free_* functions Input: atmel_mxt_ts - rely on calculated_crc rather than file config_crc Naveen Chakka (2): input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen status input: atmel_mxt_ts: added sysfs interface to update atmel T38 data Nick Dyer (25): Input: atmel_mxt_ts - rework sysfs init/remove Input: atmel_mxt_ts - only read messages in mxt_acquire_irq() when necessary Input: atmel_mxt_ts - split large i2c transfers into blocks Input: atmel_mxt_ts - output status from T48 Noise Supression Input: atmel_mxt_ts - output status from T42 Touch Suppression Input: atmel_mxt_ts - implement T9 vector/orientation support Input: atmel_mxt_ts - implement T15 Key Array support Input: atmel_mxt_ts - handle reports from T47 Stylus object Input: atmel_mxt_ts - implement support for T107 active stylus Input: atmel_mxt_ts - release touch state during suspend Input: atmel_mxt_ts - add regulator control support Input: atmel_mxt_ts - report failures in suspend/resume Input: atmel_mxt_ts - allow specification of firmware file name Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs Input: atmel_mxt_ts - allow input name to be specified in platform data Input: atmel_mxt_ts - refactor firmware flash to extract context into struct Input: atmel_mxt_ts - refactor code to enter bootloader into separate func Input: atmel_mxt_ts - combine bootloader version query with probe Input: atmel_mxt_ts - improve bootloader state machine handling Input: atmel_mxt_ts - rename bl_completion to chg_completion Input: atmel_mxt_ts - make bootloader interrupt driven Input: atmel_mxt_ts - implement I2C retries Input: atmel_mxt_ts - orientation is not present in hover Input: atmel_mxt_ts - implement debug output for messages Input: atmel_mxt_ts - implement improved debug message interface Nikhil Ravindran (1): Input: atmel_mxt_ts: Add support for run self-test routine. karl tsou (1): Input: atmel_mxt_ts - add config checksum attribute to sysfs keerthikumarp (1): input: atmel_mxt_ts: Add Missing Delay for reset handling of Atmel touch panel controller in detachable displays. --- v11: Following commits in v10 have been dropped dt-bindings: input: atmel: support to set max bytes transferred Input: atmel_mxt_ts: Implement synchronization during various operation Following commits have been added Input: atmel_mxt_ts - check data->input_dev is not null in mxt_input_sync() Input: atmel_mxt_ts - rename mxt_object_show to object_show input: atmel_mxt_ts: don't disable IRQ before remove of mxt_fw_attr_group Following commits have been updated to address review findings dt-bindings: input: atmel: add suspend mode support input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen status Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs Input: atmel_mxt_ts - delay enabling IRQ when not using regulators v10: Following commits have been updated input: touchscreen: atmel_mxt_ts: Added sysfs entry for touchscreen status dt-bindings: input: atmel: add suspend mode support Input:
[PATCH v11 02/56] Input: atmel_mxt_ts - rework sysfs init/remove
From: Nick Dyer An error in the sysfs init may otherwise interfere with the async return from the firmware loader Signed-off-by: Nick Dyer (cherry picked from ndyer/linux/for-upstream commit 3114584ae77c2b03b6dad87174f010d002e9c05d) [gdavis: Forward port and fixup conflicts. Also fixed sysfs leaks in both the mxt_initialize() and mxt_probe() error return cases.] Signed-off-by: George G. Davis [jiada: keep call mxt_initialize() before sysfs creation replace S_IWUSR with 0200] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 64 +++- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a2189739e30f..49bdf5cf3a0d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2086,10 +2086,14 @@ static int mxt_initialize_input_device(struct mxt_data *data) return 0; err_free_mem: + data->input_dev = NULL; input_free_device(input_dev); return error; } +static int mxt_sysfs_init(struct mxt_data *data); +static void mxt_sysfs_remove(struct mxt_data *data); + static int mxt_configure_objects(struct mxt_data *data, const struct firmware *cfg); @@ -2141,16 +2145,24 @@ static int mxt_initialize(struct mxt_data *data) if (error) return error; + error = mxt_sysfs_init(data); + if (error) + return error; + error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, >dev, GFP_KERNEL, data, mxt_config_cb); if (error) { dev_err(>dev, "Failed to invoke firmware loader: %d\n", error); - return error; + goto err_free_sysfs; } return 0; + +err_free_sysfs: + mxt_sysfs_remove(data); + return error; } static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) @@ -2803,6 +2815,7 @@ static int mxt_load_fw(struct device *dev, const char *fn) if (ret) goto release_firmware; + mxt_sysfs_remove(data); mxt_free_input_device(data); mxt_free_object_table(data); } else { @@ -2909,16 +2922,25 @@ static ssize_t mxt_update_fw_store(struct device *dev, return count; } +static DEVICE_ATTR(update_fw, 0200, NULL, mxt_update_fw_store); + +static struct attribute *mxt_fw_attrs[] = { + _attr_update_fw.attr, + NULL +}; + +static const struct attribute_group mxt_fw_attr_group = { + .attrs = mxt_fw_attrs, +}; + static DEVICE_ATTR(fw_version, S_IRUGO, mxt_fw_version_show, NULL); static DEVICE_ATTR(hw_version, S_IRUGO, mxt_hw_version_show, NULL); static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL); -static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store); static struct attribute *mxt_attrs[] = { _attr_fw_version.attr, _attr_hw_version.attr, _attr_object.attr, - _attr_update_fw.attr, NULL }; @@ -2926,6 +2948,28 @@ static const struct attribute_group mxt_attr_group = { .attrs = mxt_attrs, }; +static int mxt_sysfs_init(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + + error = sysfs_create_group(>dev.kobj, _attr_group); + if (error) { + dev_err(>dev, "Failure %d creating sysfs group\n", + error); + return error; + } + + return 0; +} + +static void mxt_sysfs_remove(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + + sysfs_remove_group(>dev.kobj, _attr_group); +} + static void mxt_start(struct mxt_data *data) { switch (data->suspend_mode) { @@ -3112,19 +3156,14 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) if (error) return error; - error = sysfs_create_group(>dev.kobj, _attr_group); + error = sysfs_create_group(>dev.kobj, _fw_attr_group); if (error) { - dev_err(>dev, "Failure %d creating sysfs group\n", + dev_err(>dev, "Failure %d creating fw sysfs group\n", error); - goto err_free_object; + return error; } return 0; - -err_free_object: - mxt_free_input_device(data); - mxt_free_object_table(data); - return error; } static int mxt_remove(struct i2c_client *client) @@ -3132,7 +3171,8 @@ static int mxt_remove(struct i2c_client *client) struct mxt_data *data = i2c_get_clientdata(client); disable_irq(data->irq); - sysfs_remove_group(>dev.kobj, _attr_group); + sysfs_remove_group(>dev.kobj, _fw_attr_group); + mxt_sysfs_remove(data);
[PATCH v11 13/56] dt-bindings: input: atmel: add suspend mode support
Add suspend mode support for atmel touchscreen driver Signed-off-by: Jiada Wang --- .../bindings/input/atmel,maxtouch.txt | 9 MAINTAINERS | 1 + include/dt-bindings/input/atmel_mxt_ts.h | 23 +++ 3 files changed, 33 insertions(+) create mode 100644 include/dt-bindings/input/atmel_mxt_ts.h diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index c88919480d37..530312fc7a99 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt @@ -31,6 +31,15 @@ Optional properties for main touchpad device: - reset-gpios: GPIO specifier for the touchscreen's reset pin (active low) +- atmel,suspend-mode: Select method used to suspend: +MXT_SUSPEND_DEEP_SLEEP - use T7 to suspend the device into deep sleep +MXT_SUSPEND_T9_CTRL - use T9.CTRL to turn off touch processing +MXT_SUSPEND_REGULATOR - use regulators to power down device during suspend +Definitions are in . + +- vdd: vdd: phandle to Power supply regulator +- avdd: phandle to Analog Power supply regulator + Example: touch@4b { diff --git a/MAINTAINERS b/MAINTAINERS index e48ab79879ac..350ae664e6f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2873,6 +2873,7 @@ T:git git://github.com/ndyer/linux.git S: Maintained F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt F: drivers/input/touchscreen/atmel_mxt_ts.c +F: include/dt-bindings/input/atmel_mxt_ts.h ATMEL WIRELESS DRIVER M: Simon Kelley diff --git a/include/dt-bindings/input/atmel_mxt_ts.h b/include/dt-bindings/input/atmel_mxt_ts.h new file mode 100644 index ..41ed0f8111aa --- /dev/null +++ b/include/dt-bindings/input/atmel_mxt_ts.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Atmel maXTouch Touchscreen driver + * + * Copyright (C) 2015 Atmel Corporation + * Author: Nick Dyer + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __DT_BINDINGS_ATMEL_MXT_TS_H +#define __DT_BINDINGS_ATMEL_MXT_TS_H + +enum mxt_suspend_mode { + MXT_SUSPEND_DEEP_SLEEP = 0, + MXT_SUSPEND_T9_CTRL = 1, + MXT_SUSPEND_REGULATOR = 2, +}; + +#endif /* __DT_BINDINGS_ATMEL_MXT_TS_H */ -- 2.17.1
[PATCH v11 06/56] Input: atmel_mxt_ts - output status from T42 Touch Suppression
From: Nick Dyer This patch outputs status from T42 touch suppression Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit ab95b5a30d2c098daaa9f88d9fcfae7eb516) Signed-off-by: George G. Davis [jiada: Replace dev_info() with dev_dbg()] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 25 1 file changed, 25 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index a53985a7736f..f6465edaa57e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -155,6 +155,9 @@ struct t37_debug { #define MXT_RESET_VALUE0x01 #define MXT_BACKUP_VALUE 0x55 +/* Define for MXT_PROCI_TOUCHSUPPRESSION_T42 */ +#define MXT_T42_MSG_TCHSUP BIT(0) + /* T100 Multiple Touch Touchscreen */ #define MXT_T100_CTRL 0 #define MXT_T100_CFG1 1 @@ -323,6 +326,8 @@ struct mxt_data { u8 T9_reportid_max; u16 T18_address; u8 T19_reportid; + u8 T42_reportid_min; + u8 T42_reportid_max; u16 T44_address; u8 T48_reportid; u8 T100_reportid_min; @@ -979,6 +984,17 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) data->update_input = true; } +static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = >client->dev; + u8 status = msg[1]; + + if (status & MXT_T42_MSG_TCHSUP) + dev_dbg(dev, "T42 suppress\n"); + else + dev_dbg(dev, "T42 normal\n"); +} + static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg) { struct device *dev = >client->dev; @@ -1006,6 +1022,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) if (report_id == data->T6_reportid) { mxt_proc_t6_messages(data, message); + } else if (report_id >= data->T42_reportid_min + && report_id <= data->T42_reportid_max) { + mxt_proc_t42_messages(data, message); } else if (report_id == data->T48_reportid) { mxt_proc_t48_messages(data, message); } else if (!data->input_dev) { @@ -1686,6 +1705,8 @@ static void mxt_free_object_table(struct mxt_data *data) data->T9_reportid_max = 0; data->T18_address = 0; data->T19_reportid = 0; + data->T42_reportid_min = 0; + data->T42_reportid_max = 0; data->T44_address = 0; data->T48_reportid = 0; data->T100_reportid_min = 0; @@ -1763,6 +1784,10 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_SPT_COMMSCONFIG_T18: data->T18_address = object->start_address; break; + case MXT_PROCI_TOUCHSUPPRESSION_T42: + data->T42_reportid_min = min_id; + data->T42_reportid_max = max_id; + break; case MXT_SPT_MESSAGECOUNT_T44: data->T44_address = object->start_address; break; -- 2.17.1
[PATCH v11 01/56] Input: introduce input_mt_report_slot_inactive
input_mt_report_slot_state() ignores the tool when the slot is closed. which has caused a bit of confusion. This patch introduces input_mt_report_slot_inactive() to report slot inactive state. replaces all input_mt_report_slot_state() with input_mt_report_slot_inactive() in case of close of slot. Suggested-by: Dmitry Torokhov Reported-by: kernel test robot Signed-off-by: Jiada Wang --- drivers/hid/hid-alps.c | 3 +-- drivers/hid/hid-multitouch.c | 6 ++ drivers/input/misc/xen-kbdfront.c | 2 +- drivers/input/mouse/elan_i2c_core.c| 2 +- drivers/input/touchscreen/atmel_mxt_ts.c | 7 +++ drivers/input/touchscreen/cyttsp4_core.c | 5 ++--- drivers/input/touchscreen/cyttsp_core.c| 2 +- drivers/input/touchscreen/melfas_mip4.c| 4 ++-- drivers/input/touchscreen/mms114.c | 2 +- drivers/input/touchscreen/raspberrypi-ts.c | 2 +- drivers/input/touchscreen/stmfts.c | 2 +- include/linux/input/mt.h | 5 + 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c index ae79a7c66737..36ca1d815d53 100644 --- a/drivers/hid/hid-alps.c +++ b/drivers/hid/hid-alps.c @@ -387,8 +387,7 @@ static int u1_raw_event(struct alps_dev *hdata, u8 *data, int size) input_report_abs(hdata->input, ABS_MT_PRESSURE, z); } else { - input_mt_report_slot_state(hdata->input, - MT_TOOL_FINGER, 0); + input_mt_report_slot_inactive(hdata->input); } } diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 362805ddf377..e2ce790ff4a4 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -896,7 +896,7 @@ static void mt_release_pending_palms(struct mt_device *td, clear_bit(slotnum, app->pending_palm_slots); input_mt_slot(input, slotnum); - input_mt_report_slot_state(input, MT_TOOL_PALM, false); + input_mt_report_slot_inactive(input); need_sync = true; } @@ -1640,9 +1640,7 @@ static void mt_release_contacts(struct hid_device *hid) if (mt) { for (i = 0; i < mt->num_slots; i++) { input_mt_slot(input_dev, i); - input_mt_report_slot_state(input_dev, - MT_TOOL_FINGER, - false); + input_mt_report_slot_inactive(input_dev); } input_mt_sync_frame(input_dev); input_sync(input_dev); diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 24bc5c5d876f..a1bba722b234 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c @@ -146,7 +146,7 @@ static void xenkbd_handle_mt_event(struct xenkbd_info *info, break; case XENKBD_MT_EV_UP: - input_mt_report_slot_state(info->mtouch, MT_TOOL_FINGER, false); + input_mt_report_slot_inactive(info->mtouch); break; case XENKBD_MT_EV_SYN: diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 8719da540383..3f9354baac4b 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -938,7 +938,7 @@ static void elan_report_contact(struct elan_tp_data *data, input_report_abs(input, ABS_MT_TOUCH_MINOR, minor); } else { input_mt_slot(input, contact_num); - input_mt_report_slot_state(input, MT_TOOL_FINGER, false); + input_mt_report_slot_inactive(input); } } diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index ae60442efda0..a2189739e30f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -822,8 +822,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) * have happened. */ if (status & MXT_T9_RELEASE) { - input_mt_report_slot_state(input_dev, - MT_TOOL_FINGER, 0); + input_mt_report_slot_inactive(input_dev); mxt_input_sync(data); } @@ -839,7 +838,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); } else { /* Touch no longer active, close out slot */ -
[PATCH v11 05/56] Input: atmel_mxt_ts - output status from T48 Noise Supression
From: Nick Dyer This patch outputs status from T48 Noise Supression Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 2895a6ff150a49f27a02938f8d262be238b296d8) Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 25 1 file changed, 25 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 7e6a66e3e1e0..a53985a7736f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -324,6 +324,7 @@ struct mxt_data { u16 T18_address; u8 T19_reportid; u16 T44_address; + u8 T48_reportid; u8 T100_reportid_min; u8 T100_reportid_max; @@ -978,6 +979,24 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) data->update_input = true; } +static int mxt_proc_t48_messages(struct mxt_data *data, u8 *msg) +{ + struct device *dev = >client->dev; + u8 status, state; + + status = msg[1]; + state = msg[4]; + + dev_dbg(dev, "T48 state %d status %02X %s%s%s%s%s\n", state, status, + status & 0x01 ? "FREQCHG " : "", + status & 0x02 ? "APXCHG " : "", + status & 0x04 ? "ALGOERR " : "", + status & 0x10 ? "STATCHG " : "", + status & 0x20 ? "NLVLCHG " : ""); + + return 0; +} + static int mxt_proc_message(struct mxt_data *data, u8 *message) { u8 report_id = message[0]; @@ -987,6 +1006,8 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) if (report_id == data->T6_reportid) { mxt_proc_t6_messages(data, message); + } else if (report_id == data->T48_reportid) { + mxt_proc_t48_messages(data, message); } else if (!data->input_dev) { /* * Do not report events if input device @@ -1666,6 +1687,7 @@ static void mxt_free_object_table(struct mxt_data *data) data->T18_address = 0; data->T19_reportid = 0; data->T44_address = 0; + data->T48_reportid = 0; data->T100_reportid_min = 0; data->T100_reportid_max = 0; data->max_reportid = 0; @@ -1747,6 +1769,9 @@ static int mxt_parse_object_table(struct mxt_data *data, case MXT_SPT_GPIOPWM_T19: data->T19_reportid = min_id; break; + case MXT_PROCG_NOISESUPPRESSION_T48: + data->T48_reportid = min_id; + break; case MXT_TOUCH_MULTITOUCHSCREEN_T100: data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100; data->T100_reportid_min = min_id; -- 2.17.1
[PATCH v11 12/56] Input: atmel_mxt_ts - release touch state during suspend
From: Nick Dyer If fingers are down as the MXT chip goes into suspend it does not send a lift message. In addition, it may not complete its final measurement cycle immediately, which means touch messages may be received by the interrupt handler after mxt_stop() has completed. So: - disable irq during suspend - flush any messages created after suspend - tell app layer that slots were released at suspend Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 26794433086dbc7dea18d2f6a1c8d61ab25bcfda) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [gdavis: Squash fix from Dirk Behme: - Input: atmel_mxt_ts - remove superfluous data->suspended] Signed-off-by: Dirk Behme --- drivers/input/touchscreen/atmel_mxt_ts.c | 52 ++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 6126bb8a7acc..9aafed92db9c 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -372,6 +372,9 @@ struct mxt_data { unsigned int t19_num_keys; enum mxt_suspend_mode suspend_mode; + + /* Indicates whether device is in suspend */ + bool suspended; }; struct mxt_vb2_buffer { @@ -1151,10 +1154,10 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) mxt_proc_t42_messages(data, message); } else if (report_id == data->T48_reportid) { mxt_proc_t48_messages(data, message); - } else if (!data->input_dev) { + } else if (!data->input_dev || data->suspended) { /* -* Do not report events if input device -* is not yet registered. +* Do not report events if input device is not +* yet registered or returning from suspend */ mxt_dump_message(data, message); } else if (report_id >= data->T9_reportid_min && @@ -3135,6 +3138,11 @@ static int mxt_load_fw(struct device *dev, const char *fn) if (ret) goto release_firmware; + if (data->suspended) { + enable_irq(data->irq); + data->suspended = false; + } + if (!data->in_bootloader) { /* Change to the bootloader mode */ data->in_bootloader = true; @@ -3306,8 +3314,27 @@ static void mxt_sysfs_remove(struct mxt_data *data) sysfs_remove_group(>dev.kobj, _attr_group); } +static void mxt_reset_slots(struct mxt_data *data) +{ + struct input_dev *input_dev = data->input_dev; + int id; + + if (!input_dev) + return; + + for (id = 0; id < data->num_touchids; id++) { + input_mt_slot(input_dev, id); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); + } + + mxt_input_sync(data); +} + static void mxt_start(struct mxt_data *data) { + if (!data->suspended || data->in_bootloader) + return; + switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: mxt_soft_reset(data); @@ -3320,16 +3347,29 @@ static void mxt_start(struct mxt_data *data) case MXT_SUSPEND_DEEP_SLEEP: default: + /* +* Discard any touch messages still in message buffer +* from before chip went to sleep +*/ + mxt_process_messages_until_invalid(data); + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN); /* Recalibrate since chip has been in deep sleep */ mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false); + + mxt_acquire_irq(data); break; } + + data->suspended = false; } static void mxt_stop(struct mxt_data *data) { + if (data->suspended || data->in_bootloader) + return; + switch (data->suspend_mode) { case MXT_SUSPEND_T9_CTRL: /* Touch disable */ @@ -3339,9 +3379,15 @@ static void mxt_stop(struct mxt_data *data) case MXT_SUSPEND_DEEP_SLEEP: default: + disable_irq(data->irq); + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP); + + mxt_reset_slots(data); break; } + + data->suspended = true; } static int mxt_input_open(struct input_dev *dev) -- 2.17.1
[PATCH v11 09/56] Input: atmel_mxt_ts - handle reports from T47 Stylus object
From: Nick Dyer This patch handles reports from T47 Stylus object Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 56405a5ea08eb34cfe83f3121867c9de0a5c48c1) Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index d05249b02781..ba58cdd5b76d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -823,6 +823,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) int area; int amplitude; u8 vector; + int tool; id = message[0] - data->T9_reportid_min; status = message[1]; @@ -836,6 +837,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) y >>= 2; area = message[5]; + amplitude = message[6]; vector = message[7]; @@ -865,12 +867,20 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) mxt_input_sync(data); } + /* A size of zero indicates touch is from a linked T47 Stylus */ + if (area == 0) { + area = MXT_TOUCH_MAJOR_DEFAULT; + tool = MT_TOOL_PEN; + } else { + tool = MT_TOOL_FINGER; + } + /* if active, pressure must be non-zero */ if (!amplitude) amplitude = MXT_PRESSURE_DEFAULT; /* Touch active */ - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1); + input_mt_report_slot_state(input_dev, tool, 1); input_report_abs(input_dev, ABS_MT_POSITION_X, x); input_report_abs(input_dev, ABS_MT_POSITION_Y, y); input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude); -- 2.17.1
[PATCH v11 07/56] Input: atmel_mxt_ts - implement T9 vector/orientation support
From: Nick Dyer The atmel touch messages contain orientation information as a byte in a packed format which can be passed straight on to Android if the input device configuration is correct. This requires vector reports to be enabled in maXTouch config (zero DISVECT bit 3 in T9 CTRL field) Android converts the format in InputReader.cpp, search for ORIENTATION_CALIBRATION_VECTOR. Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit a6f0ee919d2631678169b23fb18f55b6dbabcd4c) Signed-off-by: George G. Davis Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index f6465edaa57e..df2e0ba76e63 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -817,6 +817,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) int y; int area; int amplitude; + u8 vector; id = message[0] - data->T9_reportid_min; status = message[1]; @@ -831,9 +832,10 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) area = message[5]; amplitude = message[6]; + vector = message[7]; dev_dbg(dev, - "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n", + "[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u vector: %02X\n", id, (status & MXT_T9_DETECT) ? 'D' : '.', (status & MXT_T9_PRESS) ? 'P' : '.', @@ -843,7 +845,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) (status & MXT_T9_AMP) ? 'A' : '.', (status & MXT_T9_SUPPRESS) ? 'S' : '.', (status & MXT_T9_UNGRIP) ? 'U' : '.', - x, y, area, amplitude); + x, y, area, amplitude, vector); input_mt_slot(input_dev, id); @@ -868,6 +870,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) input_report_abs(input_dev, ABS_MT_POSITION_Y, y); input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude); input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); + input_report_abs(input_dev, ABS_MT_ORIENTATION, vector); } else { /* Touch no longer active, close out slot */ input_mt_report_slot_inactive(input_dev); @@ -2180,8 +2183,9 @@ static int mxt_initialize_input_device(struct mxt_data *data) 0, 255, 0, 0); } - if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && - data->t100_aux_vect) { + if (data->multitouch == MXT_TOUCH_MULTI_T9 || + (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && + data->t100_aux_vect)) { input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 255, 0, 0); } -- 2.17.1
[PATCH v11 08/56] Input: atmel_mxt_ts - implement T15 Key Array support
From: Nick Dyer There is a key array object in many maXTouch chips which allows some X/Y lines to be used as a key array. This patch maps them to a series of keys which may be configured in a platform data array. Signed-off-by: Nick Dyer Acked-by: Benson Leung Acked-by: Yufeng Shen (cherry picked from ndyer/linux/for-upstream commit 15bb074b5abf3a101f7b79544213f1c110ea4cab) [gdavis: Resolve forward port conflicts due to applying upstream commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform data support").] Signed-off-by: George G. Davis [jiada: Fix compilation warning] Signed-off-by: Jiada Wang --- drivers/input/touchscreen/atmel_mxt_ts.c | 85 1 file changed, 85 insertions(+) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index df2e0ba76e63..d05249b02781 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -314,6 +314,9 @@ struct mxt_data { struct mxt_dbg dbg; struct gpio_desc *reset_gpio; bool use_retrigen_workaround; + unsigned long t15_keystatus; + int t15_num_keys; + const unsigned int *t15_keymap; /* Cached parameters from object table */ u16 T5_address; @@ -324,6 +327,8 @@ struct mxt_data { u16 T71_address; u8 T9_reportid_min; u8 T9_reportid_max; + u8 T15_reportid_min; + u8 T15_reportid_max; u16 T18_address; u8 T19_reportid; u8 T42_reportid_min; @@ -987,6 +992,38 @@ static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) data->update_input = true; } +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *msg) +{ + struct input_dev *input_dev = data->input_dev; + struct device *dev = >client->dev; + int key; + bool curr_state, new_state; + bool sync = false; + unsigned long keystates = le32_to_cpu((__force __le32)msg[2]); + + for (key = 0; key < data->t15_num_keys; key++) { + curr_state = test_bit(key, >t15_keystatus); + new_state = test_bit(key, ); + + if (!curr_state && new_state) { + dev_dbg(dev, "T15 key press: %u\n", key); + __set_bit(key, >t15_keystatus); + input_event(input_dev, EV_KEY, + data->t15_keymap[key], 1); + sync = true; + } else if (curr_state && !new_state) { + dev_dbg(dev, "T15 key release: %u\n", key); + __clear_bit(key, >t15_keystatus); + input_event(input_dev, EV_KEY, + data->t15_keymap[key], 0); + sync = true; + } + } + + if (sync) + input_sync(input_dev); +} + static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg) { struct device *dev = >client->dev; @@ -1045,6 +1082,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) } else if (report_id == data->T19_reportid) { mxt_input_button(data, message); data->update_input = true; + } else if (report_id >= data->T15_reportid_min + && report_id <= data->T15_reportid_max) { + mxt_proc_t15_messages(data, message); } else { mxt_dump_message(data, message); } @@ -1706,6 +1746,8 @@ static void mxt_free_object_table(struct mxt_data *data) data->T71_address = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + data->T15_reportid_min = 0; + data->T15_reportid_max = 0; data->T18_address = 0; data->T19_reportid = 0; data->T42_reportid_min = 0; @@ -1784,6 +1826,10 @@ static int mxt_parse_object_table(struct mxt_data *data, object->num_report_ids - 1; data->num_touchids = object->num_report_ids; break; + case MXT_TOUCH_KEYARRAY_T15: + data->T15_reportid_min = min_id; + data->T15_reportid_max = max_id; + break; case MXT_SPT_COMMSCONFIG_T18: data->T18_address = object->start_address; break; @@ -2077,6 +2123,7 @@ static int mxt_initialize_input_device(struct mxt_data *data) int error; unsigned int num_mt_slots; unsigned int mt_flags = 0; + int i; switch (data->multitouch) { case MXT_TOUCH_MULTI_T9: @@ -2190,6 +2237,15 @@ static int mxt_initialize_input_device(struct mxt_data *data) 0, 255, 0, 0); } + /* For T15 Key Array */ + if (data->T15_reportid_min) { + data->t15_keystatus = 0; + +
Re: [PATCH 05/11] net: core: provide devm_register_netdev()
On 08.05.2020 00:56, Jakub Kicinski wrote: > On Thu, 7 May 2020 19:03:44 +0200 Bartosz Golaszewski wrote: >>> To implement Edwin's suggestion? Makes sense, but I'm no expert, let's >>> also CC Heiner since he was asking about it last time. >> >> Yes, because taking the last bit of priv_flags from net_device seems >> to be more controversial but if net maintainers are fine with that I >> can simply go with the current approach. > > From my perspective what Edwin suggests makes sense. Apart from > little use for the bit after probe, it also seems cleaner for devres > to be able to recognize managed objects based on its own state. > What I was saying is that we should catch the case that a driver author uses a device-managed register() w/o doing the same for the alloc(). A core function should not assume that driver authors do sane things only. I don't have a strong preference how it should be done. Considering what is being discussed, have a look at get_pci_dr() and find_pci_dr(), they deal with managing which parts of the PCI subsystem are device-managed.
[PATCH] ata: sata_nv: use enum values as array indeces
Positions of the entries in nv_port_info[] must be consistent to enum nv_host_type. Ensure this by using the enum as array index directly. Signed-off-by: Sascha Hauer --- drivers/ata/sata_nv.c | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 20190f66ced9..25c53fa17b33 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -520,8 +520,7 @@ struct nv_pi_priv { &(struct nv_pi_priv){ .irq_handler = _irq_handler, .sht = _sht } static const struct ata_port_info nv_port_info[] = { - /* generic */ - { + [GENERIC] = { .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, @@ -529,8 +528,7 @@ static const struct ata_port_info nv_port_info[] = { .port_ops = _generic_ops, .private_data = NV_PI_PRIV(nv_generic_interrupt, _sht), }, - /* nforce2/3 */ - { + [NFORCE2] = { .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, @@ -538,8 +536,7 @@ static const struct ata_port_info nv_port_info[] = { .port_ops = _nf2_ops, .private_data = NV_PI_PRIV(nv_nf2_interrupt, _sht), }, - /* ck804 */ - { + [CK804] = { .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, @@ -547,8 +544,7 @@ static const struct ata_port_info nv_port_info[] = { .port_ops = _ck804_ops, .private_data = NV_PI_PRIV(nv_ck804_interrupt, _sht), }, - /* ADMA */ - { + [ADMA] = { .flags = ATA_FLAG_SATA | ATA_FLAG_NCQ, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, @@ -556,8 +552,7 @@ static const struct ata_port_info nv_port_info[] = { .port_ops = _adma_ops, .private_data = NV_PI_PRIV(nv_adma_interrupt, _adma_sht), }, - /* MCP5x */ - { + [MCP5x] = { .flags = ATA_FLAG_SATA, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, @@ -565,8 +560,7 @@ static const struct ata_port_info nv_port_info[] = { .port_ops = _generic_ops, .private_data = NV_PI_PRIV(nv_generic_interrupt, _sht), }, - /* SWNCQ */ - { + [SWNCQ] = { .flags = ATA_FLAG_SATA | ATA_FLAG_NCQ, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, -- 2.26.2
Re: [PATCH v2] perf: fix compilation failure on i386
BTW, this is reported by kernel test robot , so please help to add: Reported-by: kernel test robot when it got merged. -- Sincerely, Cao jin On 5/1/20 4:25 PM, Cao jin wrote: > Compilation on i386 complains as following: > > util/session.c: In function 'perf_session__process_compressed_event': > util/session.c:91:11: error: format '%ld' expects argument of type 'long > int', but argument 4 has type 'size_t {aka unsigned int}' [-Werror=format=] > pr_debug("decomp (B): %ld to %ld\n", src_size, decomp_size); >^ > > util/zstd.c: In function 'zstd_decompress_stream': > util/zstd.c:102:11: error: format '%ld' expects argument of type 'long int', > but argument 4 has type 'size_t {aka unsigned int}' [-Werror=format=] > pr_err("failed to decompress (B): %ld -> %ld, dst_size %ld : %s\n", >^ > > Fix them by pairing "%zd" to size_t. > > Also revert an unnecessary conversion: "(long)src_size" to plain "src_size" > with conversion specifier "%zd". > > Signed-off-by: Cao jin > --- > tools/perf/util/session.c | 2 +- > tools/perf/util/zstd.c| 6 +++--- > 2 files changed, 4 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c > index 0b0bfe5bef17..50c2ffa388ad 100644 > --- a/tools/perf/util/session.c > +++ b/tools/perf/util/session.c > @@ -88,7 +88,7 @@ static int perf_session__process_compressed_event(struct > perf_session *session, > session->decomp_last = decomp; > } > > - pr_debug("decomp (B): %ld to %ld\n", src_size, decomp_size); > + pr_debug("decomp (B): %zd to %zd\n", src_size, decomp_size); > > return 0; > } > diff --git a/tools/perf/util/zstd.c b/tools/perf/util/zstd.c > index d2202392ffdb..877bfb79e4af 100644 > --- a/tools/perf/util/zstd.c > +++ b/tools/perf/util/zstd.c > @@ -74,8 +74,8 @@ size_t zstd_compress_stream_to_records(struct zstd_data > *data, void *dst, size_t > ret = ZSTD_compressStream(data->cstream, , ); > ZSTD_flushStream(data->cstream, ); > if (ZSTD_isError(ret)) { > - pr_err("failed to compress %ld bytes: %s\n", > - (long)src_size, ZSTD_getErrorName(ret)); > + pr_err("failed to compress %zd bytes: %s\n", > + src_size, ZSTD_getErrorName(ret)); > memcpy(dst, src, src_size); > return src_size; > } > @@ -99,7 +99,7 @@ size_t zstd_decompress_stream(struct zstd_data *data, void > *src, size_t src_size > while (input.pos < input.size) { > ret = ZSTD_decompressStream(data->dstream, , ); > if (ZSTD_isError(ret)) { > - pr_err("failed to decompress (B): %ld -> %ld, dst_size > %ld : %s\n", > + pr_err("failed to decompress (B): %zd -> %zd, dst_size > %zd : %s\n", > src_size, output.size, dst_size, > ZSTD_getErrorName(ret)); > break; > } >
[PATCH 2/3] dts: ppc: t4240rdb: add uie_unsupported property to drop warning
From: Biwen Li This adds uie_unsupported property to drop warning as follows: - $ hwclock.util-linux hwclock.util-linux: select() to /dev/rtc0 to wait for clock tick timed out My case: - RTC ds1374's INT pin is connected to VCC on T4240RDB, then the RTC cannot inform cpu about the alarm interrupt Signed-off-by: Biwen Li --- arch/powerpc/boot/dts/fsl/t4240rdb.dts | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/fsl/t4240rdb.dts b/arch/powerpc/boot/dts/fsl/t4240rdb.dts index a56a705d41f7..ccdd10202e56 100644 --- a/arch/powerpc/boot/dts/fsl/t4240rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t4240rdb.dts @@ -144,7 +144,11 @@ rtc@68 { compatible = "dallas,ds1374"; reg = <0x68>; - interrupts = <0x1 0x1 0 0>; + // The ds1374's INT pin isn't + // connected to cpu's INT pin, + // so the rtc cannot synchronize + // clock tick per second. + uie_unsupported; }; }; -- 2.17.1
[PATCH 3/3] dts: ppc: t1024rdb: add wakeup-source property to drop warning
From: Biwen Li This adds wakeup-source property to drop warning as follows: - $ hwclock.util-linux hwclock.util-linux: select() to /dev/rtc0 to wait for clock tick timed out My case: - RTC ds1339s INT pin isn't connected to cpus INT pin on T1024RDB, then the RTC cannot inform cpu about alarm interrupt How to fix it? - add wakeup-source property and remove IRQ line to set uie_unsupported flag Signed-off-by: Biwen Li --- arch/powerpc/boot/dts/fsl/t1024rdb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/fsl/t1024rdb.dts b/arch/powerpc/boot/dts/fsl/t1024rdb.dts index 645caff98ed1..191cbf5cda4e 100644 --- a/arch/powerpc/boot/dts/fsl/t1024rdb.dts +++ b/arch/powerpc/boot/dts/fsl/t1024rdb.dts @@ -161,7 +161,7 @@ rtc@68 { compatible = "dallas,ds1339"; reg = <0x68>; - interrupts = <0x1 0x1 0 0>; + wakeup-source; }; }; -- 2.17.1
[PATCH 1/3] rtc: ds1374: add uie_unsupported property to drop warning
From: Biwen Li Add uie_unsupported property to drop warning as follows: - $ hwclock.util-linux hwclock.util-liux: select() /dev/rtc0 to wait for clock tick timed out My case: - RTC ds1374's INT pin is connected to VCC on T4240RDB, then the RTC cannot inform cpu about the alarm interrupt Signed-off-by: Biwen Li --- drivers/rtc/rtc-ds1374.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 9c51a12cf70f..e530e887a17e 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -651,6 +651,10 @@ static int ds1374_probe(struct i2c_client *client, if (ret) return ret; + if (of_property_read_bool(client->dev.of_node, +"uie_unsupported")) + ds1374->rtc->uie_unsupported = true; + #ifdef CONFIG_RTC_DRV_DS1374_WDT save_client = client; ret = misc_register(_miscdev); -- 2.17.1
Re: [PATCH 6/7] exec: Move most of setup_new_exec into flush_old_exec
On Thu, May 07, 2020 at 04:51:13PM -0500, Eric W. Biederman wrote: > I intend to the following text to the changelog. At this point I > believe I have read through everything and nothing raises any concerns > for me: > > --- text begin --- > > To see why it is safe to move this code please note that effectively > this change moves the personality setting in the binfmt and the following > three lines of code after everything except unlocking the mutexes: > arch_pick_mmap_layout > arch_setup_new_exec > mm->task_size = TASK_SIZE > > The function arch_pick_mmap_layout at most sets: > mm->get_unmapped_area > mm->mmap_base > mm->mmap_legacy_base > mm->mmap_compat_base > mm->mmap_compat_legacy_base > which nothing in flush_old_exec or setup_new_exec depends on. > > The function arch_setup_new_exec only sets architecture specific > state and the rest of the functions only deal in state that applies > to all architectures. > > The last line just sets mm->task_size and again nothing in flush_old_exec > or setup_new_exec depend on task_size. > > --- text end --- > [...] > > So, with a bit larger changelog discussing what's moving "earlier", > > I think this looks good: > > Please see above. Awesome! Thanks for checking my checking of your checking. ;) Acked-by: Kees Cook -- Kees Cook
Re: [RFC] taint: add module firmware crash taint support
On Fri, May 08, 2020 at 02:14:38AM +, Luis Chamberlain wrote: > Device driver firmware can crash, and sometimes, this can leave your > system in a state which makes the device or subsystem completely > useless. Detecting this by inspecting /proc/sys/kernel/tainted instead > of scraping some magical words from the kernel log, which is driver > specific, is much easier. So instead provide a helper which lets drivers > annotate this. > > Once this happens, scrapers can easily scrape modules taint flags. > This will taint both the kernel and respective calling module. > > The new helper module_firmware_crashed() uses LOCKDEP_STILL_OK as > this fact should in no way shape or form affect lockdep. This taint > is device driver specific. > > Signed-off-by: Luis Chamberlain > --- > > Below is the full diff stat of manual inspection throughout the kernel > when this happens. My methodology is to just scrape for "crash" and > then study the driver a bit to see if indeed it seems like that the > firmware crashes there. In *many* cases there is even infrastructure > for this, so this is sometimes clearly obvious. Some other times it > required a bit of deciphering. > > The diff stat below is what I have so far, however the patch below > only includes the drivers that start with Q, as they were a source of > inspiration for this, and to make this RFC easier to read. > > If this seems sensible, I can follow up with the kernel helper first, > and then tackle each subsystem independently. > > I purposely skipped review of remoteproc and virtualization. That should > require its own separate careful review and considerations. This all seems reasonable to me. You might need to break these up into per-maintainer patches to get appropriate review. Perhaps land the infrastructure and some initial patches via netdev and in the next release send patches for DRM, media, etc? -- Kees Cook
Re: [PATCH v2] libata: Fix retrieving of active qcs
On Sun, May 03, 2020 at 11:46:27PM +0200, Pali Rohár wrote: > On Monday 27 January 2020 12:24:28 Sascha Hauer wrote: > > On Mon, Jan 27, 2020 at 12:16:30PM +0100, Pali Rohár wrote: > > > On Monday 06 January 2020 09:16:05 Sascha Hauer wrote: > > > > On Wed, Dec 25, 2019 at 07:18:40PM +0100, Pali Rohár wrote: > > > > > Hello Sascha! > > > > > > > > > > On Friday 13 December 2019 09:04:08 Sascha Hauer wrote: > > > > > > ata_qc_complete_multiple() is called with a mask of the still active > > > > > > tags. > > > > > > > > > > > > mv_sata doesn't have this information directly and instead > > > > > > calculates > > > > > > the still active tags from the started tags (ap->qc_active) and the > > > > > > finished tags as (ap->qc_active ^ done_mask) > > > > > > > > > > > > Since 28361c40368 the hw_tag and tag are no longer the same and the > > > > > > equation is no longer valid. In ata_exec_internal_sg() > > > > > > ap->qc_active is > > > > > > initialized as 1ULL << ATA_TAG_INTERNAL, but in hardware tag 0 is > > > > > > started and this will be in done_mask on completion. ap->qc_active ^ > > > > > > done_mask becomes 0x1 ^ 0x1 = 0x10001 and thus tag 0 > > > > > > used as > > > > > > the internal tag will never be reported as completed. > > > > > > > > > > > > This is fixed by introducing ata_qc_get_active() which returns the > > > > > > active hardware tags and calling it where appropriate. > > > > > > > > > > > > This is tested on mv_sata, but sata_fsl and sata_nv suffer from the > > > > > > same > > > > > > problem. There is another case in sata_nv that most likely needs > > > > > > fixing > > > > > > as well, but this looks a little different, so I wasn't confident > > > > > > enough > > > > > > to change that. > > > > > > > > > > I can confirm that sata_nv.ko does not work in 4.18 (and new) kernel > > > > > version correctly. More details are in email: > > > > > > > > > > https://lore.kernel.org/linux-ide/20191225180824.bql2o5whougii4ch@pali/T/ > > > > > > > > > > I tried this patch and it fixed above problems with sata_nv.ko. It > > > > > just > > > > > needs small modification (see below). > > > > > > > > > > So you can add my: > > > > > > > > > > Tested-by: Pali Rohár > > > > > > > > > > And I hope that patch would be backported to 4.18 and 4.19 stable > > > > > branches soon as distributions kernels are broken for machines with > > > > > these nvidia sata controllers. > > > > > > > > > > Anyway, what is that another case in sata_nv which needs to be fixed > > > > > too? > > > > > > > > It's in nv_swncq_sdbfis(). Here we have: > > > > > > > > sactive = readl(pp->sactive_block); > > > > done_mask = pp->qc_active ^ sactive; > > > > > > > > pp->qc_active &= ~done_mask; > > > > pp->dhfis_bits &= ~done_mask; > > > > pp->dmafis_bits &= ~done_mask; > > > > pp->sdbfis_bits |= done_mask; > > > > ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); > > > > > > > > Sascha > > > > > > Ok. Are you going to fix also this case? > > > > As said, this one looks slightly different than the others and I would > > prefer if somebody could fix it who actually has a hardware and can test > > it. > > Well, I have hardware and could test changes. But I'm not really sure > that I understand this part of code. So it would be better if somebody > else with better knowledge prepares patches I could test them. But > currently during coronavirus I have only remote ssh access, so boot, > modify/compile/reboot process is quite slower. Ok, here we go. Compile tested only. Regards, Sascha --8<--- >From fcdcfa9e7a4ee4faf411de1df4f3c4e12c78545c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 8 May 2020 07:28:19 +0200 Subject: [PATCH] ata: sata_nv: Fix retrieving of active qcs ata_qc_complete_multiple() has to be called with the tags physically active, that is the hw tag is at bit 0. ap->qc_active has the same tag at bit ATA_TAG_INTERNAL instead, so call ata_qc_get_active() to fix that up. This is done in the vein of 8385d756e114 ("libata: Fix retrieving of active qcs"). Signed-off-by: Sascha Hauer --- drivers/ata/sata_nv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index eb9dc14e5147..20190f66ced9 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -2100,7 +2100,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap) pp->dhfis_bits &= ~done_mask; pp->dmafis_bits &= ~done_mask; pp->sdbfis_bits |= done_mask; - ata_qc_complete_multiple(ap, ap->qc_active ^ done_mask); + ata_qc_complete_multiple(ap, ata_qc_get_active(ap) ^ done_mask); if (!ap->qc_active) { DPRINTK("over\n"); -- 2.26.2 -- Pengutronix e.K. | | Steuerwalder Str. 21 |
Re: [PATCH v6 3/8] bus: mhi: core: Add range check for channel id received in event ring
On Tue, May 05, 2020 at 03:47:07PM -0700, Bhaumik Bhatt wrote: > From: Hemant Kumar > > MHI data completion handler function reads channel id from event > ring element. Value is under the control of MHI devices and can be > any value between 0 and 255. In order to prevent out of bound access > add a bound check against the max channel supported by controller > and skip processing of that event ring element. > > Signed-off-by: Hemant Kumar > Signed-off-by: Bhaumik Bhatt > Reviewed-by: Jeffrey Hugo > --- > drivers/bus/mhi/core/main.c | 8 > 1 file changed, 8 insertions(+) > > diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c > index 605640c..e60ab21 100644 > --- a/drivers/bus/mhi/core/main.c > +++ b/drivers/bus/mhi/core/main.c > @@ -776,6 +776,9 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller > *mhi_cntrl, > case MHI_PKT_TYPE_TX_EVENT: > chan = MHI_TRE_GET_EV_CHID(local_rp); > mhi_chan = _cntrl->mhi_chan[chan]; Check should be done before this statement, isn't it? > + if (WARN_ON(chan >= mhi_cntrl->max_chan)) > + goto next_event; > + I don't prefer using gotos for non exit paths but I don't have a better solution here. But you can try to wrap 'WARN_ON' inside the 'MHI_TRE_GET_EV_CHID' definition and the just use: /* * Only process the event ring elements whose channel * ID is within the maximum supported range. */ if (chan < mhi_cntrl->max_chan) { mhi_chan = _cntrl->mhi_chan[chan]; parse_xfer_event(mhi_cntrl, local_rp, mhi_chan); event_quota--; } break; This looks more clean. > parse_xfer_event(mhi_cntrl, local_rp, mhi_chan); > event_quota--; > break; > @@ -784,6 +787,7 @@ int mhi_process_ctrl_ev_ring(struct mhi_controller > *mhi_cntrl, > break; > } > > +next_event: > mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); > local_rp = ev_ring->rp; > dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); So you want the count to get increased for skipped element also? Thanks, Mani > @@ -820,6 +824,9 @@ int mhi_process_data_event_ring(struct mhi_controller > *mhi_cntrl, > enum mhi_pkt_type type = MHI_TRE_GET_EV_TYPE(local_rp); > > chan = MHI_TRE_GET_EV_CHID(local_rp); > + if (WARN_ON(chan >= mhi_cntrl->max_chan)) > + goto next_event; > + > mhi_chan = _cntrl->mhi_chan[chan]; > > if (likely(type == MHI_PKT_TYPE_TX_EVENT)) { > @@ -830,6 +837,7 @@ int mhi_process_data_event_ring(struct mhi_controller > *mhi_cntrl, > event_quota--; > } > > +next_event: > mhi_recycle_ev_ring_element(mhi_cntrl, ev_ring); > local_rp = ev_ring->rp; > dev_rp = mhi_to_virtual(ev_ring, er_ctxt->rp); > -- > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project >
Re: [RFC PATCH 0/7] Share events between metrics
On Thu, May 7, 2020 at 2:47 PM Andi Kleen wrote: > > > > - without this change events within a metric may get scheduled > > > together, after they may appear as part of a larger group and be > > > multiplexed at different times, lowering accuracy - however, less > > > multiplexing may compensate for this. > > > > I agree the heuristic in this patch set is naive and would welcome to > > improve it from your toplev experience. I think this change is > > progress on TopDownL1 - would you agree? > > TopdownL1 in non SMT mode should always fit. Inside a group > deduping always makes sense. > > The problem is SMT mode where it doesn't fit. toplev tries > to group each node and each level together. Thanks Andi, I've provided some examples of TopDownL3_SMT in the cover letter of the v3 patch set: https://lore.kernel.org/lkml/20200508053629.210324-1-irog...@google.com/ I tested sandybridge and cascadelake and the results look similar to the non-SMT version. Let me know if there's a different variant to test. > > > > I'm wondering if what is needed are flags to control behavior. For > > example, avoiding the use of groups altogether. For TopDownL1 I see. > > Yes the current situation isn't great. > > For Topdown your patch clearly is an improvement, I'm not sure > it's for everything though. > > Probably the advanced heuristics are only useful for a few > formulas, most are very simple. So maybe it's ok. I guess > would need some testing over the existing formulas. Agreed, do you have a pointer on a metric group where things would obviously be worse? I started off with a cache miss and hit rate metric and similar to topdown this approach is a benefit. In v3 I've added a --metric-no-merge option to retain existing grouping behavior, I've also added a --metric-no-group that avoids groups for all metrics. This may be useful if the NMI watchdog can't be disabled. Thanks for the input! Ian > -Andi
Re: [PATCH v3] scripts: headers_install: Exit with error on config leak
On Wed, May 6, 2020 at 10:53 AM Siddharth Gupta wrote: > > Misuse of CONFIG_* in UAPI headers should result in an error. These config > options can be set in userspace by the user application which includes > these headers to control the APIs and structures being used in a kernel > which supports multiple targets. > > Signed-off-by: Siddharth Gupta Applied to linux-kbuild. Thanks. > --- > scripts/headers_install.sh | 11 ++- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh > index a07668a..94a8335 100755 > --- a/scripts/headers_install.sh > +++ b/scripts/headers_install.sh > @@ -64,7 +64,7 @@ configs=$(sed -e ' > d > ' $OUTFILE) > > -# The entries in the following list are not warned. > +# The entries in the following list do not result in an error. > # Please do not add a new entry. This list is only for existing ones. > # The list will be reduced gradually, and deleted eventually. (hopefully) > # > @@ -98,18 +98,19 @@ include/uapi/linux/raw.h:CONFIG_MAX_RAW_DEVS > > for c in $configs > do > - warn=1 > + leak_error=1 > > for ignore in $config_leak_ignores > do > if echo "$INFILE:$c" | grep -q "$ignore$"; then > - warn= > + leak_error= > break > fi > done > > - if [ "$warn" = 1 ]; then > - echo "warning: $INFILE: leak $c to user-space" >&2 > + if [ "$leak_error" = 1 ]; then > + echo "error: $INFILE: leak $c to user-space" >&2 > + exit 1 > fi > done > > -- > Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, > a Linux Foundation Collaborative Project -- Best Regards Masahiro Yamada
Re: [PATCH] modpost: Replace zero-length array with flexible-array
On Fri, May 8, 2020 at 3:51 AM Gustavo A. R. Silva wrote: > > The current codebase makes use of the zero-length array language > extension to the C90 standard, but the preferred mechanism to declare > variable-length types such as these ones is a flexible array member[1][2], > introduced in C99: > > struct foo { > int stuff; > struct boo array[]; > }; > > By making use of the mechanism above, we will get a compiler warning > in case the flexible array does not occur last in the structure, which > will help us prevent some kind of undefined behavior bugs from being > inadvertently introduced[3] to the codebase from now on. > > Also, notice that, dynamic memory allocations won't be affected by > this change: > > "Flexible array members have incomplete type, and so the sizeof operator > may not be applied. As a quirk of the original implementation of > zero-length arrays, sizeof evaluates to zero."[1] > > sizeof(flexible-array-member) triggers a warning because flexible array > members have incomplete type[1]. There are some instances of code in > which the sizeof operator is being incorrectly/erroneously applied to > zero-length arrays and the result is zero. Such instances may be hiding > some bugs. So, this work (flexible-array member conversions) will also > help to get completely rid of those sorts of issues. > > This issue was found with the help of Coccinelle. > > [1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html > [2] https://github.com/KSPP/linux/issues/21 > [3] commit 76497732932f ("cxgb3/l2t: Fix undefined behaviour") > > Signed-off-by: Gustavo A. R. Silva Applied to linux-kbuild. Thanks. -- Best Regards Masahiro Yamada
[RFC PATCH v3 04/14] libbpf: Fix memory leak and possible double-free in hashmap__clear
From: Andrii Nakryiko Fix memory leak in hashmap_clear() not freeing hashmap_entry structs for each of the remaining entries. Also NULL-out bucket list to prevent possible double-free between hashmap__clear() and hashmap__free(). Running test_progs-asan flavor clearly showed this problem. Reported-by: Alston Tang Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20200429012111.277390-5-andr...@fb.com Signed-off-by: Ian Rogers --- tools/lib/bpf/hashmap.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/tools/lib/bpf/hashmap.c b/tools/lib/bpf/hashmap.c index 54c30c802070..cffb96202e0d 100644 --- a/tools/lib/bpf/hashmap.c +++ b/tools/lib/bpf/hashmap.c @@ -59,7 +59,14 @@ struct hashmap *hashmap__new(hashmap_hash_fn hash_fn, void hashmap__clear(struct hashmap *map) { + struct hashmap_entry *cur, *tmp; + int bkt; + + hashmap__for_each_entry_safe(map, cur, tmp, bkt) { + free(cur); + } free(map->buckets); + map->buckets = NULL; map->cap = map->cap_bits = map->sz = 0; } -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 10/14] perf metricgroup: always place duration_time last
If a metric contains the duration_time event then the event is placed outside of the metric's group of events. Rather than split the group, make it so the duration_time is immediately after the group. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 7e1725d61c39..2c684fd3c4e3 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -422,8 +422,8 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events, struct expr_parse_ctx *ctx) { struct hashmap_entry *cur; - size_t bkt, i = 0; - bool no_group = false; + size_t bkt; + bool no_group = true, has_duration = false; hashmap__for_each_entry((>ids), cur, bkt) { pr_debug("found event %s\n", (const char *)cur->key); @@ -433,20 +433,20 @@ static void metricgroup__add_metric_weak_group(struct strbuf *events, * group. */ if (!strcmp(cur->key, "duration_time")) { - if (i > 0) - strbuf_addf(events, "}:W,"); - strbuf_addf(events, "duration_time"); - no_group = true; + has_duration = true; continue; } strbuf_addf(events, "%s%s", - i == 0 || no_group ? "{" : ",", + no_group ? "{" : ",", (const char *)cur->key); no_group = false; - i++; } - if (!no_group) + if (!no_group) { strbuf_addf(events, "}:W"); + if (has_duration) + strbuf_addf(events, ",duration_time"); + } else if (has_duration) + strbuf_addf(events, "duration_time"); } static void metricgroup__add_metric_non_group(struct strbuf *events, -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 08/14] perf metricgroup: change evlist_used to a bitmap
Use a bitmap rather than an array of bools. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 18 -- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 37be5a368d6e..4f7e36bc49d9 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -95,7 +95,7 @@ struct egroup { static struct evsel *find_evsel_group(struct evlist *perf_evlist, struct expr_parse_ctx *pctx, struct evsel **metric_events, - bool *evlist_used) + unsigned long *evlist_used) { struct evsel *ev; bool leader_found; @@ -105,7 +105,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, double *val_ptr; evlist__for_each_entry (perf_evlist, ev) { - if (evlist_used[j++]) + if (test_bit(j++, evlist_used)) continue; if (hashmap__find(>ids, ev->name, (void **)_ptr)) { if (!metric_events[i]) @@ -150,7 +150,7 @@ static struct evsel *find_evsel_group(struct evlist *perf_evlist, j++; } ev = metric_events[i]; - evlist_used[ev->idx] = true; + set_bit(ev->idx, evlist_used); } return metric_events[0]; @@ -166,13 +166,11 @@ static int metricgroup__setup_events(struct list_head *groups, int ret = 0; struct egroup *eg; struct evsel *evsel; - bool *evlist_used; + unsigned long *evlist_used; - evlist_used = calloc(perf_evlist->core.nr_entries, sizeof(bool)); - if (!evlist_used) { - ret = -ENOMEM; - return ret; - } + evlist_used = bitmap_alloc(perf_evlist->core.nr_entries); + if (!evlist_used) + return -ENOMEM; list_for_each_entry (eg, groups, nd) { struct evsel **metric_events; @@ -210,7 +208,7 @@ static int metricgroup__setup_events(struct list_head *groups, list_add(>nd, >head); } - free(evlist_used); + bitmap_free(evlist_used); return ret; } -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 05/14] perf expr: fix memory leaks in bison
Add a destructor for strings to reclaim memory in the event of errors. Free the ID given for a lookup. Signed-off-by: Ian Rogers --- tools/perf/util/expr.y | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/expr.y b/tools/perf/util/expr.y index 21e82a1e11a2..3b49b230b111 100644 --- a/tools/perf/util/expr.y +++ b/tools/perf/util/expr.y @@ -27,6 +27,7 @@ %token EXPR_PARSE EXPR_OTHER EXPR_ERROR %token NUMBER %token ID +%destructor { free ($$); } %token MIN MAX IF ELSE SMT_ON %left MIN MAX IF %left '|' @@ -94,8 +95,10 @@ if_expr: expr:NUMBER | ID{ if (lookup_id(ctx, $1, &$$) < 0) { pr_debug("%s not found\n", $1); + free($1); YYABORT; } + free($1); } | expr '|' expr { $$ = (long)$1 | (long)$3; } | expr '&' expr { $$ = (long)$1 & (long)$3; } -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 06/14] perf evsel: fix 2 memory leaks
If allocated, perf_pkg_mask and metric_events need freeing. Signed-off-by: Ian Rogers --- tools/perf/util/evsel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 28683b0eb738..05bb46baad6a 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -1263,6 +1263,8 @@ void evsel__exit(struct evsel *evsel) zfree(>group_name); zfree(>name); zfree(>pmu_name); + zfree(>per_pkg_mask); + zfree(>metric_events); perf_evsel__object.fini(evsel); } -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 13/14] perf metricgroup: remove duped metric group events
A metric group contains multiple metrics. These metrics may use the same events. If metrics use separate events then it leads to more multiplexing and overall metric counts fail to sum to 100%. Modify how metrics are associated with events so that if the events in an earlier group satisfy the current metric, the same events are used. A record of used events is kept and at the end of processing unnecessary events are eliminated. Before: $ perf stat -a -M TopDownL1 sleep 1 Performance counter stats for 'system wide': 920,211,343 uops_issued.any # 0.5 Backend_Bound (16.56%) 1,977,733,128 idq_uops_not_delivered.core (16.56%) 51,668,510 int_misc.recovery_cycles (16.56%) 732,305,692 uops_retired.retire_slots (16.56%) 1,497,621,849 cycles (16.56%) 721,098,274 uops_issued.any # 0.1 Bad_Speculation (16.79%) 1,332,681,791 cycles (16.79%) 552,475,482 uops_retired.retire_slots (16.79%) 47,708,340 int_misc.recovery_cycles (16.79%) 1,383,713,292 cycles # 0.4 Frontend_Bound (16.76%) 2,013,757,701 idq_uops_not_delivered.core (16.76%) 1,373,363,790 cycles # 0.1 Retiring (33.54%) 577,302,589 uops_retired.retire_slots (33.54%) 392,766,987 inst_retired.any # 0.3 IPC (50.24%) 1,351,873,350 cpu_clk_unhalted.thread (50.24%) 1,332,510,318 cycles # 5330041272.0 SLOTS (49.90%) 1.006336145 seconds time elapsed After: $ perf stat -a -M TopDownL1 sleep 1 Performance counter stats for 'system wide': 765,949,145 uops_issued.any # 0.1 Bad_Speculation # 0.5 Backend_Bound (50.09%) 1,883,830,591 idq_uops_not_delivered.core # 0.3 Frontend_Bound (50.09%) 48,237,080 int_misc.recovery_cycles (50.09%) 581,798,385 uops_retired.retire_slots # 0.1 Retiring (50.09%) 1,361,628,527 cycles # 5446514108.0 SLOTS (50.09%) 391,415,714 inst_retired.any # 0.3 IPC (49.91%) 1,336,486,781 cpu_clk_unhalted.thread (49.91%) 1.005469298 seconds time elapsed Note: Bad_Speculation + Backend_Bound + Frontend_Bound + Retiring = 100% after, where as before it is 110%. After there are 2 groups, whereas before there are 6. After the cycles event appears once, before it appeared 5 times. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 96 ++- 1 file changed, 60 insertions(+), 36 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 69fbff47089f..c97dc87c2a31 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -93,45 +93,72 @@ struct egroup { bool has_constraint; }; +/** + * Find a group of events in perf_evlist that correpond to those from a parsed + * metric expression. + * @perf_evlist: a list of events something like: {metric1 leader, metric1 + * sibling, metric1 sibling}:W,duration_time,{metric2 leader, metric2 sibling, + * metric2 sibling}:W,duration_time + * @pctx: the parse context for the metric expression. + * @has_constraint: is there a contraint on the group of events? In which case + * the events won't be grouped. + * @metric_events: out argument, null terminated array of evsel's associated + * with the metric. + * @evlist_used: in/out argument, bitmap tracking which evlist events are used. + * @return the first metric event or NULL on failure. + */ static struct evsel *find_evsel_group(struct evlist *perf_evlist, struct expr_parse_ctx *pctx, + bool has_constraint, struct evsel **metric_events, unsigned long *evlist_used) { - struct evsel *ev; - bool leader_found; - const size_t idnum = hashmap__size(>ids); - size_t i = 0; - int j = 0; + struct evsel *ev, *current_leader = NULL;
[RFC PATCH v3 09/14] perf metricgroup: free metric_events on error
Avoid a simple memory leak. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 4f7e36bc49d9..7e1725d61c39 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -186,6 +186,7 @@ static int metricgroup__setup_events(struct list_head *groups, if (!evsel) { pr_debug("Cannot resolve %s: %s\n", eg->metric_name, eg->metric_expr); + free(metric_events); continue; } for (i = 0; metric_events[i]; i++) @@ -193,11 +194,13 @@ static int metricgroup__setup_events(struct list_head *groups, me = metricgroup__lookup(metric_events_list, evsel, true); if (!me) { ret = -ENOMEM; + free(metric_events); break; } expr = malloc(sizeof(struct metric_expr)); if (!expr) { ret = -ENOMEM; + free(metric_events); break; } expr->metric_expr = eg->metric_expr; -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 07/14] perf expr: migrate expr ids table to libbpf's hashmap
Use a hashmap between a char* string and a double* value. While bpf's hashmap entries are size_t in size, we can't guarantee sizeof(size_t) >= sizeof(double). Avoid a memory allocation when gathering ids by making 0.0 a special value encoded as NULL. Suggested by Andi Kleen: https://lore.kernel.org/lkml/20200224210308.gq160...@tassilo.jf.intel.com/ and seconded by Jiri Olsa: https://lore.kernel.org/lkml/20200423112915.GH1136647@krava/ Signed-off-by: Ian Rogers --- tools/perf/tests/expr.c | 40 ++- tools/perf/tests/pmu-events.c | 25 +++ tools/perf/util/expr.c| 129 +++--- tools/perf/util/expr.h| 22 +++--- tools/perf/util/expr.y| 22 +- tools/perf/util/metricgroup.c | 87 +++ tools/perf/util/stat-shadow.c | 49 - 7 files changed, 193 insertions(+), 181 deletions(-) diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index 3f742612776a..5e606fd5a2c6 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -19,11 +19,9 @@ static int test(struct expr_parse_ctx *ctx, const char *e, double val2) int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) { const char *p; - const char **other; - double val; - int i, ret; + double val, *val_ptr; + int ret; struct expr_parse_ctx ctx; - int num_other; expr__ctx_init(); expr__add_id(, "FOO", 1); @@ -52,25 +50,29 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) ret = expr__parse(, , p, 1); TEST_ASSERT_VAL("missing operand", ret == -1); + hashmap__clear(); TEST_ASSERT_VAL("find other", - expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", , _other, 1) == 0); - TEST_ASSERT_VAL("find other", num_other == 3); - TEST_ASSERT_VAL("find other", !strcmp(other[0], "BAR")); - TEST_ASSERT_VAL("find other", !strcmp(other[1], "BAZ")); - TEST_ASSERT_VAL("find other", !strcmp(other[2], "BOZO")); - TEST_ASSERT_VAL("find other", other[3] == NULL); + expr__find_other("FOO + BAR + BAZ + BOZO", "FOO", +, 1) == 0); + TEST_ASSERT_VAL("find other", hashmap__size() == 3); + TEST_ASSERT_VAL("find other", hashmap__find(, "BAR", + (void **)_ptr)); + TEST_ASSERT_VAL("find other", hashmap__find(, "BAZ", + (void **)_ptr)); + TEST_ASSERT_VAL("find other", hashmap__find(, "BOZO", + (void **)_ptr)); + hashmap__clear(); TEST_ASSERT_VAL("find other", - expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", NULL, - , _other, 3) == 0); - TEST_ASSERT_VAL("find other", num_other == 2); - TEST_ASSERT_VAL("find other", !strcmp(other[0], "EVENT1,param=3/")); - TEST_ASSERT_VAL("find other", !strcmp(other[1], "EVENT2,param=3/")); - TEST_ASSERT_VAL("find other", other[2] == NULL); + expr__find_other("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@", +NULL, , 3) == 0); + TEST_ASSERT_VAL("find other", hashmap__size() == 2); + TEST_ASSERT_VAL("find other", hashmap__find(, "EVENT1,param=3/", + (void **)_ptr)); + TEST_ASSERT_VAL("find other", hashmap__find(, "EVENT2,param=3/", + (void **)_ptr)); - for (i = 0; i < num_other; i++) - zfree([i]); - free((void *)other); + expr__ctx_clear(); return 0; } diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index c18b9ce8cace..054550ee811c 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -428,8 +428,6 @@ static int test_parsing(void) struct pmu_events_map *map; struct pmu_event *pe; int i, j, k; - const char **ids; - int idnum; int ret = 0; struct expr_parse_ctx ctx; double result; @@ -443,13 +441,17 @@ static int test_parsing(void) } j = 0; for (;;) { + struct hashmap_entry *cur; + size_t bkt; + pe = >table[j++]; if (!pe->name && !pe->metric_group && !pe->metric_name) break; if (!pe->metric_expr) continue; - if (expr__find_other(pe->metric_expr, NULL, - , , 0) < 0) { + expr__ctx_init(); + if (expr__find_other(pe->metric_expr, NULL, , 0) +
[RFC PATCH v3 14/14] perf metricgroup: add options to not group or merge
Add --metric-no-group that causes all events within metrics to not be grouped. This can allow the event to get more time when multiplexed, but may also lower accuracy. Add --metric-no-merge option. By default events in different metrics may be shared if the group of events for one metric is the same or larger than that of the second. Sharing may increase or lower accuracy and so is now configurable. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-stat.txt | 19 ++ tools/perf/builtin-stat.c | 11 +- tools/perf/util/metricgroup.c | 51 ++ tools/perf/util/metricgroup.h | 6 ++- tools/perf/util/stat.h | 2 + 5 files changed, 71 insertions(+), 18 deletions(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 3fb5028aef08..cc1e4c62bc91 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -234,6 +234,25 @@ filter out the startup phase of the program, which is often very different. Print statistics of transactional execution if supported. +--metric-no-group:: +By default, events to compute a metric are placed in weak groups. The +group tries to enforce scheduling all or none of the events. The +--metric-no-group option places events outside of groups and may +increase the chance of the event being scheduled - leading to more +accuracy. However, as events may not be scheduled together accuracy +for metrics like instructions per cycle can be lower - as both metrics +may no longer be being measured at the same time. + +--metric-no-merge:: +By default metric events in different weak groups can be shared if one +group contains all the events needed by another. In such cases one +group will be eliminated reducing event multiplexing and making it so +that certain groups of metrics sum to 100%. A downside to sharing a +group is that the group may require multiplexing and so accuracy for a +small group that need not have multiplexing is lowered. This option +forbids the event merging logic from sharing events between groups and +may be used to increase accuracy in this case. + STAT RECORD --- Stores stat data into perf data file. diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index e0c1ad23c768..5d444b1d82fb 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -840,7 +840,10 @@ static int parse_metric_groups(const struct option *opt, const char *str, int unset __maybe_unused) { - return metricgroup__parse_groups(opt, str, _config.metric_events); + return metricgroup__parse_groups(opt, str, +stat_config.metric_no_group, +stat_config.metric_no_merge, +_config.metric_events); } static struct option stat_options[] = { @@ -918,6 +921,10 @@ static struct option stat_options[] = { "ms to wait before starting measurement after program start"), OPT_CALLBACK_NOOPT(0, "metric-only", _config.metric_only, NULL, "Only print computed metrics. No raw values", enable_metric_only), + OPT_BOOLEAN(0, "metric-no-group", _config.metric_no_group, + "don't group metric events, impacts multiplexing"), + OPT_BOOLEAN(0, "metric-no-merge", _config.metric_no_merge, + "don't try to share events between metrics in a group"), OPT_BOOLEAN(0, "topdown", _run, "measure topdown level 1 statistics"), OPT_BOOLEAN(0, "smi-cost", _cost, @@ -1442,6 +1449,8 @@ static int add_default_attributes(void) struct option opt = { .value = _list }; return metricgroup__parse_groups(, "transaction", + stat_config.metric_no_group, + stat_config.metric_no_merge, _config.metric_events); } diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index c97dc87c2a31..9dcaac4fdebd 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -95,11 +95,15 @@ struct egroup { /** * Find a group of events in perf_evlist that correpond to those from a parsed - * metric expression. + * metric expression. Note, as find_evsel_group is called in the same order as + * perf_evlist was constructed, metric_no_merge doesn't need to test for + * underfilling a group. * @perf_evlist: a list of events something like: {metric1 leader, metric1 * sibling, metric1 sibling}:W,duration_time,{metric2 leader, metric2 sibling, * metric2 sibling}:W,duration_time * @pctx: the parse context for the metric expression. + *
[RFC PATCH v3 01/14] perf parse-events: expand add PMU error/verbose messages
On a CPU like skylakex an uncore_iio_0 PMU may alias with uncore_iio_free_running_0. The latter PMU doesn't support fc_mask as a parameter and so pmu_config_term fails. Typically parse_events_add_pmu is called in a loop where if one alias succeeds errors are ignored, however, if multiple errors occur parse_events__handle_error will currently give a WARN_ONCE. This change removes the WARN_ONCE in parse_events__handle_error and makes it a pr_debug. It adds verbose messages to parse_events_add_pmu warning that non-fatal errors may occur, while giving details on the pmu and config terms for useful context. pmu_config_term is altered so the failing term and pmu are present in the case of the 'unknown term' error which makes spotting the free_running case more straightforward. Before: $ perf --debug verbose=3 stat -M llc_misses.pcie_read sleep 1 Using CPUID GenuineIntel-6-55-4 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cpu.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_req_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cpu.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_req_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 adding {unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.mem_read.part3}:W,{unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.mem_read.part3}:W intel_pt default config: tsc,mtc,mtc_period=3,psb_period=3,pt,branch WARNING: multiple event parsing errors ... Invalid event/parameter 'fc_mask' ... After: $ perf --debug verbose=3 stat -M llc_misses.pcie_read sleep 1 Using CPUID GenuineIntel-6-55-4 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cpu.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_req_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 metric expr unc_iio_data_req_of_cpu.mem_read.part0 + unc_iio_data_req_of_cpu.mem_read.part1 + unc_iio_data_req_of_cpu.mem_read.part2 + unc_iio_data_req_of_cpu.mem_read.part3 for LLC_MISSES.PCIE_READ found event unc_iio_data_req_of_cpu.mem_read.part0 found event unc_iio_data_req_of_cpu.mem_read.part1 found event unc_iio_data_req_of_cpu.mem_read.part2 found event unc_iio_data_req_of_cpu.mem_read.part3 adding {unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.mem_read.part3}:W,{unc_iio_data_req_of_cpu.mem_read.part0,unc_iio_data_req_of_cpu.mem_read.part1,unc_iio_data_req_of_cpu.mem_read.part2,unc_iio_data_req_of_cpu.mem_read.part3}:W intel_pt default config: tsc,mtc,mtc_period=3,psb_period=3,pt,branch Attempting to add event pmu 'uncore_iio_free_running_5' with 'unc_iio_data_req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_5' with 'fc_mask,ch_mask,umask,event,' that may result in non-fatal errors Attempting to add event pmu 'uncore_iio_free_running_3' with 'unc_iio_data_req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_3' with 'fc_mask,ch_mask,umask,event,' that may result in non-fatal errors Attempting to add event pmu 'uncore_iio_free_running_1' with 'unc_iio_data_req_of_cpu.mem_read.part0,' that may result in non-fatal errors After aliases, add event pmu 'uncore_iio_free_running_1' with 'fc_mask,ch_mask,umask,event,' that may result in non-fatal errors Multiple errors dropping message: unknown term 'fc_mask' for pmu 'uncore_iio_free_running_3' (valid terms: event,umask,config,config1,config2,name,period,percore) ... Signed-off-by: Ian Rogers --- tools/perf/arch/x86/util/intel-pt.c | 32 +--- tools/perf/tests/pmu.c | 4 ++-- tools/perf/util/parse-events.c | 29 - tools/perf/util/pmu.c | 33 ++--- tools/perf/util/pmu.h | 2 +- 5 files changed, 72 insertions(+), 28 deletions(-) diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index fd9e22d1e366..0fe401ad3347 100644 ---
[RFC PATCH v3 12/14] perf metricgroup: order event groups by size
When adding event groups to the group list, insert them in size order. This performs an insertion sort on the group list. By placing the largest groups at the front of the group list it is possible to see if a larger group contains the same events as a later group. This can make the later group redundant - it can reuse the events from the large group. A later patch will add this sharing. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 16 +++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 2a6456fa178b..69fbff47089f 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -520,7 +520,21 @@ static int __metricgroup__add_metric(struct list_head *group_list, return -EINVAL; } - list_add_tail(>nd, group_list); + if (list_empty(group_list)) + list_add(>nd, group_list); + else { + struct list_head *pos; + + /* Place the largest groups at the front. */ + list_for_each_prev(pos, group_list) { + struct egroup *old = list_entry(pos, struct egroup, nd); + + if (hashmap__size(>pctx.ids) <= + hashmap__size(>pctx.ids)) + break; + } + list_add(>nd, pos); + } return 0; } -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 00/14] Share events between metrics
Metric groups contain metrics. Metrics create groups of events to ideally be scheduled together. Often metrics refer to the same events, for example, a cache hit and cache miss rate. Using separate event groups means these metrics are multiplexed at different times and the counts don't sum to 100%. More multiplexing also decreases the accuracy of the measurement. This change orders metrics from groups or the command line, so that the ones with the most events are set up first. Later metrics see if groups already provide their events, and reuse them if possible. Unnecessary events and groups are eliminated. The option --metric-no-group is added so that metrics aren't placed in groups. This affects multiplexing and may increase sharing. The option --metric-mo-merge is added and with this option the existing grouping behavior is preserved. RFC because: - without this change events within a metric may get scheduled together, after they may appear as part of a larger group and be multiplexed at different times, lowering accuracy - however, less multiplexing may compensate for this. - libbpf's hashmap is used, however, libbpf is an optional requirement for building perf. - other things I'm not thinking of. Thanks! Example on Sandybridge: $ perf stat -a --metric-no-merge -M TopDownL1_SMT sleep 1 Performance counter stats for 'system wide': 14931177 cpu_clk_unhalted.one_thread_active # 0.47 Backend_Bound_SMT(12.45%) 32314653 int_misc.recovery_cycles_any (16.23%) 555020905 uops_issued.any (18.85%) 1038651176 idq_uops_not_delivered.core (24.95%) 43003170 cpu_clk_unhalted.ref_xclk (25.20%) 1154926272 cpu_clk_unhalted.thread (31.50%) 656873544 uops_retired.retire_slots (31.11%) 16491988 cpu_clk_unhalted.one_thread_active # 0.06 Bad_Speculation_SMT (31.10%) 32064061 int_misc.recovery_cycles_any (31.04%) 648394934 uops_issued.any (31.14%) 42107506 cpu_clk_unhalted.ref_xclk (24.94%) 1124565282 cpu_clk_unhalted.thread (31.14%) 523430886 uops_retired.retire_slots (31.05%) 12328380 cpu_clk_unhalted.one_thread_active # 0.35 Frontend_Bound_SMT (10.08%) 42651836 cpu_clk_unhalted.ref_xclk (10.08%) 1006287722 idq_uops_not_delivered.core (10.08%) 1130593027 cpu_clk_unhalted.thread (10.08%) 14209258 cpu_clk_unhalted.one_thread_active # 0.18 Retiring_SMT (6.39%) 41904474 cpu_clk_unhalted.ref_xclk (6.39%) 522251584 uops_retired.retire_slots (6.39%) 257754 cpu_clk_unhalted.thread (6.39%) 12930094 cpu_clk_unhalted.one_thread_active # 2865823806.05 SLOTS_SMT (11.06%) 40975376 cpu_clk_unhalted.ref_xclk (11.06%) 1089204936 cpu_clk_unhalted.thread (11.06%) 1.002165509 seconds time elapsed $ perf stat -a -M TopDownL1_SMT sleep 1 Performance counter stats for 'system wide': 11893411 cpu_clk_unhalted.one_thread_active # 2715516883.49 SLOTS_SMT # 0.19 Retiring_SMT # 0.33 Frontend_Bound_SMT # 0.04 Bad_Speculation_SMT # 0.44 Backend_Bound_SMT (71.46%) 28458253 int_misc.recovery_cycles_any (71.44%) 562710994 uops_issued.any (71.42%) 907105260 idq_uops_not_delivered.core (57.12%) 39797715 cpu_clk_unhalted.ref_xclk (57.12%) 1045357060 cpu_clk_unhalted.thread (71.41%) 504809283 uops_retired.retire_slots (71.44%) 1.001939294 seconds time elapsed Note that without merging the metrics sum to 1.06, but with
[RFC PATCH v3 02/14] perf test: improve pmu event metric testing
Add a basic floating point number test to expr. Break pmu-events test into 2 and add a test to verify that all pmu metric expressions simply parse. Try to parse all metric ids/events, failing if metrics for the current architecture fail to parse. Tested on skylakex with the patch set in place. May fail on other architectures if metrics are invalid. Signed-off-by: Ian Rogers --- tools/perf/tests/builtin-test.c | 5 + tools/perf/tests/expr.c | 1 + tools/perf/tests/pmu-events.c | 158 ++-- tools/perf/tests/tests.h| 2 + 4 files changed, 160 insertions(+), 6 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 3471ec52ea11..8147c17c71ab 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -75,6 +75,11 @@ static struct test generic_tests[] = { { .desc = "PMU events", .func = test__pmu_events, + .subtest = { + .get_nr = test__pmu_events_subtest_get_nr, + .get_desc = test__pmu_events_subtest_get_desc, + }, + }, { .desc = "DSO data read", diff --git a/tools/perf/tests/expr.c b/tools/perf/tests/expr.c index f9e8e5628836..3f742612776a 100644 --- a/tools/perf/tests/expr.c +++ b/tools/perf/tests/expr.c @@ -39,6 +39,7 @@ int test__expr(struct test *t __maybe_unused, int subtest __maybe_unused) ret |= test(, "min(1,2) + 1", 2); ret |= test(, "max(1,2) + 1", 3); ret |= test(, "1+1 if 3*4 else 0", 2); + ret |= test(, "1.1 + 2.1", 3.2); if (ret) return ret; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index d64261da8bf7..c18b9ce8cace 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -8,6 +8,10 @@ #include #include "debug.h" #include "../pmu-events/pmu-events.h" +#include "util/evlist.h" +#include "util/expr.h" +#include "util/parse-events.h" +#include struct perf_pmu_test_event { struct pmu_event event; @@ -144,7 +148,7 @@ static struct pmu_events_map *__test_pmu_get_events_map(void) } /* Verify generated events from pmu-events.c is as expected */ -static int __test_pmu_event_table(void) +static int test_pmu_event_table(void) { struct pmu_events_map *map = __test_pmu_get_events_map(); struct pmu_event *table; @@ -347,14 +351,11 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) return res; } -int test__pmu_events(struct test *test __maybe_unused, -int subtest __maybe_unused) + +static int test_aliases(void) { struct perf_pmu *pmu = NULL; - if (__test_pmu_event_table()) - return -1; - while ((pmu = perf_pmu__scan(pmu)) != NULL) { int count = 0; @@ -377,3 +378,148 @@ int test__pmu_events(struct test *test __maybe_unused, return 0; } + +static bool is_number(const char *str) +{ + size_t i; + + for (i = 0; i < strlen(str); i++) { + if (!isdigit(str[i]) && str[i] != '.') + return false; + } + return true; +} + +static int check_parse_id(const char *id, bool same_cpu, struct pmu_event *pe) +{ + struct parse_events_error error; + struct evlist *evlist; + int ret; + + /* Numbers are always valid. */ + if (is_number(id)) + return 0; + + evlist = evlist__new(); + memset(, 0, sizeof(error)); + ret = parse_events(evlist, id, ); + if (ret && same_cpu) { + fprintf(stderr, + "\nWARNING: Parse event failed metric '%s' id '%s' expr '%s'\n", + pe->metric_name, id, pe->metric_expr); + fprintf(stderr, "Error string '%s' help '%s'\n", + error.str, error.help); + } else if (ret) { + pr_debug3("Parse event failed, but for an event that may not be supported by this CPU.\nid '%s' metric '%s' expr '%s'\n", + id, pe->metric_name, pe->metric_expr); + } + evlist__delete(evlist); + free(error.str); + free(error.help); + free(error.first_str); + free(error.first_help); + /* TODO: too many metrics are broken to fail on this test currently. */ + return 0; +} + +static int test_parsing(void) +{ + struct pmu_events_map *cpus_map = perf_pmu__find_map(NULL); + struct pmu_events_map *map; + struct pmu_event *pe; + int i, j, k; + const char **ids; + int idnum; + int ret = 0; + struct expr_parse_ctx ctx; + double result; + + i = 0; + for (;;) { + map = _events_map[i++]; + if (!map->table) { + map = NULL; + break; + } + j = 0; +
[RFC PATCH v3 03/14] lib/bpf hashmap: increase portability
Don't include libbpf_internal.h as it is unused and has conflicting definitions, for example, with tools/perf/util/debug.h. Fix a non-glibc include path. Signed-off-by: Ian Rogers --- tools/lib/bpf/hashmap.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/lib/bpf/hashmap.h b/tools/lib/bpf/hashmap.h index bae8879cdf58..d5ef212a55ba 100644 --- a/tools/lib/bpf/hashmap.h +++ b/tools/lib/bpf/hashmap.h @@ -13,9 +13,8 @@ #ifdef __GLIBC__ #include #else -#include +#include #endif -#include "libbpf_internal.h" static inline size_t hash_bits(size_t h, int bits) { -- 2.26.2.645.ge9eca65c58-goog
[RFC PATCH v3 11/14] perf metricgroup: delay events string creation
Currently event groups are placed into groups_list at the same time as the events string containing the events is built. Separate these two operations and build the groups_list first, then the event string from the groups_list. This adds an ability to reorder the groups_list that will be used in a later patch. Signed-off-by: Ian Rogers --- tools/perf/util/metricgroup.c | 38 +++ 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 2c684fd3c4e3..2a6456fa178b 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -90,6 +90,7 @@ struct egroup { const char *metric_expr; const char *metric_unit; int runtime; + bool has_constraint; }; static struct evsel *find_evsel_group(struct evlist *perf_evlist, @@ -497,8 +498,8 @@ int __weak arch_get_runtimeparam(void) return 1; } -static int __metricgroup__add_metric(struct strbuf *events, - struct list_head *group_list, struct pmu_event *pe, int runtime) +static int __metricgroup__add_metric(struct list_head *group_list, +struct pmu_event *pe, int runtime) { struct egroup *eg; @@ -511,6 +512,7 @@ static int __metricgroup__add_metric(struct strbuf *events, eg->metric_expr = pe->metric_expr; eg->metric_unit = pe->unit; eg->runtime = runtime; + eg->has_constraint = metricgroup__has_constraint(pe); if (expr__find_other(pe->metric_expr, NULL, >pctx, runtime) < 0) { expr__ctx_clear(>pctx); @@ -518,14 +520,6 @@ static int __metricgroup__add_metric(struct strbuf *events, return -EINVAL; } - if (events->len > 0) - strbuf_addf(events, ","); - - if (metricgroup__has_constraint(pe)) - metricgroup__add_metric_non_group(events, >pctx); - else - metricgroup__add_metric_weak_group(events, >pctx); - list_add_tail(>nd, group_list); return 0; @@ -536,6 +530,7 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events, { struct pmu_events_map *map = perf_pmu__find_map(NULL); struct pmu_event *pe; + struct egroup *eg; int i, ret = -EINVAL; if (!map) @@ -554,7 +549,8 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events, pr_debug("metric expr %s for %s\n", pe->metric_expr, pe->metric_name); if (!strstr(pe->metric_expr, "?")) { - ret = __metricgroup__add_metric(events, group_list, pe, 1); + ret = __metricgroup__add_metric(group_list, + pe, 1); } else { int j, count; @@ -565,13 +561,29 @@ static int metricgroup__add_metric(const char *metric, struct strbuf *events, * those events to group_list. */ - for (j = 0; j < count; j++) - ret = __metricgroup__add_metric(events, group_list, pe, j); + for (j = 0; j < count; j++) { + ret = __metricgroup__add_metric( + group_list, pe, j); + } } if (ret == -ENOMEM) break; } } + if (!ret) { + list_for_each_entry(eg, group_list, nd) { + if (events->len > 0) + strbuf_addf(events, ","); + + if (eg->has_constraint) { + metricgroup__add_metric_non_group(events, + >pctx); + } else { + metricgroup__add_metric_weak_group(events, + >pctx); + } + } + } return ret; } -- 2.26.2.645.ge9eca65c58-goog
Re: [PATCH 04/14] sched: cpufreq: Move sched_cpufreq_governor_change()
On Thu, May 07, 2020 at 07:10:02PM +0100, Quentin Perret wrote: > CPUFreq calls into sched_cpufreq_governor_change() when switching > governors, which triggers a sched domain rebuild when entering or > exiting schedutil. > > Move the function to sched/cpufreq.c to prepare the ground for the > modularization of schedutil. > > Signed-off-by: Quentin Perret > --- > kernel/sched/cpufreq.c | 33 > kernel/sched/cpufreq_schedutil.c | 33 > 2 files changed, 33 insertions(+), 33 deletions(-) > > diff --git a/kernel/sched/cpufreq.c b/kernel/sched/cpufreq.c > index 7c2fe50fd76d..82f2dda61a55 100644 > --- a/kernel/sched/cpufreq.c > +++ b/kernel/sched/cpufreq.c > @@ -75,3 +75,36 @@ bool cpufreq_this_cpu_can_update(struct cpufreq_policy > *policy) > (policy->dvfs_possible_from_any_cpu && > > rcu_dereference_sched(*this_cpu_ptr(_update_util_data))); > } > + > +#ifdef CONFIG_ENERGY_MODEL > +extern bool sched_energy_update; > +extern struct mutex sched_energy_mutex; > + > +static void rebuild_sd_workfn(struct work_struct *work) > +{ > + mutex_lock(_energy_mutex); > + sched_energy_update = true; > + rebuild_sched_domains(); > + sched_energy_update = false; > + mutex_unlock(_energy_mutex); > +} > +static DECLARE_WORK(rebuild_sd_work, rebuild_sd_workfn); > + > +/* > + * EAS shouldn't be attempted without sugov, so rebuild the sched_domains > + * on governor changes to make sure the scheduler knows about it. > + */ In the previous patch, you removed reference to schedutil and replaced it with " an EAS-compatible CPUfreq governor (schedutil)". May be you could do the same here. Thanks, Pavan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH 00/14] Modularize schedutil
On 07-05-20, 19:09, Quentin Perret wrote: > Android is trying very hard to use a single kernel image (commonly > called Generic Kernel Image, or GKI), closely aligned with mainline, to > run on all Android devices regardless of the vendor. > > The GKI project intends to not only improve the status quo for Android > users directly (less fragmentation simplifies updatability), but also > to benefit upstream by forcing all vendors to agree on one common > kernel, that we push hard to be aligned with mainline. > > One challenge to implement GKI is to avoid bloating the kernel by > compiling too many things in, especially given that different devices > need different things. As such, anything that can be turned into a > module helps GKI, by offering an alternative to having that component > built-in. This is true for pretty much anything that can be made > modular, including drivers as well as other kernel components, such as > CPUFreq governors. > > Indeed, in practice, Android devices often ship with only one CPUFreq > governor enabled, and don't require any other that would simply waste > memory for no benefits. All CPUFreq governors can already be built as > modules with one notable exception: schedutil. Though popular in > Android, some devices do not use schedutil, which is why it would be > preferable to not have it unconditionally built in GKI. This series is > an attempt to solve this problem, by making schedutil tristate. > > While modularization is usually not something we want to see near the > scheduler, it appeared to me as I wrote those patches that the > particular case of schedutil was actually not too bad to implement. > We already have to support switching governors at run-time, simply > because userspace is free to do that, so the infrastructure for turning > sugov on and off dynamically is already there. Loading the code a little > later doesn't seem to make that a lot worse. > > Patches 01-05 refactor some code to break the few dependencies on > schedutil being builtin (notably EAS). Patches 06-12 export various > symbols that schedutil needs when compiled as a module. And finally, > patches 13-14 finish off the work by making the Kconfig tristate. IMHO, you have over-broken the patches, like first two could be merged together and all exports could have been done in a single patch, etc. i.e. all related or similar changes together... Acked-by: Viresh Kumar -- viresh
Re: [PATCH] HID: multitouch: Remove MT_CLS_WIN_8_DUAL
> On Apr 14, 2020, at 17:18, Kai-Heng Feng wrote: > > After commit c23e2043d5f7 ("HID: multitouch: do not filter mice nodes"), > MT_CLS_WIN_8 also supports mouse nodes, hence make MT_CLS_WIN_8_DUAL > redundant. > > Remove MT_CLS_WIN_8_DUAL accordingly. A gentle ping... > > Signed-off-by: Kai-Heng Feng > --- > drivers/hid/hid-ids.h| 9 > drivers/hid/hid-multitouch.c | 45 ++-- > 2 files changed, 2 insertions(+), 52 deletions(-) > > diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h > index b18b13147a6f..7134389afd2e 100644 > --- a/drivers/hid/hid-ids.h > +++ b/drivers/hid/hid-ids.h > @@ -76,12 +76,8 @@ > > #define USB_VENDOR_ID_ALPS_JP 0x044E > #define HID_DEVICE_ID_ALPS_U1_DUAL0x120B > -#define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F > -#define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 > #define HID_DEVICE_ID_ALPS_U1 0x1215 > #define HID_DEVICE_ID_ALPS_T4_BTNLESS 0x120C > -#define HID_DEVICE_ID_ALPS_1222 0x1222 > - > > #define USB_VENDOR_ID_AMI 0x046b > #define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10 > @@ -281,9 +277,6 @@ > > #define USB_VENDOR_ID_CIDC0x1677 > > -#define I2C_VENDOR_ID_CIRQUE 0x0488 > -#define I2C_PRODUCT_ID_CIRQUE_121F 0x121F > - > #define USB_VENDOR_ID_CJTOUCH 0x24b8 > #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_00200x0020 > #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_00400x0040 > @@ -729,8 +722,6 @@ > #define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049 > #define USB_DEVICE_ID_LENOVO_TPPRODOCK0x6067 > #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 > -#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 > -#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 > #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D0x608d > > #define USB_VENDOR_ID_LG 0x1fd2 > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c > index 362805ddf377..bcd37abb2a4a 100644 > --- a/drivers/hid/hid-multitouch.c > +++ b/drivers/hid/hid-multitouch.c > @@ -188,7 +188,7 @@ static void mt_post_parse(struct mt_device *td, struct > mt_application *app); > /* reserved 0x0011 */ > #define MT_CLS_WIN_8 0x0012 > #define MT_CLS_EXPORT_ALL_INPUTS 0x0013 > -#define MT_CLS_WIN_8_DUAL0x0014 > +/* reserved 0x0014 */ > > /* vendor specific classes */ > #define MT_CLS_3M 0x0101 > @@ -272,14 +272,6 @@ static const struct mt_class mt_classes[] = { > .quirks = MT_QUIRK_ALWAYS_VALID | > MT_QUIRK_CONTACT_CNT_ACCURATE, > .export_all_inputs = true }, > - { .name = MT_CLS_WIN_8_DUAL, > - .quirks = MT_QUIRK_ALWAYS_VALID | > - MT_QUIRK_IGNORE_DUPLICATES | > - MT_QUIRK_HOVERING | > - MT_QUIRK_CONTACT_CNT_ACCURATE | > - MT_QUIRK_WIN8_PTP_BUTTONS, > - .export_all_inputs = true }, > - > /* >* vendor specific classes >*/ > @@ -754,8 +746,7 @@ static int mt_touch_input_mapping(struct hid_device > *hdev, struct hid_input *hi, > MT_STORE_FIELD(inrange_state); > return 1; > case HID_DG_CONFIDENCE: > - if ((cls->name == MT_CLS_WIN_8 || > - cls->name == MT_CLS_WIN_8_DUAL) && > + if (cls->name == MT_CLS_WIN_8 && > (field->application == HID_DG_TOUCHPAD || >field->application == HID_DG_TOUCHSCREEN)) > app->quirks |= MT_QUIRK_CONFIDENCE; > @@ -1786,32 +1777,6 @@ static const struct hid_device_id mt_devices[] = { > MT_USB_DEVICE(USB_VENDOR_ID_3M, > USB_DEVICE_ID_3M3266) }, > > - /* Alps devices */ > - { .driver_data = MT_CLS_WIN_8_DUAL, > - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, > - USB_VENDOR_ID_ALPS_JP, > - HID_DEVICE_ID_ALPS_U1_DUAL_PTP) }, > - { .driver_data = MT_CLS_WIN_8_DUAL, > - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, > - USB_VENDOR_ID_ALPS_JP, > - HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, > - { .driver_data = MT_CLS_WIN_8_DUAL, > - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, > - USB_VENDOR_ID_ALPS_JP, > - HID_DEVICE_ID_ALPS_1222) }, > - > - /* Lenovo X1 TAB Gen 2 */ > - { .driver_data = MT_CLS_WIN_8_DUAL, > - HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, > -USB_VENDOR_ID_LENOVO, > -USB_DEVICE_ID_LENOVO_X1_TAB) }, > - > - /* Lenovo X1 TAB Gen 3 */ > - { .driver_data = MT_CLS_WIN_8_DUAL, > -
Re: [PATCH 13/14] sched: cpufreq: Use IS_ENABLED() for schedutil
Hi Quentin On Thu, May 07, 2020 at 07:10:11PM +0100, Quentin Perret wrote: > The IS_ENABLED() macro evaluates to true when an option is set to =y or > =m. As such, it is a good fit for tristate options. > > In preparation for modularizing schedutil, change all the related ifdefs > to use IS_ENABLED(). > > Signed-off-by: Quentin Perret > --- > include/linux/cpufreq.h | 2 +- > include/linux/sched/sysctl.h | 2 +- > kernel/sched/sched.h | 4 ++-- > kernel/sched/topology.c | 4 ++-- > kernel/sysctl.c | 2 +- > 5 files changed, 7 insertions(+), 7 deletions(-) > > diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h > index 267cc3b624da..c1176b8a0f61 100644 > --- a/include/linux/cpufreq.h > +++ b/include/linux/cpufreq.h > @@ -983,7 +983,7 @@ static inline bool policy_has_boost_freq(struct > cpufreq_policy *policy) > } > #endif > > -#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > +#if defined(CONFIG_ENERGY_MODEL) && IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > void sched_cpufreq_governor_change(struct cpufreq_policy *policy, > struct cpufreq_governor *old_gov); > #else > diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h > index d4f6215ee03f..704d971f204f 100644 > --- a/include/linux/sched/sysctl.h > +++ b/include/linux/sched/sysctl.h > @@ -94,7 +94,7 @@ extern int sysctl_schedstats(struct ctl_table *table, int > write, >void __user *buffer, size_t *lenp, >loff_t *ppos); > > -#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > +#if defined(CONFIG_ENERGY_MODEL) && IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > extern unsigned int sysctl_sched_energy_aware; > extern int sched_energy_aware_handler(struct ctl_table *table, int write, >void __user *buffer, size_t *lenp, > diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index 60592cde80e8..087508723e58 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -217,7 +217,7 @@ static inline void update_avg(u64 *avg, u64 sample) > > static inline bool dl_entity_is_special(struct sched_dl_entity *dl_se) > { > -#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL > +#if IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > return unlikely(dl_se->flags & SCHED_FLAG_SUGOV); > #else > return false; > @@ -2459,7 +2459,7 @@ unsigned long scale_irq_capacity(unsigned long util, > unsigned long irq, unsigned > } > #endif > > -#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > +#if defined(CONFIG_ENERGY_MODEL) && IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > > #define perf_domain_span(pd) (to_cpumask(((pd)->em_pd->cpus))) > > diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c > index b905f2e8d9b2..5f49d25730bd 100644 > --- a/kernel/sched/topology.c > +++ b/kernel/sched/topology.c > @@ -201,7 +201,7 @@ sd_parent_degenerate(struct sched_domain *sd, struct > sched_domain *parent) > return 1; > } > > -#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > +#if defined(CONFIG_ENERGY_MODEL) && IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > DEFINE_STATIC_KEY_FALSE(sched_energy_present); > unsigned int sysctl_sched_energy_aware = 1; > DEFINE_MUTEX(sched_energy_mutex); > @@ -2287,7 +2287,7 @@ void partition_sched_domains_locked(int ndoms_new, > cpumask_var_t doms_new[], > ; > } > > -#if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > +#if defined(CONFIG_ENERGY_MODEL) && IS_ENABLED(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) > /* Build perf. domains: */ > for (i = 0; i < ndoms_new; i++) { > for (j = 0; j < n && !sched_energy_update; j++) { Now that scheduler does not have any references to schedutil_gov and cpufreq has want_eas flag, do we need this CONFIG_CPU_FREQ_GOV_SCHEDUTIL checks here? Thanks, Pavan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
linux-next: build failure after merge of the block tree
Hi all, After merging the block tree, today's linux-next build (x86_64 allmodconfig) failed like this: In file included from include/linux/kernel.h:15, from include/linux/list.h:9, from include/linux/module.h:12, from block/bfq-iosched.c:116: block/bfq-iosched.c: In function 'bfq_set_next_ioprio_data': block/bfq-iosched.c:4980:5: error: implicit declaration of function 'bdi_dev_name'; did you mean 'blkg_dev_name'? [-Werror=implicit-function-declaration] 4980 | bdi_dev_name(bfqq->bfqd->queue->backing_dev_info), | ^~~~ Caused by commit 0f6438fca125 ("bdi: use bdi_dev_name() to get device name") I have applied the following patch for today. From: Stephen Rothwell Date: Fri, 8 May 2020 15:23:50 +1000 Subject: [PATCH] bdi: bdi_dev_name() needs backing-dev.h Fixes: 0f6438fca125 ("bdi: use bdi_dev_name() to get device name") Signed-off-by: Stephen Rothwell --- block/bfq-iosched.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index 4d4fe44a9eea..3d411716d7ee 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -123,6 +123,7 @@ #include #include #include +#include #include "blk.h" #include "blk-mq.h" -- 2.26.2 -- Cheers, Stephen Rothwell pgpaCQzoxeI6E.pgp Description: OpenPGP digital signature
Re: [PATCH] mmc: block: Fix request completion in the CQE timeout path
On Thu, 7 May 2020 at 16:06, Adrian Hunter wrote: > > First, it should be noted that the CQE timeout (60 seconds) is substantial > so a CQE request that times out is really stuck, and the race between > timeout and completion is extremely unlikely. Nevertheless this patch > fixes an issue with it. > > Commit ad73d6feadbd7b ("mmc: complete requests from ->timeout") > preserved the existing functionality, to complete the request. > However that had only been necessary because the block layer > timeout handler had been marking the request to prevent it from being > completed normally. That restriction was removed at the same time, the > result being that a request that has gone will have been completed anyway. > That is, the completion in the timeout handler became unnecessary. > > At the time, the unnecessary completion was harmless because the block > layer would ignore it, although that changed in kernel v5.0. > > Note for stable, this patch will not apply cleanly without patch "mmc: > core: Fix recursive locking issue in CQE recovery path" > > Signed-off-by: Adrian Hunter > Fixes: ad73d6feadbd7b ("mmc: complete requests from ->timeout") > Cc: sta...@vger.kernel.org > --- > > > This is the patch I alluded to when replying to "mmc: core: Fix recursive > locking issue in CQE recovery path" Looks like the patch got corrupted, I was trying to fix it, but just couldn't figure it out. Can you please re-format and do a repost? Kind regards Uffe > > > drivers/mmc/core/queue.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c > index 72bef39d7011..10ea67892b5f 100644 > --- a/drivers/mmc/core/queue.c > +++ b/drivers/mmc/core/queue.c > @@ -110,8 +110,7 @@ static enum blk_eh_timer_return mmc_cqe_timed_out(struct > request *req) > mmc_cqe_recovery_notifier(mrq); > return BLK_EH_RESET_TIMER; > } > - /* No timeout (XXX: huh? comment doesn't make much sense) */ > - blk_mq_complete_request(req); > + /* The request has gone already */ > return BLK_EH_DONE; > default: > /* Timeout is handled by mmc core */ > -- > 2.17.1 >
[git pull] drm fixes for 5.7-rc5
Hey Linus, Another pretty normal week, didn't get any i915 fixes yet, so next week I'd expect double the usual i915, but otherwise a bunch of amdgpu and some scattered other fixes. Dave. drm-fixes-2020-05-08: drm fixes for 5.7-rc5 hdcp: - fix HDCP regression amdgpu: - Runtime PM fixes - DC fix for PPC - Misc DC fixes virtio: - fix context ordering issue sun4i: - old gcc warning fix ingenic-drm: - missing module support The following changes since commit 0e698dfa282211e414076f9dc7e83c1c288314fd: Linux 5.7-rc4 (2020-05-03 14:56:04 -0700) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm tags/drm-fixes-2020-05-08 for you to fetch changes up to a9fe6f18cde03c20facbf75dc910a372c1c1025b: Merge tag 'drm-misc-fixes-2020-05-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes (2020-05-08 15:04:25 +1000) drm fixes for 5.7-rc5 hdcp: - fix HDCP regression amdgpu: - Runtime PM fixes - DC fix for PPC - Misc DC fixes virtio: - fix context ordering issue sun4i: - old gcc warning fix ingenic-drm: - missing module support Arnd Bergmann (1): sun6i: dsi: fix gcc-4.8 Aurabindo Pillai (1): drm/amd/display: Prevent dpcd reads with passive dongles Daniel Kolesa (1): drm/amd/display: work around fp code being emitted outside of DC_FP_START/END Dave Airlie (2): Merge tag 'amd-drm-fixes-5.7-2020-05-06' of git://people.freedesktop.org/~agd5f/linux into drm-fixes Merge tag 'drm-misc-fixes-2020-05-07' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes Evan Quan (2): drm/amdgpu: move kfd suspend after ip_suspend_phase1 drm/amdgpu: drop redundant cg/pg ungate on runpm enter Gurchetan Singh (1): drm/virtio: create context before RESOURCE_CREATE_2D in 3D mode H. Nikolaus Schaller (1): drm: ingenic-drm: add MODULE_DEVICE_TABLE Michel Dänzer (1): drm/amdgpu/dc: Use WARN_ON_ONCE for ASSERT Roman Li (1): drm/amd/display: fix counter in wait_for_no_pipes_pending Sean Paul (1): drm: Fix HDCP failures when SRM fw is missing Sung Lee (1): drm/amd/display: Update DCN2.1 DV Code Revision drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 ++--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 17 +++- drivers/gpu/drm/amd/display/dc/core/dc.c | 5 ++-- .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c | 31 -- .../display/dc/dml/dcn21/display_rq_dlg_calc_21.c | 8 +++--- drivers/gpu/drm/amd/display/dc/os_types.h | 2 +- drivers/gpu/drm/drm_hdcp.c | 8 +- drivers/gpu/drm/ingenic/ingenic-drm.c | 1 + drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 2 +- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 + drivers/gpu/drm/virtio/virtgpu_gem.c | 3 +++ drivers/gpu/drm/virtio/virtgpu_ioctl.c | 3 +-- 12 files changed, 57 insertions(+), 31 deletions(-)
Re: [PATCH 2/4] cpufreq: qoriq: Add platform dependencies
On 07-05-20, 13:29, Geert Uytterhoeven wrote: > The Freescale QorIQ clock controller is only present on Freescale E500MC > and Layerscape SoCs. Add platform dependencies to the QORIQ_CPUFREQ > config symbol, to avoid asking the user about it when configuring a > kernel without E500MC or Layerscape support. > > Signed-off-by: Geert Uytterhoeven > --- > drivers/cpufreq/Kconfig | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig > index c3e6bd59e9208822..e917501325525f16 100644 > --- a/drivers/cpufreq/Kconfig > +++ b/drivers/cpufreq/Kconfig > @@ -323,7 +323,8 @@ endif > > config QORIQ_CPUFREQ > tristate "CPU frequency scaling driver for Freescale QorIQ SoCs" > - depends on OF && COMMON_CLK && (PPC_E500MC || ARM || ARM64) > + depends on OF && COMMON_CLK > + depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST > select CLK_QORIQ > help > This adds the CPUFreq driver support for Freescale QorIQ SoCs Applied. Thanks. -- viresh
linux-next 20200506 - build failure with net/bpfilter/bpfilter_umh
My kernel build came to a screeching halt with: CHECK net/bpfilter/bpfilter_kern.c CC [M] net/bpfilter/bpfilter_kern.o CC [U] net/bpfilter/main.o LD [U] net/bpfilter/bpfilter_umh /usr/bin/ld: cannot find -lc collect2: error: ld returned 1 exit status make[2]: *** [scripts/Makefile.userprogs:36: net/bpfilter/bpfilter_umh] Error 1 make[1]: *** [scripts/Makefile.build:494: net/bpfilter] Error 2 make: *** [Makefile:1726: net] Error 2 The culprit is this commit: commit 0592c3c367c4c823f2a939968e72d39360fce1f4 Author: Masahiro Yamada Date: Wed Apr 29 12:45:15 2020 +0900 bpfilter: use 'userprogs' syntax to build bpfilter_umh and specifically, this line: +userldflags += -static At least on Fedora, this dies an ugly death unless you have the glibc-static RPM installed (which is *not* part of the glibc-devel RPM). Not sure how to fix this, or give a heads-up that there's a new requirement that might break the build. pgpNI6zjmun43.pgp Description: PGP signature
Re: [PATCH v5 1/5] mmc: core: Extend mmc_of_parse() to parse CQE bindings
On Thu, 7 May 2020 at 18:33, Veerabhadrarao Badiganti wrote: > > > On 5/6/2020 10:06 PM, Ulf Hansson wrote: > > On Wed, 6 May 2020 at 15:01, Veerabhadrarao Badiganti > > wrote: > >> > >> On 4/28/2020 5:26 AM, Chun-Hung Wu wrote: > >>> Parse CQE bindings "supports-cqe" and "disable-cqe-dcmd" > >>> in mmc_of_parse(). > >>> > >>> Signed-off-by: Chun-Hung Wu > >>> --- > >>>drivers/mmc/core/host.c | 5 + > >>>1 file changed, 5 insertions(+) > >>> > >>> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c > >>> index c876872..47521c6 100644 > >>> --- a/drivers/mmc/core/host.c > >>> +++ b/drivers/mmc/core/host.c > >>> @@ -302,6 +302,11 @@ int mmc_of_parse(struct mmc_host *host) > >>>host->caps2 |= MMC_CAP2_NO_SD; > >>>if (device_property_read_bool(dev, "no-mmc")) > >>>host->caps2 |= MMC_CAP2_NO_MMC; > >>> + if (device_property_read_bool(dev, "supports-cqe")) > >>> + host->caps2 |= MMC_CAP2_CQE; > >> This change is breaking emmc driver on qcom platforms where this dt > >> property is defined. > >> > >> [1.543453] cqhci_deactivate+0xc/0x38 > >> [1.545627] sdhci_msm_reset+0x40/0x58 > >> [1.549447] sdhci_do_reset+0x48/0x7c > >> [1.553180] __sdhci_read_caps+0x7c/0x214 > >> [1.556913] sdhci_setup_host+0x58/0xce8 > >> [1.560905] sdhci_msm_probe+0x588/0x8a4 > >> [1.564900] platform_drv_probe+0x4c/0xb0 > >> > >> So, we cant have this flag defined before sdhci_setup_host(). > >> > >> I will have to clear this cap and re-enable it in our initialization. > > Thanks for reporting! I have dropped all the four patches from > > Chun-Hung, so we can figure out how to fix this. > > > > Please help to review the next version of the series. > > Thanks Ulf. > > Hi Chun-Hung, > > On qcom controller CQE also gets reset when SDHC is reset. So we have to > explicitly disable CQE > by invoking cqhci_deactivate() during sdhc reset > > SDHC gets reset in sdhci_setup_host() even before cqe is initialized. > With MMC_CAP2_CQE_DCMD cap set even before sdhci_set_host(), we are > getting null pointer access with cqhci_deactivate(). > > If CQE getting reset with SDHC reset is generic (applicable to other > controllers) then you have revisit your logic. > If its not the case then only qcom driver would get affected. Thanks for clarifying the problem, much appreciated. To me, it looks like the DT parsing of the CQE properties are better suited to be managed by each sdhci variant, to continue to leave some room for flexibility. Chun-Hung, can you please drop patch 1 and patch2 from the series and adapt to this change in the mediatek variant? [...] Kind regards Uffe
Re: [PATCH V3 03/16] arm64/cpufeature: Make doublelock a signed feature in ID_AA64DFR0
On 05/05/2020 04:40 PM, Will Deacon wrote: > On Sat, May 02, 2020 at 07:03:52PM +0530, Anshuman Khandual wrote: >> Double lock feature can have the following possible values. >> >> 0b - Double lock implemented >> 0b - Double lock not implemented >> >> But in case of a conflict the safe value should be 0b. Hence this must >> be a signed feature instead. Also change FTR_EXACT to FTR_LOWER_SAFE. >> >> Cc: Catalin Marinas >> Cc: Will Deacon >> Cc: Mark Rutland >> Cc: Suzuki K Poulose >> Cc: linux-arm-ker...@lists.infradead.org >> Cc: linux-kernel@vger.kernel.org >> >> Suggested-by: Suzuki K Poulose >> Signed-off-by: Anshuman Khandual >> --- >> arch/arm64/kernel/cpufeature.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c >> index 51386dade423..cba43e4a5c79 100644 >> --- a/arch/arm64/kernel/cpufeature.c >> +++ b/arch/arm64/kernel/cpufeature.c >> @@ -338,7 +338,7 @@ static const struct arm64_ftr_bits ftr_id_mmfr0[] = { >> }; >> >> static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { >> -ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, 36, 28, 0), >> +S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 36, 28, 0), > > Wait, isn't this buggered today? Shouldn't that 28 be a 4? I think we really Ahh, right. Will fix it. > need to: > > 1. Make it impossible to describe overlapping fields, incomplete > registers etc (ideally at build-time) AFICS the _SHIFT defines for a given register must be placed sequentially with dummy place holders (4 bit wide) for any missing fields. In that case we could just call BUILD_BUG_ON() for any possible breakage or overlap. But wondering how and where to loop over these SHIFT values for these registers. Another way (not build time though) will be to scan through ftr_id_xxx[], fetch individual arm64_ftr_bits (assuming there are dummy entries for non existing fields) and assert that arm6r_ftr_bits[shift, width] validates against the previous arm6r_ftr_bits[shift, width] in an increasing manner. Either of these methods will require some more thoughts. > > 2. Have a macro that for 4-bit fields so you don't have to type '4' > all the time Except for ftr_single32[], all other arm64_ftr_bits entries have the exact same shift value (i.e 4). ARM64_FTR_WIDTH sounds good ? > > Suzuki, any ideas how we can make this a bit more robust? > > Will >
[PATCH] perf record: Use an eventfd to wakeup when done
The setting and checking of 'done' contains a rare race where the signal handler setting 'done' is run after checking to break the loop, but before waiting in evlist__poll(). In this case, the main loop won't wake up until either another signal is sent, or the perf data fd causes a wake up. The following simple script can trigger this condition (but you might need to run it for several hours): for ((i = 0; i >= 0; i++)) ; do echo "Loop $i" delay=$(echo "scale=4; 0.1 * $RANDOM/32768" | bc) ./perf record -- sleep 3000 >/dev/null& pid=$! sleep $delay kill -TERM $pid echo "PID $pid" wait $pid done At some point, the loop will stall. Adding logging, even though perf has received the SIGTERM and set 'done = 1', perf will remain sleeping until a second signal is sent. Signed-off-by: Anand K Mistry --- tools/perf/builtin-record.c | 8 1 file changed, 8 insertions(+) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 1ab349abe90469..ce5fc3860131d2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -518,15 +519,19 @@ static int record__pushfn(struct mmap *map, void *to, void *bf, size_t size) static volatile int signr = -1; static volatile int child_finished; +static int done_fd = -1; static void sig_handler(int sig) { + u64 tmp = 1; if (sig == SIGCHLD) child_finished = 1; else signr = sig; done = 1; + if (write(done_fd, , sizeof(tmp)) < 0) + pr_err("failed to signal wakeup fd\n"); } static void sigsegv_handler(int sig) @@ -1424,6 +1429,9 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) int fd; float ratio = 0; + done_fd = eventfd(0, EFD_NONBLOCK); + evlist__add_pollfd(rec->evlist, done_fd); + atexit(record__sig_exit); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); -- 2.26.2.645.ge9eca65c58-goog
[PATCH] kselftests: dmabuf-heaps: Fix confused return value on expected error testing
When I added the expected error testing, I forgot I need to set the return to zero when we successfully see an error. Without this change we only end up testing a single heap before the test quits. Cc: Shuah Khan Cc: Sumit Semwal Cc: Benjamin Gaignard Cc: Brian Starkey Cc: Laura Abbott Cc: "Andrew F. Davis" Cc: linux-kselft...@vger.kernel.org Signed-off-by: John Stultz --- tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c index cd5e1f602ac9..909da9cdda97 100644 --- a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c +++ b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c @@ -351,6 +351,7 @@ static int test_alloc_errors(char *heap_name) } printf("Expected error checking passed\n"); + ret = 0; out: if (dmabuf_fd >= 0) close(dmabuf_fd); -- 2.17.1
Re: [PATCH v4 1/7] ima: Switch to ima_hash_algo for boot aggregate
On Thu Apr 02 20, Mimi Zohar wrote: Hi Roberto, On Wed, 2020-03-25 at 11:47 +0100, Roberto Sassu wrote: boot_aggregate is the first entry of IMA measurement list. Its purpose is to link pre-boot measurements to IMA measurements. As IMA was designed to work with a TPM 1.2, the SHA1 PCR bank was always selected even if a TPM 2.0 with support for stronger hash algorithms is available. This patch first tries to find a PCR bank with the IMA default hash algorithm. If it does not find it, it selects the SHA256 PCR bank for TPM 2.0 and SHA1 for TPM 1.2. Ultimately, it selects SHA1 also for TPM 2.0 if the SHA256 PCR bank is not found. If none of the PCR banks above can be found, boot_aggregate file digest is filled with zeros, as for TPM bypass, making it impossible to perform a remote attestation of the system. Cc: sta...@vger.kernel.org # 5.1.x Fixes: 879b589210a9 ("tpm: retrieve digest size of unknown algorithms with PCR read") Reported-by: Jerry Snitselaar Suggested-by: James Bottomley Signed-off-by: Roberto Sassu Thank you! Â This patch set is now queued in next-integrity-testing during the open window. Â Jerry, I assume this works for you. Â Could we get your tag? thanks! Mimi Hi Mimi, Yes, I no longer get the errors with this patch. Tested-by: Jerry Snitselaar Regards, Jerry
linux-next: manual merge of the amdgpu tree with the pm tree
Hi all, Today's linux-next merge of the amdgpu tree got a conflict in: drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c between commit: e07515563d01 ("PM: sleep: core: Rename DPM_FLAG_NEVER_SKIP") from the pm tree and commit: 500bd19a7e5d ("drm/amdgpu: only set DPM_FLAG_NEVER_SKIP for legacy ATPX BOCO") from the amdgpu tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index c201bc827389,4e4c9550dcf8.. --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@@ -189,10 -188,12 +188,12 @@@ int amdgpu_driver_load_kms(struct drm_d dev_dbg(>pdev->dev, "Error during ACPI methods call\n"); if (adev->runpm) { - dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE); + /* only need to skip on ATPX */ + if (amdgpu_device_supports_boco(dev) && + !amdgpu_is_atpx_hybrid()) - dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NEVER_SKIP); ++ dev_pm_set_driver_flags(dev->dev, DPM_FLAG_NO_DIRECT_COMPLETE); pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); - pm_runtime_set_active(dev->dev); pm_runtime_allow(dev->dev); pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev); pgpSVxbFN1cDv.pgp Description: OpenPGP digital signature
Re: [PATCH v4 2/3] nsproxy: attach to namespaces via pidfds
On Tue, May 05, 2020 at 04:04:31PM +0200, Christian Brauner wrote: > For quite a while we have been thinking about using pidfds to attach to > namespaces. This patchset has existed for about a year already but we've > wanted to wait to see how the general api would be received and adopted. > Now that more and more programs in userspace have started using pidfds > for process management it's time to send this one out. > > This patch makes it possible to use pidfds to attach to the namespaces > of another process, i.e. they can be passed as the first argument to the > setns() syscall. When only a single namespace type is specified the > semantics are equivalent to passing an nsfd. That means > setns(nsfd, CLONE_NEWNET) equals setns(pidfd, CLONE_NEWNET). However, > when a pidfd is passed, multiple namespace flags can be specified in the > second setns() argument and setns() will attach the caller to all the > specified namespaces all at once or to none of them. Specifying 0 is not > valid together with a pidfd. > > Here are just two obvious examples: > setns(pidfd, CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET); > setns(pidfd, CLONE_NEWUSER); > Allowing to also attach subsets of namespaces supports various use-cases > where callers setns to a subset of namespaces to retain privilege, perform > an action and then re-attach another subset of namespaces. > > If the need arises, as Eric suggested, we can extend this patchset to > assume even more context than just attaching all namespaces. His suggestion > specifically was about assuming the process' root directory when > setns(pidfd, 0) or setns(pidfd, SETNS_PIDFD) is specified. For now, just > keep it flexible in terms of supporting subsets of namespaces but let's > wait until we have users asking for even more context to be assumed. At > that point we can add an extension. > > The obvious example where this is useful is a standard container > manager interacting with a running container: pushing and pulling files > or directories, injecting mounts, attaching/execing any kind of process, > managing network devices all these operations require attaching to all > or at least multiple namespaces at the same time. Given that nowadays > most containers are spawned with all namespaces enabled we're currently > looking at at least 14 syscalls, 7 to open the /proc//ns/ > nsfds, another 7 to actually perform the namespace switch. With time > namespaces we're looking at about 16 syscalls. > (We could amortize the first 7 or 8 syscalls for opening the nsfds by > stashing them in each container's monitor process but that would mean > we need to send around those file descriptors through unix sockets > everytime we want to interact with the container or keep on-disk > state. Even in scenarios where a caller wants to join a particular > namespace in a particular order callers still profit from batching > other namespaces. That mostly applies to the user namespace but > all container runtimes I found join the user namespace first no matter > if it privileges or deprivileges the container similar to how unshare > behaves.) > With pidfds this becomes a single syscall no matter how many namespaces > are supposed to be attached to. > > A decently designed, large-scale container manager usually isn't the > parent of any of the containers it spawns so the containers don't die > when it crashes or needs to update or reinitialize. This means that > for the manager to interact with containers through pids is inherently > racy especially on systems where the maximum pid number is not > significicantly bumped. This is even more problematic since we often spawn > and manage thousands or ten-thousands of containers. Interacting with a > container through a pid thus can become risky quite quickly. Especially > since we allow for an administrator to enable advanced features such as > syscall interception where we're performing syscalls in lieu of the > container. In all of those cases we use pidfds if they are available and > we pass them around as stable references. Using them to setns() to the > target process' namespaces is as reliable as using nsfds. Either the > target process is already dead and we get ESRCH or we manage to attach > to its namespaces but we can't accidently attach to another process' > namespaces. So pidfds lend themselves to be used with this api. > The other main advantage is that with this change the pidfd becomes the > only relevant token for most container interactions and it's the only > token we need to create and send around. > > Apart from significiantly reducing the number of syscalls from double > digit to single digit which is a decent reason post-spectre/meltdown > this also allows to switch to a set of namespaces atomically, i.e. > either attaching to all the specified namespaces succeeds or we fail. If > we fail we haven't changed a single namespace. There are currently three > namespaces that can fail (other than for ENOMEM which really is
linux-next: build failure after merge of the drm tree
Hi all, After merging the drm tree, today's linux-next build (x86_64 allmodconfig) failed like this: In file included from include/asm-generic/bug.h:19, from arch/x86/include/asm/bug.h:83, from include/linux/bug.h:5, from include/linux/seq_file.h:7, from include/drm/drm_print.h:31, from drivers/gpu/drm/i915/gt/intel_engine_cs.c:25: drivers/gpu/drm/i915/gt/intel_engine_cs.c: In function 'intel_engine_print_registers': drivers/gpu/drm/i915/gt/intel_engine_cs.c:1428:31: error: 'struct intel_context' has no member named 'lrc_desc' 1428 | upper_32_bits(rq->context->lrc_desc)); | ^~ drivers/gpu/drm/i915/gt/intel_engine_cs.c:1440:31: error: 'struct intel_context' has no member named 'lrc_desc' 1440 | upper_32_bits(rq->context->lrc_desc)); | ^~ In file included from include/linux/interrupt.h:6, from drivers/gpu/drm/i915/gt/intel_lrc.c:134: drivers/gpu/drm/i915/gt/intel_lrc.c: In function 'active_context': drivers/gpu/drm/i915/gt/intel_lrc.c:2850:32: error: 'struct intel_context' has no member named 'lrc_desc' 2850 | if (upper_32_bits(rq->context->lrc_desc) == ccid) { |^~ drivers/gpu/drm/i915/gt/intel_lrc.c:2859:32: error: 'struct intel_context' has no member named 'lrc_desc' 2859 | if (upper_32_bits(rq->context->lrc_desc) == ccid) { |^~ Caused by commit 53b2622e7746 ("drm/i915/execlists: Avoid reusing the same logical CCID") from the drm-intel-fixes tree interacting with commits 606727842d8b ("drm/i915/gt: Include the execlists CCID of each port in the engine dump") 4c977837ba29 ("drm/i915/execlists: Peek at the next submission for error interrupts") from the drm tree. I have added teh following merge fix patch. From: Stephen Rothwell Date: Fri, 8 May 2020 14:21:40 +1000 Subject: [PATCH] drm/i915/execlists: fix up for "Avoid reusing the same logical CCID" Signed-off-by: Stephen Rothwell --- drivers/gpu/drm/i915/gt/intel_engine_cs.c | 4 ++-- drivers/gpu/drm/i915/gt/intel_lrc.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index b1f8527f02c8..7c3cb5aedfdf 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -1425,7 +1425,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, len = scnprintf(hdr, sizeof(hdr), "\t\tActive[%d]: ccid:%08x, ", (int)(port - execlists->active), - upper_32_bits(rq->context->lrc_desc)); + rq->context->lrc.ccid); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); print_request(m, rq, hdr); @@ -1437,7 +1437,7 @@ static void intel_engine_print_registers(struct intel_engine_cs *engine, len = scnprintf(hdr, sizeof(hdr), "\t\tPending[%d]: ccid:%08x, ", (int)(port - execlists->pending), - upper_32_bits(rq->context->lrc_desc)); + rq->context->lrc.ccid); len += print_ring(hdr + len, sizeof(hdr) - len, rq); scnprintf(hdr + len, sizeof(hdr) - len, "rq: "); print_request(m, rq, hdr); diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c b/drivers/gpu/drm/i915/gt/intel_lrc.c index 233f815c3c86..456d286c17dd 100644 --- a/drivers/gpu/drm/i915/gt/intel_lrc.c +++ b/drivers/gpu/drm/i915/gt/intel_lrc.c @@ -2847,7 +2847,7 @@ active_context(struct intel_engine_cs *engine, u32 ccid) */ for (port = el->active; (rq = *port); port++) { - if (upper_32_bits(rq->context->lrc_desc) == ccid) { + if (rq->context->lrc.ccid == ccid) { ENGINE_TRACE(engine, "ccid found at active:%zd\n", port - el->active); @@ -2856,7 +2856,7 @@ active_context(struct intel_engine_cs *engine, u32 ccid) } for (port = el->pending; (rq = *port); port++) { - if (upper_32_bits(rq->context->lrc_desc) == ccid) { + if (rq->context->lrc.ccid == ccid) { ENGINE_TRACE(engine, "ccid found at pending:%zd\n", port - el->pending); -- 2.26.2 -- Cheers, Stephen Rothwell pgpz7GVW5NJ_R.pgp Description: OpenPGP digital signature
Re: [PATCH V3 02/16] arm64/cpufeature: Drop TraceFilt feature exposure from ID_DFR0 register
On 05/05/2020 04:12 PM, Will Deacon wrote: > On Tue, May 05, 2020 at 12:20:41PM +0530, Anshuman Khandual wrote: >> On 05/05/2020 01:54 AM, Will Deacon wrote: >>> On Sat, May 02, 2020 at 07:03:51PM +0530, Anshuman Khandual wrote: ID_DFR0 based TraceFilt feature should not be exposed to guests. Hence lets drop it. Cc: Catalin Marinas Cc: Will Deacon Cc: Marc Zyngier Cc: Mark Rutland Cc: James Morse Cc: Suzuki K Poulose Cc: linux-arm-ker...@lists.infradead.org Cc: linux-kernel@vger.kernel.org Suggested-by: Mark Rutland Reviewed-by: Suzuki K Poulose Signed-off-by: Anshuman Khandual --- arch/arm64/kernel/cpufeature.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 6d032fbe416f..51386dade423 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -435,7 +435,6 @@ static const struct arm64_ftr_bits ftr_id_pfr1[] = { }; static const struct arm64_ftr_bits ftr_id_dfr0[] = { - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), >>> >>> Hmm, this still confuses me. Is this not now FTR_NONSTRICT? Why is that ok? >> >> Mark had mentioned about it earlier >> (https://patchwork.kernel.org/patch/11287805/) >> Did I misinterpret the first part ? Could not figure "capping the emulated >> debug >> features" part. Probably, Mark could give some more details. >> >> From the earlier discussion: >> >> * ID_DFR0 fields need more thought; we should limit what we expose here. >> I don't think it's valid for us to expose TraceFilt, and I suspect we >> need to add capping for debug features we currently emulate. > > Sorry, I for confused (again) by the cpufeature code :) I'm going to add > the following to my comment: > > > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index c1d44d127baa..9b05843d67af 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -53,6 +53,11 @@ > * arbitrary physical CPUs, but some features not present on the host are > * also advertised and emulated. Look at sys_reg_descs[] for the gory > * details. > + * > + * - If the arm64_ftr_bits[] for a register has a missing field, then this > + * field is treated as STRICT RES0, including for read_sanitised_ftr_reg(). > + * This is stronger than FTR_HIDDEN and can be used to hide features from > + * KVM guests. > */ > > #define pr_fmt(fmt) "CPU features: " fmt > Wondering if you will take this comment via a separate patch/branch or should I fold it here instead. > > However, I think we really want to get rid of ftr_generic_32bits[] entirely > and spell out all of the register fields, even just using comments for the > fields we're omitting: Should we do that later or in this series itself ? > > > @@ -425,7 +430,7 @@ static const struct arm64_ftr_bits ftr_id_pfr1[] = { > }; > > static const struct arm64_ftr_bits ftr_id_dfr0[] = { > - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), > + /* 31:28TraceFilt */ > S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0xf), > /* PerfMon */ > ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), > ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0), > > > Longer term, I think we'll probably want to handle these within > ARM64_FTR_BITS, as we may end up with features that we want to hide from > KVM guests but not from the host kernel. Sure, but for now will fold the above changes here.
[PATCH] f2fs: remove race condition in releasing cblocks
From: Daeho Jeong Now, if writing pages and releasing compress blocks occur simultaneously, and releasing cblocks is executed more than one time to a file, then total block count of filesystem and block count of the file could be incorrect and damaged. We have to execute releasing compress blocks only one time for a file without being interfered by writepages path. Signed-off-by: Daeho Jeong --- fs/f2fs/file.c | 31 --- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4aab4b42d8ba..a92bc51b9b28 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3488,6 +3488,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) pgoff_t page_idx = 0, last_idx; unsigned int released_blocks = 0; int ret; + int writecount; if (!f2fs_sb_has_compression(F2FS_I_SB(inode))) return -EOPNOTSUPP; @@ -3509,13 +3510,29 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) inode_lock(inode); - if (!IS_IMMUTABLE(inode)) { - F2FS_I(inode)->i_flags |= F2FS_IMMUTABLE_FL; - f2fs_set_inode_flags(inode); - inode->i_ctime = current_time(inode); - f2fs_mark_inode_dirty_sync(inode, true); + writecount = atomic_read(>i_writecount); + if ((filp->f_mode & FMODE_WRITE && writecount != 1) || writecount) { + ret = -EBUSY; + goto out; } + if (IS_IMMUTABLE(inode)) { + ret = -EINVAL; + goto out; + } + + ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX); + if (ret) + goto out; + + if (!F2FS_I(inode)->i_compr_blocks) + goto out; + + F2FS_I(inode)->i_flags |= F2FS_IMMUTABLE_FL; + f2fs_set_inode_flags(inode); + inode->i_ctime = current_time(inode); + f2fs_mark_inode_dirty_sync(inode, true); + down_write(_I(inode)->i_gc_rwsem[WRITE]); down_write(_I(inode)->i_mmap_sem); @@ -3554,9 +3571,9 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) up_write(_I(inode)->i_gc_rwsem[WRITE]); up_write(_I(inode)->i_mmap_sem); - - inode_unlock(inode); out: + inode_unlock(inode); + mnt_drop_write_file(filp); if (ret >= 0) { -- 2.26.2.526.g744177e7f7-goog
Re: [PATCH v3 4/4] media: rockchip: rga: Only set output CSC mode for RGB input
On Thu, 2020-04-30 at 18:42 +0200, Paul Kocialkowski wrote: > Setting the output CSC mode is required for a YUV output, but must not > be set when the input is also YUV. Doing this (as tested with a YUV420P > to YUV420P conversion) results in wrong colors. > > Adapt the logic to only set the output CSC mode when the output is YUV and > the input is RGB. Also add a comment to clarify the rationale. > > Fixes: f7e7b48e6d79 ("[media] rockchip/rga: v4l2 m2m support") > Signed-off-by: Paul Kocialkowski Reviewed-by: Ezequiel Garcia Thanks! > --- > drivers/media/platform/rockchip/rga/rga-hw.c | 8 +++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c > b/drivers/media/platform/rockchip/rga/rga-hw.c > index 5607ee8d1917..aaa96f256356 100644 > --- a/drivers/media/platform/rockchip/rga/rga-hw.c > +++ b/drivers/media/platform/rockchip/rga/rga-hw.c > @@ -200,6 +200,11 @@ static void rga_cmd_set_trans_info(struct rga_ctx *ctx) > dst_info.data.format = ctx->out.fmt->hw_format; > dst_info.data.swap = ctx->out.fmt->color_swap; > > + /* > + * CSC mode must only be set when the colorspace families differ between > + * input and output. It must remain unset (zeroed) if both are the same. > + */ > + > if (RGA_COLOR_FMT_IS_YUV(ctx->in.fmt->hw_format) && > RGA_COLOR_FMT_IS_RGB(ctx->out.fmt->hw_format)) { > switch (ctx->in.colorspace) { > @@ -212,7 +217,8 @@ static void rga_cmd_set_trans_info(struct rga_ctx *ctx) > } > } > > - if (RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) { > + if (RGA_COLOR_FMT_IS_RGB(ctx->in.fmt->hw_format) && > + RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) { > switch (ctx->out.colorspace) { > case V4L2_COLORSPACE_REC709: > dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0;
Re: [PATCH v3 3/4] media: rockchip: rga: Introduce color fmt macros and refactor CSC mode logic
On Thu, 2020-04-30 at 18:42 +0200, Paul Kocialkowski wrote: > This introduces two macros: RGA_COLOR_FMT_IS_YUV and RGA_COLOR_FMT_IS_RGB > which allow quick checking of the colorspace familily of a RGA color format. > > These macros are then used to refactor the logic for CSC mode selection. > The two nested tests for input colorspace are simplified into a single one, > with a logical and, making the whole more readable. > > Signed-off-by: Paul Kocialkowski Reviewed-by: Ezequiel Garcia Thanks a lot for the nice cleanup. > --- > drivers/media/platform/rockchip/rga/rga-hw.c | 23 +--- > drivers/media/platform/rockchip/rga/rga-hw.h | 5 + > 2 files changed, 15 insertions(+), 13 deletions(-) > > diff --git a/drivers/media/platform/rockchip/rga/rga-hw.c > b/drivers/media/platform/rockchip/rga/rga-hw.c > index 4be6dcf292ff..5607ee8d1917 100644 > --- a/drivers/media/platform/rockchip/rga/rga-hw.c > +++ b/drivers/media/platform/rockchip/rga/rga-hw.c > @@ -200,22 +200,19 @@ static void rga_cmd_set_trans_info(struct rga_ctx *ctx) > dst_info.data.format = ctx->out.fmt->hw_format; > dst_info.data.swap = ctx->out.fmt->color_swap; > > - if (ctx->in.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { > - if (ctx->out.fmt->hw_format < RGA_COLOR_FMT_YUV422SP) { > - switch (ctx->in.colorspace) { > - case V4L2_COLORSPACE_REC709: > - src_info.data.csc_mode = > - RGA_SRC_CSC_MODE_BT709_R0; > - break; > - default: > - src_info.data.csc_mode = > - RGA_SRC_CSC_MODE_BT601_R0; > - break; > - } > + if (RGA_COLOR_FMT_IS_YUV(ctx->in.fmt->hw_format) && > + RGA_COLOR_FMT_IS_RGB(ctx->out.fmt->hw_format)) { > + switch (ctx->in.colorspace) { > + case V4L2_COLORSPACE_REC709: > + src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; > + break; > + default: > + src_info.data.csc_mode = RGA_SRC_CSC_MODE_BT601_R0; > + break; > } > } > > - if (ctx->out.fmt->hw_format >= RGA_COLOR_FMT_YUV422SP) { > + if (RGA_COLOR_FMT_IS_YUV(ctx->out.fmt->hw_format)) { > switch (ctx->out.colorspace) { > case V4L2_COLORSPACE_REC709: > dst_info.data.csc_mode = RGA_SRC_CSC_MODE_BT709_R0; > diff --git a/drivers/media/platform/rockchip/rga/rga-hw.h > b/drivers/media/platform/rockchip/rga/rga-hw.h > index 96cb0314dfa7..e8917e5630a4 100644 > --- a/drivers/media/platform/rockchip/rga/rga-hw.h > +++ b/drivers/media/platform/rockchip/rga/rga-hw.h > @@ -95,6 +95,11 @@ > #define RGA_COLOR_FMT_CP_8BPP 15 > #define RGA_COLOR_FMT_MASK 15 > > +#define RGA_COLOR_FMT_IS_YUV(fmt) \ > + (((fmt) >= RGA_COLOR_FMT_YUV422SP) && ((fmt) < RGA_COLOR_FMT_CP_1BPP)) > +#define RGA_COLOR_FMT_IS_RGB(fmt) \ > + ((fmt) < RGA_COLOR_FMT_YUV422SP) > + > #define RGA_COLOR_NONE_SWAP 0 > #define RGA_COLOR_RB_SWAP 1 > #define RGA_COLOR_ALPHA_SWAP 2
[PATCH v2 5/5] drm/panel: add panel driver for Ilitek ili9341 panels
From: dillon min This is a driver for 320x240 TFT panels, accepting a rgb input streams that get adapted and scaled to the panel. Signed-off-by: dillon min --- drivers/gpu/drm/panel/Kconfig| 8 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 561 +++ 3 files changed, 570 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index a1723c1..e42692c 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -95,6 +95,14 @@ config DRM_PANEL_ILITEK_IL9322 Say Y here if you want to enable support for Ilitek IL9322 QVGA (320x240) RGB, YUV and ITU-T BT.656 panels. +config DRM_PANEL_ILITEK_IL9341 + tristate "Ilitek ILI9341 240x320 QVGA panels" + depends on OF && SPI + select REGMAP + help + Say Y here if you want to enable support for Ilitek IL9341 + QVGA (240x320) RGB panels. + config DRM_PANEL_ILITEK_ILI9881C tristate "Ilitek ILI9881C-based panels" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index 96a883c..d123543 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += panel-feiyang-fy07024di26a30d.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o +obj-$(CONFIG_DRM_PANEL_ILITEK_IL9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9341.c b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c new file mode 100644 index 000..ec22d80 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9341.c @@ -0,0 +1,561 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Ilitek ILI9341 TFT LCD drm_panel driver. + * + * This panel can be configured to support: + * - 16-bit parallel RGB interface + * + * Copyright (C) 2020 Dillon Min + * Derived from drivers/drm/gpu/panel/panel-ilitek-ili9322.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#define DEFAULT_SPI_SPEED 1000 + +#define ILI9341_SLEEP_OUT0x11 /* Sleep out register */ +#define ILI9341_GAMMA0x26 /* Gamma register */ +#define ILI9341_DISPLAY_OFF 0x28 /* Display off register */ +#define ILI9341_DISPLAY_ON 0x29 /* Display on register */ +#define ILI9341_COLUMN_ADDR 0x2A /* Colomn address register */ +#define ILI9341_PAGE_ADDR0x2B /* Page address register */ +#define ILI9341_GRAM 0x2C /* GRAM register */ +#define ILI9341_MAC 0x36 /* Memory Access Control register*/ +#define ILI9341_PIXEL_FORMAT 0x3A /* Pixel Format register */ +#define ILI9341_WDB 0x51 /* Write Brightness Display +* register +*/ +#define ILI9341_WCD 0x53 /* Write Control Display +* register +*/ +#define ILI9341_RGB_INTERFACE0xB0 /* RGB Interface Signal Control */ +#define ILI9341_FRC 0xB1 /* Frame Rate Control register */ +#define ILI9341_BPC 0xB5 /* Blanking Porch Control +* register +*/ +#define ILI9341_DFC 0xB6 /* Display Function Control +* register +*/ +#define ILI9341_POWER1 0xC0 /* Power Control 1 register */ +#define ILI9341_POWER2 0xC1 /* Power Control 2 register */ +#define ILI9341_VCOM10xC5 /* VCOM Control 1 register */ +#define ILI9341_VCOM20xC7 /* VCOM Control 2 register */ +#define ILI9341_POWERA 0xCB /* Power control A register */ +#define ILI9341_POWERB 0xCF /* Power control B register */ +#define ILI9341_PGAMMA 0xE0 /* Positive Gamma Correction +* register +*/ +#define ILI9341_NGAMMA 0xE1 /* Negative Gamma Correction +* register +*/ +#define ILI9341_DTCA
[PATCH v2 4/5] clk: stm32: Fix stm32f429 ltdc driver loading hang in clk set rate. keep ltdc clk running after kernel startup
From: dillon min as store stm32f4_rcc_register_pll return to the wrong offset of clks, so ltdc gate clk is null. need change clks[PLL_VCO_SAI] to clks[PLL_SAI] add CLK_IGNORE_UNUSED for ltdc to make sure clk not be freed by clk_disable_unused Signed-off-by: dillon min --- drivers/clk/clk-stm32f4.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 18117ce..0ba73de 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -129,7 +129,8 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, - { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, + { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div", + CLK_IGNORE_UNUSED }, }; static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { @@ -1757,7 +1758,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in", >pll_data[1], _clk_lock); - clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in", + clks[PLL_SAI] = stm32f4_rcc_register_pll("vco_in", >pll_data[2], _clk_lock); for (n = 0; n < MAX_POST_DIV; n++) { -- 2.7.4
[PATCH v2 1/5] ARM: dts: stm32: Add pin map for ltdc, spi5 on stm32f429-disco board
From: dillon min This patch adds the pin configuration for ltdc, spi5 controller on stm32f429-disco board. Signed-off-by: dillon min --- arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 ++ 1 file changed, 67 insertions(+) diff --git a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi index 392fa14..0eb107f 100644 --- a/arch/arm/boot/dts/stm32f4-pinctrl.dtsi +++ b/arch/arm/boot/dts/stm32f4-pinctrl.dtsi @@ -316,6 +316,73 @@ }; }; + ltdc_pins_f429_disco: ltdc-1 { + pins { + pinmux = , + /* LCD_HSYNC */ +, +/* LCD_VSYNC */ +, +/* LCD_CLK */ +, +/* LCD_R2 */ +, +/* LCD_R3 */ +, +/* LCD_R4 */ +, +/* LCD_R5 */ +, +/* LCD_R6*/ +, +/* LCD_R7 */ +, +/* LCD_G2 */ +, +/* LCD_G3 */ +, +/* LCD_G4 */ +, +/* LCD_B2 */ +, +/* LCD_B3*/ +, +/* LCD_G5 */ +, +/* LCD_G6 */ +, +/* LCD_G7 */ +, +/* LCD_B4 */ +, +/* LCD_B5 */ +, +/* LCD_B6 */ +, +/* LCD_B7 */ +; +/* LCD_DE */ + slew-rate = <2>; + }; + }; + + spi5_pins: spi5-0 { + pins1 { + pinmux = , + /* SPI5_CLK */ +; + /* SPI5_MOSI */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = ; + /* SPI5_MISO */ + bias-disable; + }; + }; + dcmi_pins: dcmi-0 { pins { pinmux = , /* DCMI_HSYNC */ -- 2.7.4
[PATCH v2 2/5] ARM: dts: stm32: enable ltdc binding with ili9341 on stm32429-disco board
From: dillon min Enable the ltdc & ili9341 on stm32429-disco board. Signed-off-by: dillon min --- arch/arm/boot/dts/stm32f429-disco.dts | 40 +++ 1 file changed, 40 insertions(+) diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index 30c0f67..2d9637a 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -49,6 +49,8 @@ #include "stm32f429.dtsi" #include "stm32f429-pinctrl.dtsi" #include +#include +#include / { model = "STMicroelectronics STM32F429i-DISCO board"; @@ -127,3 +129,41 @@ pinctrl-names = "default"; status = "okay"; }; + + { + status = "okay"; + pinctrl-0 = <_pins_f429_disco>; + pinctrl-names = "default"; + + port { + ltdc_out_rgb: endpoint { + remote-endpoint = <_in_rgb>; + }; + }; +}; + + { + status = "okay"; + pinctrl-0 = <_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = < 2 GPIO_ACTIVE_LOW>; + dmas = < 3 2 0x400 0x0>, + < 4 2 0x400 0x0>; + dma-names = "rx", "tx"; + display: display@0{ + /* Connect panel-ilitek-9341 to ltdc */ + compatible = "stm32f429,ltdc-panel", "ilitek,ili9341"; + reg = <0>; + spi-3wire; + spi-max-frequency = <1000>; + dc-gpios = < 13 0>; + port { + panel_in_rgb: endpoint { + remote-endpoint = <_out_rgb>; + }; + }; + }; +}; + -- 2.7.4
[PATCH v2 0/5] Enable ilitek ili9341 on stm32f429-disco board
From: dillon min This patchset have following changes V2: verify ilitek,ili9341.yaml with make O=../linux-stm32 dt_binding_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml V1: add ili9341 drm panel driver add ltdc, spi5 controller for stm32f429-disco add ltdc, spi5 pin map for stm32f429-disco add docs about ili9341 fix ltdc driver loading hang in clk set rate bug dillon min (5): ARM: dts: stm32: Add pin map for ltdc, spi5 on stm32f429-disco board ARM: dts: stm32: enable ltdc binding with ili9341 on stm32429-disco board dt-bindings: display: panel: Add ilitek ili9341 panel bindings clk: stm32: Fix stm32f429 ltdc driver loading hang in clk set rate. keep ltdc clk running after kernel startup drm/panel: add panel driver for Ilitek ili9341 panels .../bindings/display/panel/ilitek,ili9341.yaml | 68 +++ arch/arm/boot/dts/stm32f4-pinctrl.dtsi | 67 +++ arch/arm/boot/dts/stm32f429-disco.dts | 40 ++ drivers/clk/clk-stm32f4.c | 5 +- drivers/gpu/drm/panel/Kconfig | 8 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-ilitek-ili9341.c | 561 + 7 files changed, 748 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9341.c -- 2.7.4
[PATCH v2 3/5] dt-bindings: display: panel: Add ilitek ili9341 panel bindings
From: dillon min Add documentation for "ilitek,ili9341" panel. Signed-off-by: dillon min --- Hi Rob Herring, This patch [PATCH V2 3/5] about ilitek,ili9341.yaml was verifyed with make dt_binding_check thanks. best regards, dillon, .../bindings/display/panel/ilitek,ili9341.yaml | 68 ++ 1 file changed, 68 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml diff --git a/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml new file mode 100644 index 000..94c2b15 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/ilitek,ili9341.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/ilitek,ili9341.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek-9341 Display Panel + +maintainers: + - Dillon Min + +description: | + Ilitek ILI9341 TFT panel driver with SPI control bus + This is a driver for 320x240 TFT panels, accepting a rgb input + streams that get adapted and scaled to the panel. + +allOf: + - $ref: panel-common.yaml# + +properties: + compatible: +items: + - const: stm32f429,ltdc-panel + - {} # ilitek,ili9341, but not listed here to avoid false select + + reg: true + + dc-gpios: +maxItems: 1 +description: panel spi dc gpio + + spi-3wire: true + + spi-max-frequency: +const: 1000 + + port: true + +additionalProperties: false + +required: + - compatible + - reg + - dc-gpios + - spi-3wire + - spi-max-frequency + - port + +examples: + - |+ +spi { +#address-cells = <1>; +#size-cells = <0>; +panel: display@0 { + compatible = "stm32f429,ltdc-panel", "ilitek,ili9341"; + reg = <0>; + spi-3wire; + spi-max-frequency = <1000>; + dc-gpios = < 13 0>; + port { + panel_in: endpoint { + remote-endpoint = <_out>; + }; + }; + }; +}; +... + -- 2.7.4
[PATCH] perf/core: Do not initialise statics to 0 and add space before '{'
Fix the following checkpatch errors: ERROR: do not initialise statics to 0 #10616: FILE: ./kernel/events/core.c:10616: + static int hw_context_taken = 0; ERROR: space required before the open brace '{' #11070: FILE: ./kernel/events/core.c:11070: + } else if (is_write_backward(event)){ Signed-off-by: Kaige Li --- kernel/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 80cf996..8d47d30 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -10618,7 +10618,7 @@ int perf_pmu_register(struct pmu *pmu, const char *name, int type) skip_type: if (pmu->task_ctx_nr == perf_hw_context) { - static int hw_context_taken = 0; + static int hw_context_taken; /* * Other than systems with heterogeneous CPUs, it never makes @@ -11072,7 +11072,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, if (overflow_handler) { event->overflow_handler = overflow_handler; event->overflow_handler_context = context; - } else if (is_write_backward(event)){ + } else if (is_write_backward(event)) { event->overflow_handler = perf_event_output_backward; event->overflow_handler_context = NULL; } else { -- 2.1.0
Re: [PATCH v4 1/3] nsproxy: add struct nsset
On Tue, May 05, 2020 at 04:04:30PM +0200, Christian Brauner wrote: > Add a simple struct nsset. It holds all necessary pieces to switch to a new > set of namespaces without leaving a task in a half-switched state which we > will make use of in the next patch. This patch switches the existing setns > logic over without causing a change in setns() behavior. This brings > setns() closer to how unshare() works(). The prepare_ns() function is > responsible to prepare all necessary information. This has two reasons. > First it minimizes dependencies between individual namespaces, i.e. all > install handler can expect that all fields are properly initialized > independent in what order they are called in. Second, this makes the code > easier to maintain and easier to follow if it needs to be changed. > > The prepare_ns() helper will only be switched over to use a flags argument > in the next patch. Here it will still use nstype as a simple integer > argument which was argued would be clearer. I'm not particularly > opinionated about this if it really helps or not. The struct nsset itself > already contains the flags field since its name already indicates that it > can contain information required by different namespaces. None of this > should have functional consequences. > > Cc: Eric W. Biederman > Cc: Serge Hallyn Reviewed-by: Serge Hallyn Thanks, Christian. > Cc: Jann Horn > Cc: Michael Kerrisk > Cc: Aleksa Sarai > Signed-off-by: Christian Brauner > --- > /* v2 */ > patch introduced > > /* v3 */ > - Eric W. Biederman : > - Remove the prior ns_capable_cred() patch and simplify the permission > check from ns_capable_cred(nsset, nsset->cred->user_ns, CAP_SYS_ADMIN)) > to from ns_capable(nsset->cred->user_ns, CAP_SYS_ADMIN)). > > /* v4 */ > - Eric W. Biederman : > - Fix nstype == 0 case. > --- > fs/namespace.c| 10 ++-- > include/linux/mnt_namespace.h | 1 + > include/linux/nsproxy.h | 24 ++ > include/linux/proc_ns.h | 4 +- > ipc/namespace.c | 7 ++- > kernel/cgroup/namespace.c | 5 +- > kernel/nsproxy.c | 90 ++- > kernel/pid_namespace.c| 5 +- > kernel/time/namespace.c | 5 +- > kernel/user_namespace.c | 8 ++-- > kernel/utsname.c | 5 +- > net/core/net_namespace.c | 5 +- > 12 files changed, 132 insertions(+), 37 deletions(-) > > diff --git a/fs/namespace.c b/fs/namespace.c > index a28e4db075ed..62899fad4a04 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -3954,16 +3954,18 @@ static void mntns_put(struct ns_common *ns) > put_mnt_ns(to_mnt_ns(ns)); > } > > -static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) > +static int mntns_install(struct nsset *nsset, struct ns_common *ns) > { > - struct fs_struct *fs = current->fs; > + struct nsproxy *nsproxy = nsset->nsproxy; > + struct fs_struct *fs = nsset->fs; > struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns; > + struct user_namespace *user_ns = nsset->cred->user_ns; > struct path root; > int err; > > if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) || > - !ns_capable(current_user_ns(), CAP_SYS_CHROOT) || > - !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) > + !ns_capable(user_ns, CAP_SYS_CHROOT) || > + !ns_capable(user_ns, CAP_SYS_ADMIN)) > return -EPERM; > > if (is_anon_ns(mnt_ns)) > diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h > index 35942084cd40..007cfa52efb2 100644 > --- a/include/linux/mnt_namespace.h > +++ b/include/linux/mnt_namespace.h > @@ -6,6 +6,7 @@ > struct mnt_namespace; > struct fs_struct; > struct user_namespace; > +struct ns_common; > > extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace > *, > struct user_namespace *, struct fs_struct *); > diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h > index 074f395b9ad2..cdb171efc7cb 100644 > --- a/include/linux/nsproxy.h > +++ b/include/linux/nsproxy.h > @@ -41,6 +41,30 @@ struct nsproxy { > }; > extern struct nsproxy init_nsproxy; > > +/* > + * A structure to encompass all bits needed to install > + * a partial or complete new set of namespaces. > + * > + * If a new user namespace is requested cred will > + * point to a modifiable set of credentials. If a pointer > + * to a modifiable set is needed nsset_cred() must be > + * used and tested. > + */ > +struct nsset { > + unsigned flags; > + struct nsproxy *nsproxy; > + struct fs_struct *fs; > + const struct cred *cred; > +}; > + > +static inline struct cred *nsset_cred(struct nsset *set) > +{ > + if (set->flags & CLONE_NEWUSER) > + return (struct cred *)set->cred; > + > + return NULL; > +} > + > /* > * the namespaces access rules are: > * > diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h > index
Re: [PATCH v2] PM / devfreq: tegra: Add Dmitry as a maintainer
Hi Rafael, Could you please apply it to linux-pm directly? I think that it is better to be applied directly for preventing the possible merge conflict of MAINTAINERS file. Best Regards, Chanwoo Choi On 4/3/20 7:17 AM, Dmitry Osipenko wrote: > I was contributing to the NVIDIA Tegra20+ devfreq drivers recently and > want to help keep them working and evolving in the future. > > Acked-by: Chanwoo Choi > Signed-off-by: Dmitry Osipenko > --- > > Changelog: > > v2: - Addressed review comments made by Chanwoo Choi to v1 by correcting > git's address, making this patch standalone and adding Rafael Wysocki > to the list of email recipients. > > MAINTAINERS | 9 + > 1 file changed, 9 insertions(+) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 245a96316636..0a694e20ea19 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -10922,6 +10922,15 @@ F: include/linux/memblock.h > F: mm/memblock.c > F: Documentation/core-api/boot-time-mm.rst > > +MEMORY FREQUENCY SCALING DRIVERS FOR NVIDIA TEGRA > +M: Dmitry Osipenko > +L: linux...@vger.kernel.org > +L: linux-te...@vger.kernel.org > +T: git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git > +S: Maintained > +F: drivers/devfreq/tegra20-devfreq.c > +F: drivers/devfreq/tegra30-devfreq.c > + > MEMORY MANAGEMENT > M: Andrew Morton > L: linux...@kvack.org >
Re: [PATCH] mmc: meson-mx-sdio: trigger a soft reset after a timeout or CRC error
On Thu, 7 May 2020 at 23:14, Martin Blumenstingl wrote: > > Hi Ulf, > > On Thu, May 7, 2020 at 11:29 AM Ulf Hansson wrote: > > > > On Mon, 4 May 2020 at 00:28, Martin Blumenstingl > > wrote: > > > > > > The vendor driver (from the 3.10 kernel) triggers a soft reset every > > > time before starting a new command. While this fixes a problem where > > > SDIO cards are not detected at all (because all commands simply > > > timed out) this hurts SD card read performance a bit (in my tests > > > between 10% to 20%). > > > > > > Trigger a soft reset after we got a CRC error or if the previous command > > > timed out (just like the vendor driver from the same 3.10 kernel for the > > > newer SDHC controller IP does). This fixes detection of SDIO cards and > > > doesn't hurt SD card read performance at the same time. > > > > > > With this patch the initialization of an RTL8723BS SDIO card looks like > > > this: > > > req done (CMD52): -110: > > > clock 40Hz busmode 2 powermode 2 cs 1 Vdd 21 width 1 timing 0 > > > starting CMD0 arg flags 00c0 > > > req done (CMD0): 0: > > > clock 40Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 0 > > > starting CMD8 arg 01aa flags 02f5 > > > req done (CMD8): -110: > > > starting CMD5 arg flags 02e1 > > > req done (CMD5): 0: 90ff > > > starting CMD5 arg 0020 flags 02e1 > > > req done (CMD5): 0: 90ff > > > starting CMD3 arg flags 0075 > > > req done (CMD3): 0: 0001 > > > starting CMD7 arg 0001 flags 0015 > > > req done (CMD7): 0: 1e00 > > > starting CMD52 arg flags 0195 > > > req done (CMD52): 0: 1032 > > > [... more CMD52 omitted ...] > > > clock 40Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 2 > > > clock 5000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 1 timing 2 > > > starting CMD52 arg 0e00 flags 0195 > > > req done (CMD52): 0: 1000 > > > starting CMD52 arg 8e02 flags 0195 > > > req done (CMD52): 0: 1002 > > > clock 5000Hz busmode 2 powermode 2 cs 0 Vdd 21 width 4 timing 2 > > > starting CMD52 arg 0002 flags 0195 > > > req done (CMD52): 0: 1007 > > > [... more CMD52 omitted ...] > > > new high speed SDIO card at address 0001 > > > > > > Fixes: ed80a13bb4c4c9 ("mmc: meson-mx-sdio: Add a driver for the Amlogic > > > Meson8 and Meson8b SoCs") > > > Signed-off-by: Martin Blumenstingl > > > --- > > > Ulf, I consider this non-critical because as long as the meson-mx-sdhc > > > driver is not merged we only have one MMC driver for these platforms. > > > I don't know anybody to prefer SDIO wifi over SD card access, so this > > > can go into -next (in my option at least). > > > > > > > Alright, applied for next, thanks! > thank you for taking this patch! > > I received a confirmation (off-list) saying that this patch works as it > should. > Tobias was not Cc'ed on the original mail so he gave me to permission > (again, off-list - he's Cc'ed now) to add his: > Tested-by: Tobias Baumann <017623705...@o2online.de> I will add it next time I rebase my branch, probably on Monday, thanks! Kind regards Uffe
linux-next: manual merge of the drm tree with the drm-intel-fixes tree
Hi all, Today's linux-next merge of the drm tree got a conflict in: drivers/gpu/drm/i915/gem/i915_gem_domain.c between commit: 47bf7b7a7151 ("drm/i915/gem: Remove object_is_locked assertion from unpin_from_display_plane") from the drm-intel-fixes tree and commit: 9da0ea09639f ("drm/i915/gem: Drop cached obj->bind_count") from the drm tree. I fixed it up (see below) and can carry the fix as necessary. This is now fixed as far as linux-next is concerned, but any non trivial conflicts should be mentioned to your upstream maintainer when your tree is submitted for merging. You may also want to consider cooperating with the maintainer of the conflicting tree to minimise any particularly complex conflicts. -- Cheers, Stephen Rothwell diff --cc drivers/gpu/drm/i915/gem/i915_gem_domain.c index 4f96c8788a2e,af43e82f45c7.. --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@@ -368,7 -368,8 +368,7 @@@ static void i915_gem_object_bump_inacti struct drm_i915_private *i915 = to_i915(obj->base.dev); struct i915_vma *vma; - if (!atomic_read(>bind_count)) - GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); + if (list_empty(>vma.list)) return; mutex_lock(>ggtt.vm.mutex); pgpj95Fw915Q8.pgp Description: OpenPGP digital signature
Re: [PATCH] PM / devfreq: imx: Fix inconsistent IS_ERR and PTR_ERR
On 5/8/20 12:55 PM, Chanwoo Choi wrote: > On 5/7/20 10:12 PM, Gustavo A. R. Silva wrote: >> Fix inconsistent IS_ERR and PTR_ERR in imx_bus_init_icc(). >> >> The proper pointer to be passed as argument to PTR_ERR() is >> priv->icc_pdev. >> >> This bug was detected with the help of Coccinelle. >> >> Fixes: 16c1d2f1b0bd ("PM / devfreq: imx: Register interconnect device") >> Signed-off-by: Gustavo A. R. Silva >> --- >> drivers/devfreq/imx-bus.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c >> index 532e7954032f..4f38455ad742 100644 >> --- a/drivers/devfreq/imx-bus.c >> +++ b/drivers/devfreq/imx-bus.c >> @@ -88,8 +88,8 @@ static int imx_bus_init_icc(struct device *dev) >> dev, icc_driver_name, -1, NULL, 0); >> if (IS_ERR(priv->icc_pdev)) { >> dev_err(dev, "failed to register icc provider %s: %ld\n", >> -icc_driver_name, PTR_ERR(priv->devfreq)); >> -return PTR_ERR(priv->devfreq); >> +icc_driver_name, PTR_ERR(priv->icc_pdev)); >> +return PTR_ERR(priv->icc_pdev); >> } >> >> return 0; >> > > Applied it. Thanks. > I edit the patch title as following: - before : PM / devfreq: imx: Fix inconsistent IS_ERR and PTR_ERR - after : PM / devfreq: imx-bus: Fix inconsistent IS_ERR and PTR_ERR Thanks. -- Best Regards, Chanwoo Choi Samsung Electronics
Re: [PATCH v2] KVM: SVM: Disable AVIC before setting V_IRQ
Hi Suravee, I love your patch! Yet something to improve: [auto build test ERROR on kvm/linux-next] [also build test ERROR on vhost/linux-next linus/master v5.7-rc4 next-20200507] [cannot apply to linux/master] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Suravee-Suthikulpanit/KVM-SVM-Disable-AVIC-before-setting-V_IRQ/20200507-111704 base: https://git.kernel.org/pub/scm/virt/kvm/kvm.git linux-next config: x86_64-allyesconfig (attached as .config) compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 54b35c066417d4856e9d53313f7e98b354274584) reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kbuild test robot All errors (new ones prefixed by >>): >> arch/x86/kvm/x86.c:8107:2: error: implicit declaration of function >> 'kvm_make_all_cpus_request_except' [-Werror,-Wimplicit-function-declaration] kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, ^ arch/x86/kvm/x86.c:8107:2: note: did you mean 'kvm_make_all_cpus_request'? include/linux/kvm_host.h:818:6: note: 'kvm_make_all_cpus_request' declared here bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req); ^ 1 error generated. vim +/kvm_make_all_cpus_request_except +8107 arch/x86/kvm/x86.c 8065 8066 /* 8067 * NOTE: Do not hold any lock prior to calling this. 8068 * 8069 * In particular, kvm_request_apicv_update() expects kvm->srcu not to be 8070 * locked, because it calls __x86_set_memory_region() which does 8071 * synchronize_srcu(>srcu). 8072 */ 8073 void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit) 8074 { 8075 struct kvm_vcpu *except; 8076 unsigned long old, new, expected; 8077 8078 if (!kvm_x86_ops.check_apicv_inhibit_reasons || 8079 !kvm_x86_ops.check_apicv_inhibit_reasons(bit)) 8080 return; 8081 8082 old = READ_ONCE(kvm->arch.apicv_inhibit_reasons); 8083 do { 8084 expected = new = old; 8085 if (activate) 8086 __clear_bit(bit, ); 8087 else 8088 __set_bit(bit, ); 8089 if (new == old) 8090 break; 8091 old = cmpxchg(>arch.apicv_inhibit_reasons, expected, new); 8092 } while (old != expected); 8093 8094 if (!!old == !!new) 8095 return; 8096 8097 trace_kvm_apicv_update_request(activate, bit); 8098 if (kvm_x86_ops.pre_update_apicv_exec_ctrl) 8099 kvm_x86_ops.pre_update_apicv_exec_ctrl(kvm, activate); 8100 8101 /* 8102 * Sending request to update APICV for all other vcpus, 8103 * while update the calling vcpu immediately instead of 8104 * waiting for another #VMEXIT to handle the request. 8105 */ 8106 except = kvm_get_running_vcpu(); > 8107 kvm_make_all_cpus_request_except(kvm, KVM_REQ_APICV_UPDATE, 8108 except); 8109 if (except) 8110 kvm_vcpu_update_apicv(except); 8111 } 8112 EXPORT_SYMBOL_GPL(kvm_request_apicv_update); 8113 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org .config.gz Description: application/gzip
Re: [PATCH] PM / devfreq: imx: Fix inconsistent IS_ERR and PTR_ERR
On 5/7/20 10:12 PM, Gustavo A. R. Silva wrote: > Fix inconsistent IS_ERR and PTR_ERR in imx_bus_init_icc(). > > The proper pointer to be passed as argument to PTR_ERR() is > priv->icc_pdev. > > This bug was detected with the help of Coccinelle. > > Fixes: 16c1d2f1b0bd ("PM / devfreq: imx: Register interconnect device") > Signed-off-by: Gustavo A. R. Silva > --- > drivers/devfreq/imx-bus.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c > index 532e7954032f..4f38455ad742 100644 > --- a/drivers/devfreq/imx-bus.c > +++ b/drivers/devfreq/imx-bus.c > @@ -88,8 +88,8 @@ static int imx_bus_init_icc(struct device *dev) > dev, icc_driver_name, -1, NULL, 0); > if (IS_ERR(priv->icc_pdev)) { > dev_err(dev, "failed to register icc provider %s: %ld\n", > - icc_driver_name, PTR_ERR(priv->devfreq)); > - return PTR_ERR(priv->devfreq); > + icc_driver_name, PTR_ERR(priv->icc_pdev)); > + return PTR_ERR(priv->icc_pdev); > } > > return 0; > Applied it. Thanks. -- Best Regards, Chanwoo Choi Samsung Electronics
Re: [PATCH] ipc/util.c: sysvipc_find_ipc() incorrectly updates position index
On Thu, May 07, 2020 at 05:02:42PM -0700, Andrew Morton wrote: > Here's how I resolved things. Please check? > > static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, > loff_t *new_pos) > { > unsigned long index = pos; > struct kern_ipc_perm *ipc; > > rcu_read_lock(); > ipc = xa_find(>ipcs, , ULONG_MAX, XA_PRESENT); > if (ipc) > ipc_lock_object(ipc); > else > rcu_read_unlock(); > *new_pos = pos + 1; > return ipc; > } Surely that should be '*new_pos = index + 1'? Or did I misunderstand the reasoning behind the other patch?
Re: [PATCH v3 3/4] perf stat: Copy counts from prev_raw_counts to evsel->counts
Hi Jiri, On 5/7/2020 11:19 PM, Jiri Olsa wrote: On Thu, May 07, 2020 at 02:58:21PM +0800, Jin Yao wrote: It would be useful to support the overall statistics for perf-stat interval mode. For example, report the summary at the end of "perf-stat -I" output. But since perf-stat can support many aggregation modes, such as --per-thread, --per-socket, -M and etc, we need a solution which doesn't bring much complexity. The idea is to use 'evsel->prev_raw_counts' which is updated in each interval and it's saved with the latest counts. Before reporting the summary, we copy the counts from evsel->prev_raw_counts to evsel->counts, and next we just follow non-interval processing. I did not realize we already store the count in prev_raw_counts ;-) nice catch! Thanks! :) In evsel__compute_deltas, this patch saves counts to the position of [cpu0,thread0] for AGGR_GLOBAL. After copying counts from evsel->prev_raw_counts to evsel->counts, we don't need to modify process_counter_maps in perf_stat_process_counter to let it work well. I don't understand why you need to store it in here.. what's the catch in process_counter_maps? Sorry, I didn't explain clearly. You know the idea is to copy evsel->prev_raw_counts to evsel->counts before reporting the summary. But for AGGR_GLOBAL (cpu = -1 in perf_evsel__compute_deltas), the evsel->prev_raw_counts is only stored with the aggr value. if (cpu == -1) { tmp = evsel->prev_raw_counts->aggr; evsel->prev_raw_counts->aggr = *count; } else { tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread); *perf_counts(evsel->prev_raw_counts, cpu, thread) = *count; } So after copying evsel->prev_raw_counts to evsel->counts, perf_counts(evsel->counts, cpu, thread) are all 0. Once we go to process_counter_maps again, in process_counter_values, count->val is 0. case AGGR_GLOBAL: aggr->val += count->val; aggr->ena += count->ena; aggr->run += count->run; And the aggr->val is 0. So this patch uses a trick that saves the previous aggr value to cpu0/thread0, then above aggr->val calculation can work correctly. Thanks Jin Yao thanks, jirka
[PATCH RFCv2 9/9] arm64: Support async page fault
This supports asynchronous page fault for the guest. The design is similar to what x86 has: on receiving a PAGE_NOT_PRESENT signal from the host, the current task is either rescheduled or put into power saving mode. The task will be waken up when PAGE_READY signal is received. The PAGE_READY signal might be received in the context of the suspended process, to be waken up. That means the suspended process has to wake up itself, but it's not safe and prone to cause dead-lock on CPU runqueue lock. So the wakeup is delayed on returning from kernel space to user space or idle process is picked for running. The signals are conveyed through the async page fault control block, which was passed to host on enabling the functionality. On each page fault, the control block is checked and switch to the async page fault handling flow if any signals exist. The feature is put into the CONFIG_KVM_GUEST umbrella, which is added by this patch. So we have inline functions implemented in kvm_para.h, like other architectures do, to check if async page fault (one of the KVM para-virtualized features) is available. Also, the kernel boot parameter "no-kvmapf" can be specified to disable the feature. Signed-off-by: Gavin Shan --- arch/arm64/Kconfig | 11 + arch/arm64/include/asm/exception.h | 3 + arch/arm64/include/asm/kvm_para.h | 27 +- arch/arm64/kernel/entry.S | 33 +++ arch/arm64/kernel/process.c| 4 + arch/arm64/mm/fault.c | 434 + 6 files changed, 505 insertions(+), 7 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 40fb05d96c60..2d5e5ee62d6d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1045,6 +1045,17 @@ config PARAVIRT under a hypervisor, potentially improving performance significantly over full virtualization. +config KVM_GUEST + bool "KVM Guest Support" + depends on PARAVIRT + default y + help + This option enables various optimizations for running under the KVM + hypervisor. Overhead for the kernel when not running inside KVM should + be minimal. + + In case of doubt, say Y + config PARAVIRT_TIME_ACCOUNTING bool "Paravirtual steal time accounting" select PARAVIRT diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index 7a6e81ca23a8..d878afa42746 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -46,4 +46,7 @@ void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr); void do_cp15instr(unsigned int esr, struct pt_regs *regs); void do_el0_svc(struct pt_regs *regs); void do_el0_svc_compat(struct pt_regs *regs); +#ifdef CONFIG_KVM_GUEST +void kvm_async_pf_delayed_wake(void); +#endif #endif /* __ASM_EXCEPTION_H */ diff --git a/arch/arm64/include/asm/kvm_para.h b/arch/arm64/include/asm/kvm_para.h index 0ea481dd1c7a..b2f8ef243df7 100644 --- a/arch/arm64/include/asm/kvm_para.h +++ b/arch/arm64/include/asm/kvm_para.h @@ -3,6 +3,20 @@ #define _ASM_ARM_KVM_PARA_H #include +#include +#include + +#ifdef CONFIG_KVM_GUEST +static inline int kvm_para_available(void) +{ + return 1; +} +#else +static inline int kvm_para_available(void) +{ + return 0; +} +#endif /* CONFIG_KVM_GUEST */ static inline bool kvm_check_and_clear_guest_paused(void) { @@ -11,17 +25,16 @@ static inline bool kvm_check_and_clear_guest_paused(void) static inline unsigned int kvm_arch_para_features(void) { - return 0; + unsigned int features = 0; + + if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_APF)) + features |= (1 << KVM_FEATURE_ASYNC_PF); + + return features; } static inline unsigned int kvm_arch_para_hints(void) { return 0; } - -static inline bool kvm_para_available(void) -{ - return false; -} - #endif /* _ASM_ARM_KVM_PARA_H */ diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index ddcde093c433..15efd57129ff 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -751,12 +751,45 @@ finish_ret_to_user: enable_step_tsk x1, x2 #ifdef CONFIG_GCC_PLUGIN_STACKLEAK bl stackleak_erase +#endif +#ifdef CONFIG_KVM_GUEST + bl kvm_async_pf_delayed_wake #endif kernel_exit 0 ENDPROC(ret_to_user) .popsection // .entry.text +#ifdef CONFIG_KVM_GUEST + .pushsection ".rodata", "a" +SYM_DATA_START(__exception_handlers_offset) + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .quad el1_sync - vectors + .quad el1_irq - vectors + .quad 0 + .quad el1_error - vectors + .quad el0_sync - vectors + .quad el0_irq - vectors + .quad 0 + .quad el0_error - vectors +#ifdef CONFIG_COMPAT + .quad el0_sync_compat - vectors + .quad el0_irq_compat - vectors + .quad