Merge ac18d78146 ("media: uvcvideo: Remove dangling pointers") into android14-6.1-lts

Steps on the way to 6.1.130

Resolves merge conflicts in:
	drivers/bluetooth/btqca.c

Change-Id: I8e563e9814854b55f5ee133f4ae72d59659161a8
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2025-03-12 10:26:46 +00:00
33 changed files with 294 additions and 142 deletions

View File

@@ -1753,6 +1753,7 @@
resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
phys = <&mipi_tx0>;
phy-names = "dphy";
status = "disabled";
};
mutex: mutex@14016000 {

View File

@@ -2226,7 +2226,7 @@
cdsp: remoteproc@98900000 {
compatible = "qcom,sm8350-cdsp-pas";
reg = <0 0x098900000 0 0x1400000>;
reg = <0 0x98900000 0 0x1400000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,

View File

@@ -2093,7 +2093,7 @@
remoteproc_adsp: remoteproc@30000000 {
compatible = "qcom,sm8450-adsp-pas";
reg = <0 0x030000000 0 0x100>;
reg = <0 0x30000000 0 0x100>;
interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
<&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2159,7 +2159,7 @@
remoteproc_cdsp: remoteproc@32300000 {
compatible = "qcom,sm8450-cdsp-pas";
reg = <0 0x032300000 0 0x1400000>;
reg = <0 0x32300000 0 0x10000>;
interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
<&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,

View File

@@ -246,6 +246,39 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
}
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
static bool qca_filename_has_extension(const char *filename)
{
const char *suffix = strrchr(filename, '.');
/* File extensions require a dot, but not as the first or last character */
if (!suffix || suffix == filename || *(suffix + 1) == '\0')
return 0;
/* Avoid matching directories with names that look like files with extensions */
return !strchr(suffix, '/');
}
static bool qca_get_alt_nvm_file(char *filename, size_t max_size)
{
char fwname[64];
const char *suffix;
/* nvm file name has an extension, replace with .bin */
if (qca_filename_has_extension(filename)) {
suffix = strrchr(filename, '.');
strscpy(fwname, filename, suffix - filename + 1);
snprintf(fwname + (suffix - filename),
sizeof(fwname) - (suffix - filename), ".bin");
/* If nvm file is already the default one, return false to skip the retry. */
if (strcmp(fwname, filename) == 0)
return false;
snprintf(filename, max_size, "%s", fwname);
return true;
}
return false;
}
static int qca_tlv_check_data(struct hci_dev *hdev,
struct qca_fw_config *config,
u8 *fw_data, size_t fw_size,
@@ -543,6 +576,19 @@ static int qca_download_firmware(struct hci_dev *hdev,
config->fwname, ret);
return ret;
}
}
/* If the board-specific file is missing, try loading the default
* one, unless that was attempted already.
*/
else if (config->type == TLV_TYPE_NVM &&
qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
ret = request_firmware(&fw, config->fwname, &hdev->dev);
if (ret) {
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
return ret;
}
} else {
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);

View File

@@ -14,6 +14,7 @@
* Access to the event log extended by the TCG BIOS of PC platform
*/
#include <linux/device.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <linux/security.h>
@@ -62,6 +63,11 @@ static bool tpm_is_tpm2_log(void *bios_event_log, u64 len)
return n == 0;
}
static void tpm_bios_log_free(void *data)
{
kvfree(data);
}
/* read binary bios log */
int tpm_read_log_acpi(struct tpm_chip *chip)
{
@@ -135,7 +141,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
}
/* malloc EventLog space */
log->bios_event_log = kmalloc(len, GFP_KERNEL);
log->bios_event_log = kvmalloc(len, GFP_KERNEL);
if (!log->bios_event_log)
return -ENOMEM;
@@ -161,10 +167,16 @@ int tpm_read_log_acpi(struct tpm_chip *chip)
goto err;
}
ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log);
if (ret) {
log->bios_event_log = NULL;
goto err;
}
return format;
err:
kfree(log->bios_event_log);
tpm_bios_log_free(log->bios_event_log);
log->bios_event_log = NULL;
return ret;
}

