mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 02:21:52 +09:00
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:
@@ -1753,6 +1753,7 @@
|
||||
resets = <&mmsys MT8183_MMSYS_SW0_RST_B_DISP_DSI0>;
|
||||
phys = <&mipi_tx0>;
|
||||
phy-names = "dphy";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mutex: mutex@14016000 {
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
Reference in New Issue
Block a user