View File

@@ -6,6 +6,7 @@
* Thiebaud Weksteen <tweek@google.com>
*/
#include <linux/device.h>
#include <linux/efi.h>
#include <linux/tpm_eventlog.h>
@@ -55,7 +56,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
}
/* malloc EventLog space */
log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
log->bios_event_log = devm_kmemdup(&chip->dev, log_tbl->log, log_size, GFP_KERNEL);
if (!log->bios_event_log) {
ret = -ENOMEM;
goto out;
@@ -76,7 +77,7 @@ int tpm_read_log_efi(struct tpm_chip *chip)
MEMREMAP_WB);
if (!final_tbl) {
pr_err("Could not map UEFI TPM final log\n");
kfree(log->bios_event_log);
devm_kfree(&chip->dev, log->bios_event_log);
ret = -ENOMEM;
goto out;
}
@@ -91,11 +92,11 @@ int tpm_read_log_efi(struct tpm_chip *chip)
* Allocate memory for the 'combined log' where we will append the
* 'final events log' to.
*/
tmp = krealloc(log->bios_event_log,
log_size + final_events_log_size,
GFP_KERNEL);
tmp = devm_krealloc(&chip->dev, log->bios_event_log,
log_size + final_events_log_size,
GFP_KERNEL);
if (!tmp) {
kfree(log->bios_event_log);
devm_kfree(&chip->dev, log->bios_event_log);
ret = -ENOMEM;
goto out;
}

View File

@@ -10,6 +10,7 @@
* Read the event log created by the firmware on PPC64
*/
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/tpm_eventlog.h>
@@ -65,7 +66,7 @@ int tpm_read_log_of(struct tpm_chip *chip)
return -EIO;
}
log->bios_event_log = kmemdup(__va(base), size, GFP_KERNEL);
log->bios_event_log = devm_kmemdup(&chip->dev, __va(base), size, GFP_KERNEL);
if (!log->bios_event_log)
return -ENOMEM;

View File

@@ -267,7 +267,6 @@ static void tpm_dev_release(struct device *dev)
idr_remove(&dev_nums_idr, chip->dev_num);
mutex_unlock(&idr_lock);
kfree(chip->log.bios_event_log);
kfree(chip->work_space.context_buf);
kfree(chip->work_space.session_buf);
kfree(chip->allocated_banks);

View File

@@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate bdp_clks[] = {
GATE_DUMMY(CLK_DUMMY, "bdp_dummy"),
GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),

View File

@@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = {
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate img_clks[] = {
GATE_DUMMY(CLK_DUMMY, "img_dummy"),
GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),

View File

@@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
static const struct mtk_gate vdec_clks[] = {
GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
};

View File

@@ -21,6 +21,22 @@
#include "clk-gate.h"
#include "clk-mux.h"
const struct mtk_gate_regs cg_regs_dummy = { 0, 0, 0 };
EXPORT_SYMBOL_GPL(cg_regs_dummy);
static int mtk_clk_dummy_enable(struct clk_hw *hw)
{
return 0;
}
static void mtk_clk_dummy_disable(struct clk_hw *hw) { }
const struct clk_ops mtk_clk_dummy_ops = {
.enable = mtk_clk_dummy_enable,
.disable = mtk_clk_dummy_disable,
};
EXPORT_SYMBOL_GPL(mtk_clk_dummy_ops);
static void mtk_init_clk_data(struct clk_hw_onecell_data *clk_data,
unsigned int clk_num)
{

View File

@@ -22,6 +22,25 @@
struct platform_device;
/*
* We need the clock IDs to start from zero but to maintain devicetree
* backwards compatibility we can't change bindings to start from zero.
* Only a few platforms are affected, so we solve issues given by the
* commonized MTK clocks probe function(s) by adding a dummy clock at
* the beginning where needed.
*/
#define CLK_DUMMY 0
extern const struct clk_ops mtk_clk_dummy_ops;
extern const struct mtk_gate_regs cg_regs_dummy;
#define GATE_DUMMY(_id, _name) { \
.id = _id, \
.name = _name, \
.regs = &cg_regs_dummy, \
.ops = &mtk_clk_dummy_ops, \
}
struct mtk_fixed_clk {
int id;
const char *name;

View File

@@ -288,12 +288,9 @@ static int stm32_cec_probe(struct platform_device *pdev)
return ret;
cec->clk_cec = devm_clk_get(&pdev->dev, "cec");
if (IS_ERR(cec->clk_cec)) {
if (PTR_ERR(cec->clk_cec) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Cannot get cec clock\n");
return PTR_ERR(cec->clk_cec);
}
if (IS_ERR(cec->clk_cec))
return dev_err_probe(&pdev->dev, PTR_ERR(cec->clk_cec),
"Cannot get cec clock\n");
ret = clk_prepare(cec->clk_cec);
if (ret) {

View File

@@ -301,21 +301,15 @@ static int ad5820_probe(struct i2c_client *client,
return -ENOMEM;
coil->vana = devm_regulator_get(&client->dev, "VANA");
if (IS_ERR(coil->vana)) {
ret = PTR_ERR(coil->vana);
if (ret != -EPROBE_DEFER)
dev_err(&client->dev, "could not get regulator for vana\n");
return ret;
}
if (IS_ERR(coil->vana))
return dev_err_probe(&client->dev, PTR_ERR(coil->vana),
"could not get regulator for vana\n");
coil->enable_gpio = devm_gpiod_get_optional(&client->dev, "enable",
GPIOD_OUT_LOW);
if (IS_ERR(coil->enable_gpio)) {
ret = PTR_ERR(coil->enable_gpio);
if (ret != -EPROBE_DEFER)
dev_err(&client->dev, "could not get enable gpio\n");
return ret;
}
if (IS_ERR(coil->enable_gpio))
return dev_err_probe(&client->dev, PTR_ERR(coil->enable_gpio),
"could not get enable gpio\n");
mutex_init(&coil->power_lock);

View File

@@ -2060,9 +2060,8 @@ static int imx274_probe(struct i2c_client *client)
imx274->reset_gpio = devm_gpiod_get_optional(dev, "reset",
GPIOD_OUT_HIGH);
if (IS_ERR(imx274->reset_gpio)) {
if (PTR_ERR(imx274->reset_gpio) != -EPROBE_DEFER)
dev_err(dev, "Reset GPIO not setup in DT");
ret = PTR_ERR(imx274->reset_gpio);
ret = dev_err_probe(dev, PTR_ERR(imx274->reset_gpio),
"Reset GPIO not setup in DT\n");
goto err_me;
}

View File

@@ -1891,12 +1891,9 @@ static int tc358743_probe_of(struct tc358743_state *state)
int ret;
refclk = devm_clk_get(dev, "refclk");
if (IS_ERR(refclk)) {
if (PTR_ERR(refclk) != -EPROBE_DEFER)
dev_err(dev, "failed to get refclk: %ld\n",
PTR_ERR(refclk));
return PTR_ERR(refclk);
}
if (IS_ERR(refclk))
return dev_err_probe(dev, PTR_ERR(refclk),
"failed to get refclk\n");
ep = of_graph_get_next_endpoint(dev->of_node, NULL);
if (!ep) {

View File

@@ -52,9 +52,8 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
comp->clk[i] = of_clk_get(node, i);
if (IS_ERR(comp->clk[i])) {
if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
dev_err(dev, "Failed to get clock\n");
ret = PTR_ERR(comp->clk[i]);
ret = dev_err_probe(dev, PTR_ERR(comp->clk[i]),
"Failed to get clock\n");
goto put_dev;
}

View File

@@ -1471,9 +1471,7 @@ static int fimc_md_probe(struct platform_device *pdev)
pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get pinctrl: %d\n", ret);
ret = dev_err_probe(dev, PTR_ERR(pinctrl), "Failed to get pinctrl\n");
goto err_clk;
}

View File

@@ -1946,12 +1946,9 @@ static int dcmi_probe(struct platform_device *pdev)
return -ENOMEM;
dcmi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(dcmi->rstc)) {
if (PTR_ERR(dcmi->rstc) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Could not get reset control\n");
return PTR_ERR(dcmi->rstc);
}
if (IS_ERR(dcmi->rstc))
return dev_err_probe(&pdev->dev, PTR_ERR(dcmi->rstc),
"Could not get reset control\n");
/* Get bus characteristics from devicetree */
np = of_graph_get_next_endpoint(np, NULL);
@@ -2003,20 +2000,14 @@ static int dcmi_probe(struct platform_device *pdev)
}
mclk = devm_clk_get(&pdev->dev, "mclk");
if (IS_ERR(mclk)) {
if (PTR_ERR(mclk) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Unable to get mclk\n");
return PTR_ERR(mclk);
}
if (IS_ERR(mclk))
return dev_err_probe(&pdev->dev, PTR_ERR(mclk),
"Unable to get mclk\n");
chan = dma_request_chan(&pdev->dev, "tx");
if (IS_ERR(chan)) {
ret = PTR_ERR(chan);
if (ret != -EPROBE_DEFER)
dev_err(&pdev->dev,
"Failed to request DMA channel: %d\n", ret);
return ret;
}
if (IS_ERR(chan))
return dev_err_probe(&pdev->dev, PTR_ERR(chan),
"Failed to request DMA channel\n");
dcmi->dma_max_burst = UINT_MAX;
ret = dma_get_slave_caps(chan, &caps);

View File

@@ -1884,8 +1884,7 @@ static int isp_initialize_modules(struct isp_device *isp)
ret = omap3isp_ccp2_init(isp);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
dev_err(isp->dev, "CCP2 initialization failed\n");
dev_err_probe(isp->dev, ret, "CCP2 initialization failed\n");
goto error_ccp2;
}

View File

@@ -976,11 +976,9 @@ static int xcsi2rxss_probe(struct platform_device *pdev)
/* Reset GPIO */
xcsi2rxss->rst_gpio = devm_gpiod_get_optional(dev, "video-reset",
GPIOD_OUT_HIGH);
if (IS_ERR(xcsi2rxss->rst_gpio)) {
if (PTR_ERR(xcsi2rxss->rst_gpio) != -EPROBE_DEFER)
dev_err(dev, "Video Reset GPIO not setup in DT");
return PTR_ERR(xcsi2rxss->rst_gpio);
}
if (IS_ERR(xcsi2rxss->rst_gpio))
return dev_err_probe(dev, PTR_ERR(xcsi2rxss->rst_gpio),
"Video Reset GPIO not setup in DT\n");
ret = xcsi2rxss_parse_of(xcsi2rxss);
if (ret < 0)

View File

@@ -74,13 +74,9 @@ static int gpio_ir_recv_probe(struct platform_device *pdev)
return -ENOMEM;
gpio_dev->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN);
if (IS_ERR(gpio_dev->gpiod)) {
rc = PTR_ERR(gpio_dev->gpiod);
/* Just try again if this happens */
if (rc != -EPROBE_DEFER)
dev_err(dev, "error getting gpio (%d)\n", rc);
return rc;
}
if (IS_ERR(gpio_dev->gpiod))
return dev_err_probe(dev, PTR_ERR(gpio_dev->gpiod),
"error getting gpio\n");
gpio_dev->irq = gpiod_to_irq(gpio_dev->gpiod);
if (gpio_dev->irq < 0)
return gpio_dev->irq;

View File

@@ -174,12 +174,9 @@ static int gpio_ir_tx_probe(struct platform_device *pdev)
return -ENOMEM;
gpio_ir->gpio = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
if (IS_ERR(gpio_ir->gpio)) {
if (PTR_ERR(gpio_ir->gpio) != -EPROBE_DEFER)
dev_err(&pdev->dev, "Failed to get gpio (%ld)\n",
PTR_ERR(gpio_ir->gpio));
return PTR_ERR(gpio_ir->gpio);
}
if (IS_ERR(gpio_ir->gpio))
return dev_err_probe(&pdev->dev, PTR_ERR(gpio_ir->gpio),
"Failed to get gpio\n");
rcdev->priv = gpio_ir;
rcdev->driver_name = DRIVER_NAME;

View File

@@ -231,13 +231,8 @@ static int ir_rx51_probe(struct platform_device *dev)
struct rc_dev *rcdev;
pwm = pwm_get(&dev->dev, NULL);
if (IS_ERR(pwm)) {
int err = PTR_ERR(pwm);
if (err != -EPROBE_DEFER)
dev_err(&dev->dev, "pwm_get failed: %d\n", err);
return err;
}
if (IS_ERR(pwm))
return dev_err_probe(&dev->dev, PTR_ERR(pwm), "pwm_get failed\n");
/* Use default, in case userspace does not set the carrier */
ir_rx51.freq = DIV_ROUND_CLOSEST_ULL(pwm_get_period(pwm), NSEC_PER_SEC);

View File

@@ -1470,6 +1470,40 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain,
uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
}
static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
struct uvc_fh *new_handle)
{
lockdep_assert_held(&handle->chain->ctrl_mutex);
if (new_handle) {
if (ctrl->handle)
dev_warn_ratelimited(&handle->stream->dev->udev->dev,
"UVC non compliance: Setting an async control with a pending operation.");
if (new_handle == ctrl->handle)
return;
if (ctrl->handle) {
WARN_ON(!ctrl->handle->pending_async_ctrls);
if (ctrl->handle->pending_async_ctrls)
ctrl->handle->pending_async_ctrls--;
}
ctrl->handle = new_handle;
handle->pending_async_ctrls++;
return;
}
/* Cannot clear the handle for a control not owned by us.*/
if (WARN_ON(ctrl->handle != handle))
return;
ctrl->handle = NULL;
if (WARN_ON(!handle->pending_async_ctrls))
return;
handle->pending_async_ctrls--;
}
void uvc_ctrl_status_event(struct uvc_video_chain *chain,
struct uvc_control *ctrl, const u8 *data)
{
@@ -1480,7 +1514,8 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
mutex_lock(&chain->ctrl_mutex);
handle = ctrl->handle;
ctrl->handle = NULL;
if (handle)
uvc_ctrl_set_handle(handle, ctrl, NULL);
list_for_each_entry(mapping, &ctrl->info.mappings, list) {
s32 value = __uvc_ctrl_get_value(mapping, data);
@@ -1700,7 +1735,10 @@ int uvc_ctrl_begin(struct uvc_video_chain *chain)
}
static int uvc_ctrl_commit_entity(struct uvc_device *dev,
struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
struct uvc_fh *handle,
struct uvc_entity *entity,
int rollback,
struct uvc_control **err_ctrl)
{
struct uvc_control *ctrl;
unsigned int i;
@@ -1748,6 +1786,10 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
*err_ctrl = ctrl;
return ret;
}
if (!rollback && handle &&
ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
uvc_ctrl_set_handle(handle, ctrl, handle);
}
return 0;
@@ -1784,18 +1826,20 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback,
/* Find the control. */
list_for_each_entry(entity, &chain->entities, chain) {
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
&err_ctrl);
if (ret < 0)
ret = uvc_ctrl_commit_entity(chain->dev, handle, entity,
rollback, &err_ctrl);
if (ret < 0) {
if (ctrls)
ctrls->error_idx =
uvc_ctrl_find_ctrl_idx(entity, ctrls,
err_ctrl);
goto done;
}
}
if (!rollback)
uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
done:
if (ret < 0 && ctrls)
ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
err_ctrl);
mutex_unlock(&chain->ctrl_mutex);
return ret;
}
@@ -1925,9 +1969,6 @@ int uvc_ctrl_set(struct uvc_fh *handle,
mapping->set(mapping, value,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
ctrl->handle = handle;
ctrl->dirty = 1;
ctrl->modified = 1;
return 0;
@@ -2100,7 +2141,7 @@ static int uvc_ctrl_init_xu_ctrl(struct uvc_device *dev,
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
struct uvc_xu_control_query *xqry)
{
struct uvc_entity *entity;
struct uvc_entity *entity, *iter;
struct uvc_control *ctrl;
unsigned int i;
bool found;
@@ -2110,16 +2151,16 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
int ret;
/* Find the extension unit. */
found = false;
list_for_each_entry(entity, &chain->entities, chain) {
if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
entity->id == xqry->unit) {
found = true;
entity = NULL;
list_for_each_entry(iter, &chain->entities, chain) {
if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT &&
iter->id == xqry->unit) {
entity = iter;
break;
}
}
if (!found) {
if (!entity) {
uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
xqry->unit);
return -ENOENT;
@@ -2256,7 +2297,7 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
ctrl->dirty = 1;
}
ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL);
if (ret < 0)
return ret;
}
@@ -2660,6 +2701,26 @@ int uvc_ctrl_init_device(struct uvc_device *dev)
return 0;
}
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
{
struct uvc_entity *entity;
guard(mutex)(&handle->chain->ctrl_mutex);
if (!handle->pending_async_ctrls)
return;
list_for_each_entry(entity, &handle->chain->dev->entities, list) {
for (unsigned int i = 0; i < entity->ncontrols; ++i) {
if (entity->controls[i].handle != handle)
continue;
uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
}
}
WARN_ON(handle->pending_async_ctrls);
}
/*
* Cleanup device controls.
*/

View File

@@ -1247,18 +1247,15 @@ static int uvc_gpio_parse(struct uvc_device *dev)
struct gpio_desc *gpio_privacy;
int irq;
gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy",
gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy",
GPIOD_IN);
if (IS_ERR_OR_NULL(gpio_privacy))
return PTR_ERR_OR_ZERO(gpio_privacy);
irq = gpiod_to_irq(gpio_privacy);
if (irq < 0) {
if (irq != EPROBE_DEFER)
dev_err(&dev->udev->dev,
"No IRQ for privacy GPIO (%d)\n", irq);
return irq;
}
if (irq < 0)
return dev_err_probe(&dev->intf->dev, irq,
"No IRQ for privacy GPIO\n");
unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
if (!unit)
@@ -1283,15 +1280,27 @@ static int uvc_gpio_parse(struct uvc_device *dev)
static int uvc_gpio_init_irq(struct uvc_device *dev)
{
struct uvc_entity *unit = dev->gpio_unit;
int ret;
if (!unit || unit->gpio.irq < 0)
return 0;
return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL,
uvc_gpio_irq,
IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING,
"uvc_privacy_gpio", dev);
ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq,
IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
IRQF_TRIGGER_RISING,
"uvc_privacy_gpio", dev);
unit->gpio.initialized = !ret;
return ret;
}
static void uvc_gpio_deinit(struct uvc_device *dev)
{
if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized)
return;
free_irq(dev->gpio_unit->gpio.irq, dev);
}
/* ------------------------------------------------------------------------
@@ -1885,6 +1894,8 @@ static void uvc_unregister_video(struct uvc_device *dev)
{
struct uvc_streaming *stream;
uvc_gpio_deinit(dev);
list_for_each_entry(stream, &dev->streams, list) {
/* Nothing to do here, continue. */
if (!video_is_registered(&stream->vdev))

View File

@@ -607,6 +607,8 @@ static int uvc_v4l2_release(struct file *file)
uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
uvc_ctrl_cleanup_fh(handle);
/* Only free resources if this is a privileged handle. */
if (uvc_has_privileges(handle))
uvc_queue_release(&stream->queue);

View File

@@ -227,6 +227,7 @@ struct uvc_entity {
u8 *bmControls;
struct gpio_desc *gpio_privacy;
int irq;
bool initialized;
} gpio;
};
@@ -330,7 +331,11 @@ struct uvc_video_chain {
struct uvc_entity *processing; /* Processing unit */
struct uvc_entity *selector; /* Selector unit */
struct mutex ctrl_mutex; /* Protects ctrl.info */
struct mutex ctrl_mutex; /*
* Protects ctrl.info,
* ctrl.handle and
* uvc_fh.pending_async_ctrls
*/
struct v4l2_prio_state prio; /* V4L2 priority state */
u32 caps; /* V4L2 chain-wide caps */
@@ -584,6 +589,7 @@ struct uvc_fh {
struct uvc_video_chain *chain;
struct uvc_streaming *stream;
enum uvc_handle_state state;
unsigned int pending_async_ctrls;
};
struct uvc_driver {
@@ -768,6 +774,8 @@ int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
struct uvc_xu_control_query *xqry);
void uvc_ctrl_cleanup_fh(struct uvc_fh *handle);
/* Utility functions */
struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
u8 epaddr);

View File

@@ -781,12 +781,18 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result)
case 0x1a: /* start stop unit in progress */
case 0x1b: /* sanitize in progress */
case 0x1d: /* configuration in progress */
case 0x24: /* depopulation in progress */
action = ACTION_DELAYED_RETRY;
break;
case 0x0a: /* ALUA state transition */
action = ACTION_DELAYED_REPREP;
break;
/*
* Depopulation might take many hours,
* thus it is not worthwhile to retry.
*/
case 0x24: /* depopulation in progress */
case 0x25: /* depopulation restore in progress */
fallthrough;
default:
action = ACTION_FAIL;
break;

View File

@@ -2127,6 +2127,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
break; /* unavailable */
if (sshdr.asc == 4 && sshdr.ascq == 0x1b)
break; /* sanitize in progress */
if (sshdr.asc == 4 && sshdr.ascq == 0x24)
break; /* depopulation in progress */
if (sshdr.asc == 4 && sshdr.ascq == 0x25)
break; /* depopulation restoration in progress */
/*
* Issue command to spin up drive when not ready
*/

View File

@@ -273,44 +273,44 @@ static int mtk_devapc_probe(struct platform_device *pdev)
return -EINVAL;
devapc_irq = irq_of_parse_and_map(node, 0);
if (!devapc_irq)
return -EINVAL;
if (!devapc_irq) {
ret = -EINVAL;
goto err;
}
ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock");
if (IS_ERR(ctx->infra_clk))
return -EINVAL;
if (clk_prepare_enable(ctx->infra_clk))
return -EINVAL;
ctx->infra_clk = devm_clk_get_enabled(&pdev->dev, "devapc-infra-clock");
if (IS_ERR(ctx->infra_clk)) {
ret = -EINVAL;
goto err;
}
ret = devm_request_irq(&pdev->dev, devapc_irq, devapc_violation_irq,
IRQF_TRIGGER_NONE, "devapc", ctx);
if (ret) {
clk_disable_unprepare(ctx->infra_clk);
return ret;
}
if (ret)
goto err;
platform_set_drvdata(pdev, ctx);
start_devapc(ctx);
return 0;
err:
iounmap(ctx->infra_base);
return ret;
}
static int mtk_devapc_remove(struct platform_device *pdev)
static void mtk_devapc_remove(struct platform_device *pdev)
{
struct mtk_devapc_context *ctx = platform_get_drvdata(pdev);
stop_devapc(ctx);
clk_disable_unprepare(ctx->infra_clk);
return 0;
iounmap(ctx->infra_base);
}
static struct platform_driver mtk_devapc_driver = {
.probe = mtk_devapc_probe,
.remove = mtk_devapc_remove,
.remove_new = mtk_devapc_remove,
.driver = {
.name = "mtk-devapc",
.of_match_table = mtk_devapc_dt_match,

View File

@@ -483,6 +483,8 @@ static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
sample_space = strm->fifo_sample_size;
ssifsr = rz_ssi_reg_readl(ssi, SSIFSR);
sample_space -= (ssifsr >> SSIFSR_TDC_SHIFT) & SSIFSR_TDC_MASK;
if (sample_space < 0)
return -EINVAL;
/* Only add full frames at a time */
while (frames_left && (sample_space >= runtime->channels)) {