Merge 83d09ad4b9 ("Merge tag 'for-linus' of git://github.com/openrisc/linux") into android-mainline

Steps on the way to 5.11-rc5

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: If1f5550483e27451775c61f3fbc912903a56c4b2
This commit is contained in:
Greg Kroah-Hartman
2021-01-22 14:08:09 +01:00
61 changed files with 645 additions and 443 deletions

View File

@@ -14517,10 +14517,18 @@ S: Supported
F: drivers/crypto/qat/
QCOM AUDIO (ASoC) DRIVERS
M: Patrick Lai <plai@codeaurora.org>
M: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
M: Banajit Goswami <bgoswami@codeaurora.org>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/codecs/lpass-va-macro.c
F: sound/soc/codecs/lpass-wsa-macro.*
F: sound/soc/codecs/msm8916-wcd-analog.c
F: sound/soc/codecs/msm8916-wcd-digital.c
F: sound/soc/codecs/wcd9335.*
F: sound/soc/codecs/wcd934x.c
F: sound/soc/codecs/wcd-clsh-v2.*
F: sound/soc/codecs/wsa881x.c
F: sound/soc/qcom/
QCOM IPA DRIVER
@@ -16972,7 +16980,7 @@ M: Olivier Moysan <olivier.moysan@st.com>
M: Arnaud Pouliquen <arnaud.pouliquen@st.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/sound/st,stm32-*.txt
F: Documentation/devicetree/bindings/iio/adc/st,stm32-*.yaml
F: sound/soc/stm/
STM32 TIMER/LPTIMER DRIVERS

View File

@@ -31,7 +31,7 @@
void __iomem *ioremap(phys_addr_t offset, unsigned long size);
#define iounmap iounmap
extern void iounmap(void *addr);
extern void iounmap(void __iomem *addr);
#include <asm-generic/io.h>

View File

@@ -77,7 +77,7 @@ void __iomem *__ref ioremap(phys_addr_t addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap);
void iounmap(void *addr)
void iounmap(void __iomem *addr)
{
/* If the page is from the fixmap pool then we just clear out
* the fixmap mapping.

View File

@@ -586,6 +586,8 @@ static int acpi_get_device_data(acpi_handle handle, struct acpi_device **device,
if (!device)
return -EINVAL;
*device = NULL;
status = acpi_get_data_full(handle, acpi_scan_drop_device,
(void **)device, callback);
if (ACPI_FAILURE(status) || !*device) {

View File

@@ -521,7 +521,8 @@ config GPIO_SAMA5D2_PIOBU
config GPIO_SIFIVE
bool "SiFive GPIO support"
depends on OF_GPIO && IRQ_DOMAIN_HIERARCHY
depends on OF_GPIO
select IRQ_DOMAIN_HIERARCHY
select GPIO_GENERIC
select GPIOLIB_IRQCHIP
select REGMAP_MMIO
@@ -597,6 +598,8 @@ config GPIO_TEGRA
default ARCH_TEGRA
depends on ARCH_TEGRA || COMPILE_TEST
depends on OF_GPIO
select GPIOLIB_IRQCHIP
select IRQ_DOMAIN_HIERARCHY
help
Say yes here to support GPIO pins on NVIDIA Tegra SoCs.

View File

@@ -676,20 +676,17 @@ static void mvebu_pwm_get_state(struct pwm_chip *chip,
else
state->duty_cycle = 1;
val = (unsigned long long) u; /* on duration */
regmap_read(mvpwm->regs, mvebu_pwmreg_blink_off_duration(mvpwm), &u);
val = (unsigned long long) u * NSEC_PER_SEC;
val += (unsigned long long) u; /* period = on + off duration */
val *= NSEC_PER_SEC;
do_div(val, mvpwm->clk_rate);
if (val < state->duty_cycle) {
if (val > UINT_MAX)
state->period = UINT_MAX;
else if (val)
state->period = val;
else
state->period = 1;
} else {
val -= state->duty_cycle;
if (val > UINT_MAX)
state->period = UINT_MAX;
else if (val)
state->period = val;
else
state->period = 1;
}
regmap_read(mvchip->regs, GPIO_BLINK_EN_OFF + mvchip->offset, &u);
if (u)

View File

@@ -1979,6 +1979,21 @@ struct gpio_chardev_data {
#endif
};
static int chipinfo_get(struct gpio_chardev_data *cdev, void __user *ip)
{
struct gpio_device *gdev = cdev->gdev;
struct gpiochip_info chipinfo;
memset(&chipinfo, 0, sizeof(chipinfo));
strscpy(chipinfo.name, dev_name(&gdev->dev), sizeof(chipinfo.name));
strscpy(chipinfo.label, gdev->label, sizeof(chipinfo.label));
chipinfo.lines = gdev->ngpio;
if (copy_to_user(ip, &chipinfo, sizeof(chipinfo)))
return -EFAULT;
return 0;
}
#ifdef CONFIG_GPIO_CDEV_V1
/*
* returns 0 if the versions match, else the previously selected ABI version
@@ -1993,6 +2008,41 @@ static int lineinfo_ensure_abi_version(struct gpio_chardev_data *cdata,
return abiv;
}
static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip,
bool watch)
{
struct gpio_desc *desc;
struct gpioline_info lineinfo;
struct gpio_v2_line_info lineinfo_v2;
if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
return -EFAULT;
/* this doubles as a range check on line_offset */
desc = gpiochip_get_desc(cdev->gdev->chip, lineinfo.line_offset);
if (IS_ERR(desc))
return PTR_ERR(desc);
if (watch) {
if (lineinfo_ensure_abi_version(cdev, 1))
return -EPERM;
if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines))
return -EBUSY;
}
gpio_desc_to_lineinfo(desc, &lineinfo_v2);
gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
if (watch)
clear_bit(lineinfo.line_offset, cdev->watched_lines);
return -EFAULT;
}
return 0;
}
#endif
static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
@@ -2030,6 +2080,22 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip,
return 0;
}
static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
{
__u32 offset;
if (copy_from_user(&offset, ip, sizeof(offset)))
return -EFAULT;
if (offset >= cdev->gdev->ngpio)
return -EINVAL;
if (!test_and_clear_bit(offset, cdev->watched_lines))
return -EBUSY;
return 0;
}
/*
* gpio_ioctl() - ioctl handler for the GPIO chardev
*/
@@ -2037,80 +2103,24 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct gpio_chardev_data *cdev = file->private_data;
struct gpio_device *gdev = cdev->gdev;
struct gpio_chip *gc = gdev->chip;
void __user *ip = (void __user *)arg;
__u32 offset;
/* We fail any subsequent ioctl():s when the chip is gone */
if (!gc)
if (!gdev->chip)
return -ENODEV;
/* Fill in the struct and pass to userspace */
if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
struct gpiochip_info chipinfo;
memset(&chipinfo, 0, sizeof(chipinfo));
strscpy(chipinfo.name, dev_name(&gdev->dev),
sizeof(chipinfo.name));
strscpy(chipinfo.label, gdev->label,
sizeof(chipinfo.label));
chipinfo.lines = gdev->ngpio;
if (copy_to_user(ip, &chipinfo, sizeof(chipinfo)))
return -EFAULT;
return 0;
return chipinfo_get(cdev, ip);
#ifdef CONFIG_GPIO_CDEV_V1
} else if (cmd == GPIO_GET_LINEINFO_IOCTL) {
struct gpio_desc *desc;
struct gpioline_info lineinfo;
struct gpio_v2_line_info lineinfo_v2;
if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
return -EFAULT;
/* this doubles as a range check on line_offset */
desc = gpiochip_get_desc(gc, lineinfo.line_offset);
if (IS_ERR(desc))
return PTR_ERR(desc);
gpio_desc_to_lineinfo(desc, &lineinfo_v2);
gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo)))
return -EFAULT;
return 0;
} else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) {
return linehandle_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEEVENT_IOCTL) {
return lineevent_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
struct gpio_desc *desc;
struct gpioline_info lineinfo;
struct gpio_v2_line_info lineinfo_v2;
if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
return -EFAULT;
/* this doubles as a range check on line_offset */
desc = gpiochip_get_desc(gc, lineinfo.line_offset);
if (IS_ERR(desc))
return PTR_ERR(desc);
if (lineinfo_ensure_abi_version(cdev, 1))
return -EPERM;
if (test_and_set_bit(lineinfo.line_offset, cdev->watched_lines))
return -EBUSY;
gpio_desc_to_lineinfo(desc, &lineinfo_v2);
gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
clear_bit(lineinfo.line_offset, cdev->watched_lines);
return -EFAULT;
}
return 0;
} else if (cmd == GPIO_GET_LINEINFO_IOCTL ||
cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) {
return lineinfo_get_v1(cdev, ip,
cmd == GPIO_GET_LINEINFO_WATCH_IOCTL);
#endif /* CONFIG_GPIO_CDEV_V1 */
} else if (cmd == GPIO_V2_GET_LINEINFO_IOCTL ||
cmd == GPIO_V2_GET_LINEINFO_WATCH_IOCTL) {
@@ -2119,16 +2129,7 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} else if (cmd == GPIO_V2_GET_LINE_IOCTL) {
return linereq_create(gdev, ip);
} else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) {
if (copy_from_user(&offset, ip, sizeof(offset)))
return -EFAULT;
if (offset >= cdev->gdev->ngpio)
return -EINVAL;
if (!test_and_clear_bit(offset, cdev->watched_lines))
return -EBUSY;
return 0;
return lineinfo_unwatch(cdev, ip);
}
return -EINVAL;
}

View File

@@ -1489,6 +1489,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gc,
type = IRQ_TYPE_NONE;
}
if (gc->to_irq)
chip_warn(gc, "to_irq is redefined in %s and you shouldn't rely on it\n", __func__);
gc->to_irq = gpiochip_to_irq;
gc->irq.default_type = type;
gc->irq.lock_key = lock_key;

View File

@@ -81,7 +81,6 @@ MODULE_FIRMWARE("amdgpu/navi10_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navi14_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/navi12_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/vangogh_gpu_info.bin");
MODULE_FIRMWARE("amdgpu/green_sardine_gpu_info.bin");
#define AMDGPU_RESUME_MS 2000

View File

@@ -119,6 +119,8 @@
#define mmVGT_ESGS_RING_SIZE_Vangogh_BASE_IDX 1
#define mmSPI_CONFIG_CNTL_Vangogh 0x2440
#define mmSPI_CONFIG_CNTL_Vangogh_BASE_IDX 1
#define mmGCR_GENERAL_CNTL_Vangogh 0x1580
#define mmGCR_GENERAL_CNTL_Vangogh_BASE_IDX 0
#define mmCP_HYP_PFP_UCODE_ADDR 0x5814
#define mmCP_HYP_PFP_UCODE_ADDR_BASE_IDX 1
@@ -3244,7 +3246,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3_vangogh[] =
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x00800000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_EXCEPTION_CONTROL, 0x7fff0f1f, 0x00b80000),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1807ff, 0x00000142),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff1ffff, 0x00000500),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL_Vangogh, 0x1ff1ffff, 0x00000500),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0x000000ff, 0x000000e4),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_0, 0x77777777, 0x32103210),
SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL2_PIPE_STEER_1, 0x77777777, 0x32103210),

View File

@@ -491,12 +491,11 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
{
uint32_t def, data, def1, data1;
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_MGCG)) {
data |= MM_ATC_L2_MISC_CG__ENABLE_MASK;
data &= ~MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK;
data1 &= ~(DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
@@ -505,8 +504,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK);
} else {
data &= ~MM_ATC_L2_MISC_CG__ENABLE_MASK;
data |= MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK;
data1 |= (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
@@ -516,7 +514,7 @@ mmhub_v2_3_update_medium_grain_clock_gating(struct amdgpu_device *adev,
}
if (def != data)
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data);
if (def1 != data1)
WREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2, data1);
}
@@ -525,17 +523,44 @@ static void
mmhub_v2_3_update_medium_grain_light_sleep(struct amdgpu_device *adev,
bool enable)
{
uint32_t def, data;
uint32_t def, data, def1, data1, def2, data2;
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
def = data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
def1 = data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL);
def2 = data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL);
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS))
data |= MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
else
data &= ~MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK;
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_MC_LS)) {
data &= ~MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK;
data1 &= !(DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
data2 &= !(DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
} else {
data |= MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK;
data1 |= (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
data2 |= (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK);
}
if (def != data)
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG, data);
WREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL, data);
if (def1 != data1)
WREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL, data1);
if (def2 != data2)
WREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL, data2);
}
static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev,
@@ -554,26 +579,39 @@ static int mmhub_v2_3_set_clockgating(struct amdgpu_device *adev,
static void mmhub_v2_3_get_clockgating(struct amdgpu_device *adev, u32 *flags)
{
int data, data1;
int data, data1, data2, data3;
if (amdgpu_sriov_vf(adev))
*flags = 0;
data = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_MISC_CG);
data1 = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
data = RREG32_SOC15(MMHUB, 0, mmDAGB0_CNTL_MISC2);
data1 = RREG32_SOC15(MMHUB, 0, mmMM_ATC_L2_CGTT_CLK_CTRL);
data2 = RREG32_SOC15(MMHUB, 0, mmDAGB0_WR_CGTT_CLK_CTRL);
data3 = RREG32_SOC15(MMHUB, 0, mmDAGB0_RD_CGTT_CLK_CTRL);
/* AMD_CG_SUPPORT_MC_MGCG */
if ((data & MM_ATC_L2_MISC_CG__ENABLE_MASK) &&
!(data1 & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
if (!(data & (DAGB0_CNTL_MISC2__DISABLE_WRREQ_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_WRRET_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_RDREQ_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_RDRET_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_TLBWR_CG_MASK |
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK)))
*flags |= AMD_CG_SUPPORT_MC_MGCG;
DAGB0_CNTL_MISC2__DISABLE_TLBRD_CG_MASK))
&& !(data1 & MM_ATC_L2_CGTT_CLK_CTRL__SOFT_OVERRIDE_MASK)) {
*flags |= AMD_CG_SUPPORT_MC_MGCG;
}
/* AMD_CG_SUPPORT_MC_LS */
if (data & MM_ATC_L2_MISC_CG__MEM_LS_ENABLE_MASK)
if (!(data1 & MM_ATC_L2_CGTT_CLK_CTRL__MGLS_OVERRIDE_MASK)
&& !(data2 & (DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_WR_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK))
&& !(data3 & (DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_WRITE_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_READ_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_RETURN_MASK |
DAGB0_RD_CGTT_CLK_CTRL__LS_OVERRIDE_REGISTER_MASK)))
*flags |= AMD_CG_SUPPORT_MC_LS;
}

View File

@@ -251,6 +251,7 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
struct dmcu *dmcu = clk_mgr_base->ctx->dc->res_pool->dmcu;
bool force_reset = false;
bool update_uclk = false;
bool p_state_change_support;
if (dc->work_arounds.skip_clock_update || !clk_mgr->smu_present)
return;
@@ -291,8 +292,9 @@ static void dcn3_update_clocks(struct clk_mgr *clk_mgr_base,
clk_mgr_base->clks.socclk_khz = new_clocks->socclk_khz;
clk_mgr_base->clks.prev_p_state_change_support = clk_mgr_base->clks.p_state_change_support;
if (should_update_pstate_support(safe_to_lower, new_clocks->p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
clk_mgr_base->clks.p_state_change_support = new_clocks->p_state_change_support;
p_state_change_support = new_clocks->p_state_change_support || (display_count == 0);
if (should_update_pstate_support(safe_to_lower, p_state_change_support, clk_mgr_base->clks.p_state_change_support)) {
clk_mgr_base->clks.p_state_change_support = p_state_change_support;
/* to disable P-State switching, set UCLK min = max */
if (!clk_mgr_base->clks.p_state_change_support)

View File

@@ -2399,6 +2399,9 @@ static bool decide_dp_link_settings(struct dc_link *link, struct dc_link_setting
initial_link_setting;
uint32_t link_bw;
if (req_bw > dc_link_bandwidth_kbps(link, &link->verified_link_cap))
return false;
/* search for the minimum link setting that:
* 1. is supported according to the link training result
* 2. could support the b/w requested by the timing
@@ -3045,14 +3048,14 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
for (i = 0; i < MAX_PIPES; i++) {
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
pipe_ctx->stream->link == link)
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
core_link_disable_stream(pipe_ctx);
}
for (i = 0; i < MAX_PIPES; i++) {
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
if (pipe_ctx && pipe_ctx->stream && !pipe_ctx->stream->dpms_off &&
pipe_ctx->stream->link == link)
pipe_ctx->stream->link == link && !pipe_ctx->prev_odm_pipe)
core_link_enable_stream(link->dc->current_state, pipe_ctx);
}

View File

@@ -647,8 +647,13 @@ static void power_on_plane(
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
hws->funcs.dpp_pg_control(hws, plane_id, true);
hws->funcs.hubp_pg_control(hws, plane_id, true);
if (hws->funcs.dpp_pg_control)
hws->funcs.dpp_pg_control(hws, plane_id, true);
if (hws->funcs.hubp_pg_control)
hws->funcs.hubp_pg_control(hws, plane_id, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
DC_LOG_DEBUG(
@@ -1082,8 +1087,13 @@ void dcn10_plane_atomic_power_down(struct dc *dc,
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
hws->funcs.dpp_pg_control(hws, dpp->inst, false);
hws->funcs.hubp_pg_control(hws, hubp->inst, false);
if (hws->funcs.dpp_pg_control)
hws->funcs.dpp_pg_control(hws, dpp->inst, false);
if (hws->funcs.hubp_pg_control)
hws->funcs.hubp_pg_control(hws, hubp->inst, false);
dpp->funcs->dpp_reset(dpp);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);

View File

@@ -1062,8 +1062,13 @@ static void dcn20_power_on_plane(
if (REG(DC_IP_REQUEST_CNTL)) {
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 1);
dcn20_dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
dcn20_hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
if (hws->funcs.dpp_pg_control)
hws->funcs.dpp_pg_control(hws, pipe_ctx->plane_res.dpp->inst, true);
if (hws->funcs.hubp_pg_control)
hws->funcs.hubp_pg_control(hws, pipe_ctx->plane_res.hubp->inst, true);
REG_SET(DC_IP_REQUEST_CNTL, 0,
IP_REQUEST_EN, 0);
DC_LOG_DEBUG(

View File

@@ -2517,8 +2517,7 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
* if this primary pipe has a bottom pipe in prev. state
* and if the bottom pipe is still available (which it should be),
* pick that pipe as secondary
* Same logic applies for ODM pipes. Since mpo is not allowed with odm
* check in else case.
* Same logic applies for ODM pipes
*/
if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe) {
preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].bottom_pipe->pipe_idx;
@@ -2526,7 +2525,9 @@ struct pipe_ctx *dcn20_find_secondary_pipe(struct dc *dc,
secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];
secondary_pipe->pipe_idx = preferred_pipe_idx;
}
} else if (dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
}
if (secondary_pipe == NULL &&
dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe) {
preferred_pipe_idx = dc->current_state->res_ctx.pipe_ctx[primary_pipe->pipe_idx].next_odm_pipe->pipe_idx;
if (res_ctx->pipe_ctx[preferred_pipe_idx].stream == NULL) {
secondary_pipe = &res_ctx->pipe_ctx[preferred_pipe_idx];

View File

@@ -296,7 +296,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
.num_banks = 8,
.num_chans = 4,
.vmm_page_size_bytes = 4096,
.dram_clock_change_latency_us = 23.84,
.dram_clock_change_latency_us = 11.72,
.return_bus_width_bytes = 64,
.dispclk_dppclk_vco_speed_mhz = 3600,
.xfc_bus_transport_time_us = 4,

View File

@@ -1121,7 +1121,7 @@ static ssize_t renoir_get_gpu_metrics(struct smu_context *smu,
static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state)
{
return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GpuChangeState, state, NULL);
return 0;
}
static const struct pptable_funcs renoir_ppt_funcs = {

View File

@@ -3021,7 +3021,7 @@ int drm_atomic_helper_set_config(struct drm_mode_set *set,
ret = handle_conflicting_encoders(state, true);
if (ret)
return ret;
goto fail;
ret = drm_atomic_commit(state);

View File

@@ -387,9 +387,16 @@ static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
if (gbo->vmap_use_count > 0)
goto out;
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret)
return ret;
/*
* VRAM helpers unmap the BO only on demand. So the previous
* page mapping might still be around. Only vmap if the there's
* no mapping present.
*/
if (dma_buf_map_is_null(&gbo->map)) {
ret = ttm_bo_vmap(&gbo->bo, &gbo->map);
if (ret)
return ret;
}
out:
++gbo->vmap_use_count;
@@ -577,6 +584,7 @@ static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
return;
ttm_bo_vunmap(bo, &gbo->map);
dma_buf_map_clear(&gbo->map); /* explicitly clear mapping for next vmap call */
}
static int drm_gem_vram_bo_driver_move(struct drm_gem_vram_object *gbo,

View File

@@ -388,19 +388,18 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
return -ENOENT;
*fence = drm_syncobj_fence_get(syncobj);
drm_syncobj_put(syncobj);
if (*fence) {
ret = dma_fence_chain_find_seqno(fence, point);
if (!ret)
return 0;
goto out;
dma_fence_put(*fence);
} else {
ret = -EINVAL;
}
if (!(flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT))
return ret;
goto out;
memset(&wait, 0, sizeof(wait));
wait.task = current;
@@ -432,6 +431,9 @@ int drm_syncobj_find_fence(struct drm_file *file_private,
if (wait.node.next)
drm_syncobj_remove_wait(syncobj, &wait);
out:
drm_syncobj_put(syncobj);
return ret;
}
EXPORT_SYMBOL(drm_syncobj_find_fence);

View File

@@ -3725,7 +3725,7 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_ddi_init_dp_buf_reg(encoder, crtc_state);
if (!is_mst)
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
intel_dp_configure_protocol_converter(intel_dp, crtc_state);
intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
true);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state);

View File

@@ -4014,7 +4014,8 @@ static void intel_dp_enable_port(struct intel_dp *intel_dp,
intel_de_posting_read(dev_priv, intel_dp->output_reg);
}
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 tmp;
@@ -4033,8 +4034,8 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp)
drm_dbg_kms(&i915->drm, "Failed to set protocol converter HDMI mode to %s\n",
enableddisabled(intel_dp->has_hdmi_sink));
tmp = intel_dp->dfp.ycbcr_444_to_420 ?
DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
tmp = crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 &&
intel_dp->dfp.ycbcr_444_to_420 ? DP_CONVERSION_TO_YCBCR420_ENABLE : 0;
if (drm_dp_dpcd_writeb(&intel_dp->aux,
DP_PROTOCOL_CONVERTER_CONTROL_1, tmp) != 1)
@@ -4088,7 +4089,7 @@ static void intel_enable_dp(struct intel_atomic_state *state,
}
intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp);
intel_dp_configure_protocol_converter(intel_dp, pipe_config);
intel_dp_start_link_train(intel_dp, pipe_config);
intel_dp_stop_link_train(intel_dp, pipe_config);

View File

@@ -51,7 +51,8 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
int intel_dp_retrain_link(struct intel_encoder *encoder,
struct drm_modeset_acquire_ctx *ctx);
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state);
void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
bool enable);

View File

@@ -2210,6 +2210,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
if (content_protection_type_changed) {
mutex_lock(&hdcp->mutex);
hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
drm_connector_get(&connector->base);
schedule_work(&hdcp->prop_work);
mutex_unlock(&hdcp->mutex);
}
@@ -2221,6 +2222,14 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
desired_and_not_enabled =
hdcp->value != DRM_MODE_CONTENT_PROTECTION_ENABLED;
mutex_unlock(&hdcp->mutex);
/*
* If HDCP already ENABLED and CP property is DESIRED, schedule
* prop_work to update correct CP property to user space.
*/
if (!desired_and_not_enabled && !content_protection_type_changed) {
drm_connector_get(&connector->base);
schedule_work(&hdcp->prop_work);
}
}
if (desired_and_not_enabled || content_protection_type_changed)

View File

@@ -134,11 +134,6 @@ static bool remove_signaling_context(struct intel_breadcrumbs *b,
return true;
}
static inline bool __request_completed(const struct i915_request *rq)
{
return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
}
__maybe_unused static bool
check_signal_order(struct intel_context *ce, struct i915_request *rq)
{
@@ -257,7 +252,7 @@ static void signal_irq_work(struct irq_work *work)
list_for_each_entry_rcu(rq, &ce->signals, signal_link) {
bool release;
if (!__request_completed(rq))
if (!__i915_request_is_complete(rq))
break;
if (!test_and_clear_bit(I915_FENCE_FLAG_SIGNAL,
@@ -379,7 +374,7 @@ static void insert_breadcrumb(struct i915_request *rq)
* straight onto a signaled list, and queue the irq worker for
* its signal completion.
*/
if (__request_completed(rq)) {
if (__i915_request_is_complete(rq)) {
if (__signal_request(rq) &&
llist_add(&rq->signal_node, &b->signaled_requests))
irq_work_queue(&b->irq_work);

View File

@@ -3988,6 +3988,9 @@ err:
static void lrc_destroy_wa_ctx(struct intel_engine_cs *engine)
{
i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0);
/* Called on error unwind, clear all flags to prevent further use */
memset(&engine->wa_ctx, 0, sizeof(engine->wa_ctx));
}
typedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch);

View File

@@ -126,6 +126,10 @@ static void __rcu_cacheline_free(struct rcu_head *rcu)
struct intel_timeline_cacheline *cl =
container_of(rcu, typeof(*cl), rcu);
/* Must wait until after all *rq->hwsp are complete before removing */
i915_gem_object_unpin_map(cl->hwsp->vma->obj);
__idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
i915_active_fini(&cl->active);
kfree(cl);
}
@@ -133,11 +137,6 @@ static void __rcu_cacheline_free(struct rcu_head *rcu)
static void __idle_cacheline_free(struct intel_timeline_cacheline *cl)
{
GEM_BUG_ON(!i915_active_is_idle(&cl->active));
i915_gem_object_unpin_map(cl->hwsp->vma->obj);
i915_vma_put(cl->hwsp->vma);
__idle_hwsp_free(cl->hwsp, ptr_unmask_bits(cl->vaddr, CACHELINE_BITS));
call_rcu(&cl->rcu, __rcu_cacheline_free);
}
@@ -179,7 +178,6 @@ cacheline_alloc(struct intel_timeline_hwsp *hwsp, unsigned int cacheline)
return ERR_CAST(vaddr);
}
i915_vma_get(hwsp->vma);
cl->hwsp = hwsp;
cl->vaddr = page_pack_bits(vaddr, cacheline);

View File

@@ -184,13 +184,24 @@ static u64 get_rc6(struct intel_gt *gt)
return val;
}
static void init_rc6(struct i915_pmu *pmu)
{
struct drm_i915_private *i915 = container_of(pmu, typeof(*i915), pmu);
intel_wakeref_t wakeref;
with_intel_runtime_pm(i915->gt.uncore->rpm, wakeref) {
pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur =
pmu->sample[__I915_SAMPLE_RC6].cur;
pmu->sleep_last = ktime_get();
}
}
static void park_rc6(struct drm_i915_private *i915)
{
struct i915_pmu *pmu = &i915->pmu;
if (pmu->enable & config_enabled_mask(I915_PMU_RC6_RESIDENCY))
pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
pmu->sleep_last = ktime_get();
}
@@ -201,6 +212,7 @@ static u64 get_rc6(struct intel_gt *gt)
return __get_rc6(gt);
}
static void init_rc6(struct i915_pmu *pmu) { }
static void park_rc6(struct drm_i915_private *i915) {}
#endif
@@ -612,10 +624,8 @@ static void i915_pmu_enable(struct perf_event *event)
container_of(event->pmu, typeof(*i915), pmu.base);
unsigned int bit = event_enabled_bit(event);
struct i915_pmu *pmu = &i915->pmu;
intel_wakeref_t wakeref;
unsigned long flags;
wakeref = intel_runtime_pm_get(&i915->runtime_pm);
spin_lock_irqsave(&pmu->lock, flags);
/*
@@ -626,13 +636,6 @@ static void i915_pmu_enable(struct perf_event *event)
GEM_BUG_ON(bit >= ARRAY_SIZE(pmu->enable_count));
GEM_BUG_ON(pmu->enable_count[bit] == ~0);
if (pmu->enable_count[bit] == 0 &&
config_enabled_mask(I915_PMU_RC6_RESIDENCY) & BIT_ULL(bit)) {
pmu->sample[__I915_SAMPLE_RC6_LAST_REPORTED].cur = 0;
pmu->sample[__I915_SAMPLE_RC6].cur = __get_rc6(&i915->gt);
pmu->sleep_last = ktime_get();
}
pmu->enable |= BIT_ULL(bit);
pmu->enable_count[bit]++;
@@ -673,8 +676,6 @@ static void i915_pmu_enable(struct perf_event *event)
* an existing non-zero value.
*/
local64_set(&event->hw.prev_count, __i915_pmu_event_read(event));
intel_runtime_pm_put(&i915->runtime_pm, wakeref);
}
static void i915_pmu_disable(struct perf_event *event)
@@ -1130,6 +1131,7 @@ void i915_pmu_register(struct drm_i915_private *i915)
hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pmu->timer.function = i915_sample;
pmu->cpuhp.cpu = -1;
init_rc6(pmu);
if (!is_igp(i915)) {
pmu->name = kasprintf(GFP_KERNEL,

View File

@@ -434,7 +434,7 @@ static inline u32 hwsp_seqno(const struct i915_request *rq)
static inline bool __i915_request_has_started(const struct i915_request *rq)
{
return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno - 1);
return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno - 1);
}
/**
@@ -465,11 +465,19 @@ static inline bool __i915_request_has_started(const struct i915_request *rq)
*/
static inline bool i915_request_started(const struct i915_request *rq)
{
bool result;
if (i915_request_signaled(rq))
return true;
/* Remember: started but may have since been preempted! */
return __i915_request_has_started(rq);
result = true;
rcu_read_lock(); /* the HWSP may be freed at runtime */
if (likely(!i915_request_signaled(rq)))
/* Remember: started but may have since been preempted! */
result = __i915_request_has_started(rq);
rcu_read_unlock();
return result;
}
/**
@@ -482,10 +490,16 @@ static inline bool i915_request_started(const struct i915_request *rq)
*/
static inline bool i915_request_is_running(const struct i915_request *rq)
{
bool result;
if (!i915_request_is_active(rq))
return false;
return __i915_request_has_started(rq);
rcu_read_lock();
result = __i915_request_has_started(rq) && i915_request_is_active(rq);
rcu_read_unlock();
return result;
}
/**
@@ -509,12 +523,25 @@ static inline bool i915_request_is_ready(const struct i915_request *rq)
return !list_empty(&rq->sched.link);
}
static inline bool __i915_request_is_complete(const struct i915_request *rq)
{
return i915_seqno_passed(__hwsp_seqno(rq), rq->fence.seqno);
}
static inline bool i915_request_completed(const struct i915_request *rq)
{
bool result;
if (i915_request_signaled(rq))
return true;
return i915_seqno_passed(hwsp_seqno(rq), rq->fence.seqno);
result = true;
rcu_read_lock(); /* the HWSP may be freed at runtime */
if (likely(!i915_request_signaled(rq)))
result = __i915_request_is_complete(rq);
rcu_read_unlock();
return result;
}
static inline void i915_request_mark_complete(struct i915_request *rq)

View File

@@ -79,12 +79,13 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags,
struct page *p;
void *vaddr;
if (order) {
gfp_flags |= GFP_TRANSHUGE_LIGHT | __GFP_NORETRY |
/* Don't set the __GFP_COMP flag for higher order allocations.
* Mapping pages directly into an userspace process and calling
* put_page() on a TTM allocated page is illegal.
*/
if (order)
gfp_flags |= __GFP_NOMEMALLOC | __GFP_NORETRY |
__GFP_KSWAPD_RECLAIM;
gfp_flags &= ~__GFP_MOVABLE;
gfp_flags &= ~__GFP_COMP;
}
if (!pool->use_dma_alloc) {
p = alloc_pages(gfp_flags, order);

View File

@@ -1267,6 +1267,7 @@ static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
card->dai_link = dai_link;
card->num_links = 1;
card->name = vc4_hdmi->variant->card_name;
card->driver_name = "vc4-hdmi";
card->dev = dev;
card->owner = THIS_MODULE;

View File

@@ -347,7 +347,7 @@ FUNC_GROUP_DECL(RMII4, F24, E23, E24, E25, C25, C24, B26, B25, B24);
#define D22 40
SIG_EXPR_LIST_DECL_SESG(D22, SD1CLK, SD1, SIG_DESC_SET(SCU414, 8));
SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU414, 8));
SIG_EXPR_LIST_DECL_SEMG(D22, PWM8, PWM8G0, PWM8, SIG_DESC_SET(SCU4B4, 8));
PIN_DECL_2(D22, GPIOF0, SD1CLK, PWM8);
GROUP_DECL(PWM8G0, D22);

View File

@@ -920,6 +920,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw,
err = hw->soc->bias_set(hw, desc, pullup);
if (err)
return err;
} else if (hw->soc->bias_set_combo) {
err = hw->soc->bias_set_combo(hw, desc, pullup, arg);
if (err)
return err;
} else {
return -ENOTSUPP;
}

View File

@@ -949,7 +949,6 @@ static void nmk_gpio_dbg_show_one(struct seq_file *s,
} else {
int irq = chip->to_irq(chip, offset);
const int pullidx = pull ? 1 : 0;
bool wake;
int val;
static const char * const pulls[] = {
"none ",

View File

@@ -37,11 +37,11 @@
#define JZ4740_GPIO_TRIG 0x70
#define JZ4740_GPIO_FLAG 0x80
#define JZ4760_GPIO_INT 0x10
#define JZ4760_GPIO_PAT1 0x30
#define JZ4760_GPIO_PAT0 0x40
#define JZ4760_GPIO_FLAG 0x50
#define JZ4760_GPIO_PEN 0x70
#define JZ4770_GPIO_INT 0x10
#define JZ4770_GPIO_PAT1 0x30
#define JZ4770_GPIO_PAT0 0x40
#define JZ4770_GPIO_FLAG 0x50
#define JZ4770_GPIO_PEN 0x70
#define X1830_GPIO_PEL 0x110
#define X1830_GPIO_PEH 0x120
@@ -1688,8 +1688,8 @@ static inline bool ingenic_gpio_get_value(struct ingenic_gpio_chip *jzgc,
static void ingenic_gpio_set_value(struct ingenic_gpio_chip *jzgc,
u8 offset, int value)
{
if (jzgc->jzpc->info->version >= ID_JZ4760)
ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_PAT0, offset, !!value);
if (jzgc->jzpc->info->version >= ID_JZ4770)
ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_PAT0, offset, !!value);
else
ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, offset, !!value);
}
@@ -1718,9 +1718,9 @@ static void irq_set_type(struct ingenic_gpio_chip *jzgc,
break;
}
if (jzgc->jzpc->info->version >= ID_JZ4760) {
reg1 = JZ4760_GPIO_PAT1;
reg2 = JZ4760_GPIO_PAT0;
if (jzgc->jzpc->info->version >= ID_JZ4770) {
reg1 = JZ4770_GPIO_PAT1;
reg2 = JZ4770_GPIO_PAT0;
} else {
reg1 = JZ4740_GPIO_TRIG;
reg2 = JZ4740_GPIO_DIR;
@@ -1758,8 +1758,8 @@ static void ingenic_gpio_irq_enable(struct irq_data *irqd)
struct ingenic_gpio_chip *jzgc = gpiochip_get_data(gc);
int irq = irqd->hwirq;
if (jzgc->jzpc->info->version >= ID_JZ4760)
ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, true);
if (jzgc->jzpc->info->version >= ID_JZ4770)
ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, true);
else
ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, true);
@@ -1774,8 +1774,8 @@ static void ingenic_gpio_irq_disable(struct irq_data *irqd)
ingenic_gpio_irq_mask(irqd);
if (jzgc->jzpc->info->version >= ID_JZ4760)
ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_INT, irq, false);
if (jzgc->jzpc->info->version >= ID_JZ4770)
ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_INT, irq, false);
else
ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_SELECT, irq, false);
}
@@ -1799,8 +1799,8 @@ static void ingenic_gpio_irq_ack(struct irq_data *irqd)
irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH);
}
if (jzgc->jzpc->info->version >= ID_JZ4760)
ingenic_gpio_set_bit(jzgc, JZ4760_GPIO_FLAG, irq, false);
if (jzgc->jzpc->info->version >= ID_JZ4770)
ingenic_gpio_set_bit(jzgc, JZ4770_GPIO_FLAG, irq, false);
else
ingenic_gpio_set_bit(jzgc, JZ4740_GPIO_DATA, irq, true);
}
@@ -1856,8 +1856,8 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc)
chained_irq_enter(irq_chip, desc);
if (jzgc->jzpc->info->version >= ID_JZ4760)
flag = ingenic_gpio_read_reg(jzgc, JZ4760_GPIO_FLAG);
if (jzgc->jzpc->info->version >= ID_JZ4770)
flag = ingenic_gpio_read_reg(jzgc, JZ4770_GPIO_FLAG);
else
flag = ingenic_gpio_read_reg(jzgc, JZ4740_GPIO_FLAG);
@@ -1938,9 +1938,9 @@ static int ingenic_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
struct ingenic_pinctrl *jzpc = jzgc->jzpc;
unsigned int pin = gc->base + offset;
if (jzpc->info->version >= ID_JZ4760) {
if (ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_INT) ||
ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PAT1))
if (jzpc->info->version >= ID_JZ4770) {
if (ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_INT) ||
ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PAT1))
return GPIO_LINE_DIRECTION_IN;
return GPIO_LINE_DIRECTION_OUT;
}
@@ -1991,20 +1991,20 @@ static int ingenic_pinmux_set_pin_fn(struct ingenic_pinctrl *jzpc,
'A' + offt, idx, func);
if (jzpc->info->version >= ID_X1000) {
ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, false);
ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
ingenic_shadow_config_pin_load(jzpc, pin);
} else if (jzpc->info->version >= ID_JZ4760) {
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
} else if (jzpc->info->version >= ID_JZ4770) {
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_config_pin(jzpc, pin, GPIO_MSK, false);
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, func & 0x1);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, func & 0x1);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_FUNC, true);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_TRIG, func & 0x2);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func > 0);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, func & 0x1);
}
return 0;
@@ -2057,14 +2057,14 @@ static int ingenic_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
'A' + offt, idx, input ? "in" : "out");
if (jzpc->info->version >= ID_X1000) {
ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_shadow_config_pin(jzpc, pin, GPIO_MSK, true);
ingenic_shadow_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
ingenic_shadow_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
ingenic_shadow_config_pin_load(jzpc, pin);
} else if (jzpc->info->version >= ID_JZ4760) {
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_INT, false);
} else if (jzpc->info->version >= ID_JZ4770) {
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_INT, false);
ingenic_config_pin(jzpc, pin, GPIO_MSK, true);
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT1, input);
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT1, input);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_SELECT, false);
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DIR, !input);
@@ -2091,8 +2091,8 @@ static int ingenic_pinconf_get(struct pinctrl_dev *pctldev,
unsigned int offt = pin / PINS_PER_GPIO_CHIP;
bool pull;
if (jzpc->info->version >= ID_JZ4760)
pull = !ingenic_get_pin_config(jzpc, pin, JZ4760_GPIO_PEN);
if (jzpc->info->version >= ID_JZ4770)
pull = !ingenic_get_pin_config(jzpc, pin, JZ4770_GPIO_PEN);
else
pull = !ingenic_get_pin_config(jzpc, pin, JZ4740_GPIO_PULL_DIS);
@@ -2141,8 +2141,8 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
REG_SET(X1830_GPIO_PEH), bias << idxh);
}
} else if (jzpc->info->version >= ID_JZ4760) {
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PEN, !bias);
} else if (jzpc->info->version >= ID_JZ4770) {
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PEN, !bias);
} else {
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_PULL_DIS, !bias);
}
@@ -2151,8 +2151,8 @@ static void ingenic_set_bias(struct ingenic_pinctrl *jzpc,
static void ingenic_set_output_level(struct ingenic_pinctrl *jzpc,
unsigned int pin, bool high)
{
if (jzpc->info->version >= ID_JZ4760)
ingenic_config_pin(jzpc, pin, JZ4760_GPIO_PAT0, high);
if (jzpc->info->version >= ID_JZ4770)
ingenic_config_pin(jzpc, pin, JZ4770_GPIO_PAT0, high);
else
ingenic_config_pin(jzpc, pin, JZ4740_GPIO_DATA, high);
}

View File

@@ -51,6 +51,7 @@
* @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
* detection.
* @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
* @disabled_for_mux: These IRQs were disabled because we muxed away.
* @soc: Reference to soc_data of platform specific data.
* @regs: Base addresses for the TLMM tiles.
* @phys_base: Physical base address
@@ -72,6 +73,7 @@ struct msm_pinctrl {
DECLARE_BITMAP(dual_edge_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(enabled_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(skip_wake_irqs, MAX_NR_GPIO);
DECLARE_BITMAP(disabled_for_mux, MAX_NR_GPIO);
const struct msm_pinctrl_soc_data *soc;
void __iomem *regs[MAX_NR_TILES];
@@ -96,6 +98,14 @@ MSM_ACCESSOR(intr_cfg)
MSM_ACCESSOR(intr_status)
MSM_ACCESSOR(intr_target)
static void msm_ack_intr_status(struct msm_pinctrl *pctrl,
const struct msm_pingroup *g)
{
u32 val = g->intr_ack_high ? BIT(g->intr_status_bit) : 0;
msm_writel_intr_status(val, pctrl, g);
}
static int msm_get_groups_count(struct pinctrl_dev *pctldev)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
@@ -171,6 +181,10 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
unsigned group)
{
struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *gc = &pctrl->chip;
unsigned int irq = irq_find_mapping(gc->irq.domain, group);
struct irq_data *d = irq_get_irq_data(irq);
unsigned int gpio_func = pctrl->soc->gpio_func;
const struct msm_pingroup *g;
unsigned long flags;
u32 val, mask;
@@ -187,6 +201,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
if (WARN_ON(i == g->nfuncs))
return -EINVAL;
/*
* If an GPIO interrupt is setup on this pin then we need special
* handling. Specifically interrupt detection logic will still see
* the pin twiddle even when we're muxed away.
*
* When we see a pin with an interrupt setup on it then we'll disable
* (mask) interrupts on it when we mux away until we mux back. Note
* that disable_irq() refcounts and interrupts are disabled as long as
* at least one disable_irq() has been called.
*/
if (d && i != gpio_func &&
!test_and_set_bit(d->hwirq, pctrl->disabled_for_mux))
disable_irq(irq);
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = msm_readl_ctl(pctrl, g);
@@ -196,6 +224,20 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
if (d && i == gpio_func &&
test_and_clear_bit(d->hwirq, pctrl->disabled_for_mux)) {
/*
* Clear interrupts detected while not GPIO since we only
* masked things.
*/
if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, false);
else
msm_ack_intr_status(pctrl, g);
enable_irq(irq);
}
return 0;
}
@@ -210,8 +252,7 @@ static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev,
if (!g->nfuncs)
return 0;
/* For now assume function 0 is GPIO because it always is */
return msm_pinmux_set_mux(pctldev, g->funcs[0], offset);
return msm_pinmux_set_mux(pctldev, g->funcs[pctrl->soc->gpio_func], offset);
}
static const struct pinmux_ops msm_pinmux_ops = {
@@ -774,7 +815,7 @@ static void msm_gpio_irq_mask(struct irq_data *d)
raw_spin_unlock_irqrestore(&pctrl->lock, flags);
}
static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
static void msm_gpio_irq_unmask(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
@@ -792,17 +833,6 @@ static void msm_gpio_irq_clear_unmask(struct irq_data *d, bool status_clear)
raw_spin_lock_irqsave(&pctrl->lock, flags);
if (status_clear) {
/*
* clear the interrupt status bit before unmask to avoid
* any erroneous interrupts that would have got latched
* when the interrupt is not in use.
*/
val = msm_readl_intr_status(pctrl, g);
val &= ~BIT(g->intr_status_bit);
msm_writel_intr_status(val, pctrl, g);
}
val = msm_readl_intr_cfg(pctrl, g);
val |= BIT(g->intr_raw_status_bit);
val |= BIT(g->intr_enable_bit);
@@ -822,7 +852,7 @@ static void msm_gpio_irq_enable(struct irq_data *d)
irq_chip_enable_parent(d);
if (!test_bit(d->hwirq, pctrl->skip_wake_irqs))
msm_gpio_irq_clear_unmask(d, true);
msm_gpio_irq_unmask(d);
}
static void msm_gpio_irq_disable(struct irq_data *d)
@@ -837,11 +867,6 @@ static void msm_gpio_irq_disable(struct irq_data *d)
msm_gpio_irq_mask(d);
}
static void msm_gpio_irq_unmask(struct irq_data *d)
{
msm_gpio_irq_clear_unmask(d, false);
}
/**
* msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent.
* @d: The irq dta.
@@ -894,7 +919,6 @@ static void msm_gpio_irq_ack(struct irq_data *d)
struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
const struct msm_pingroup *g;
unsigned long flags;
u32 val;
if (test_bit(d->hwirq, pctrl->skip_wake_irqs)) {
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
@@ -906,12 +930,7 @@ static void msm_gpio_irq_ack(struct irq_data *d)
raw_spin_lock_irqsave(&pctrl->lock, flags);
val = msm_readl_intr_status(pctrl, g);
if (g->intr_ack_high)
val |= BIT(g->intr_status_bit);
else
val &= ~BIT(g->intr_status_bit);
msm_writel_intr_status(val, pctrl, g);
msm_ack_intr_status(pctrl, g);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@@ -936,6 +955,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
const struct msm_pingroup *g;
unsigned long flags;
bool was_enabled;
u32 val;
if (msm_gpio_needs_dual_edge_parent_workaround(d, type)) {
@@ -997,6 +1017,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
* could cause the INTR_STATUS to be set for EDGE interrupts.
*/
val = msm_readl_intr_cfg(pctrl, g);
was_enabled = val & BIT(g->intr_raw_status_bit);
val |= BIT(g->intr_raw_status_bit);
if (g->intr_detection_width == 2) {
val &= ~(3 << g->intr_detection_bit);
@@ -1046,6 +1067,14 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
}
msm_writel_intr_cfg(val, pctrl, g);
/*
* The first time we set RAW_STATUS_EN it could trigger an interrupt.
* Clear the interrupt. This is safe because we have
* IRQCHIP_SET_TYPE_MASKED.
*/
if (!was_enabled)
msm_ack_intr_status(pctrl, g);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
msm_gpio_update_dual_edge_pos(pctrl, g, d);
@@ -1099,16 +1128,11 @@ static int msm_gpio_irq_reqres(struct irq_data *d)
}
/*
* Clear the interrupt that may be pending before we enable
* the line.
* This is especially a problem with the GPIOs routed to the
* PDC. These GPIOs are direct-connect interrupts to the GIC.
* Disabling the interrupt line at the PDC does not prevent
* the interrupt from being latched at the GIC. The state at
* GIC needs to be cleared before enabling.
* The disable / clear-enable workaround we do in msm_pinmux_set_mux()
* only works if disable is not lazy since we only clear any bogus
* interrupt in hardware. Explicitly mark the interrupt as UNLAZY.
*/
if (d->parent_data && test_bit(d->hwirq, pctrl->skip_wake_irqs))
irq_chip_set_parent_state(d, IRQCHIP_STATE_PENDING, 0);
irq_set_status_flags(d->irq, IRQ_DISABLE_UNLAZY);
return 0;
out:

View File

@@ -118,6 +118,7 @@ struct msm_gpio_wakeirq_map {
* @wakeirq_dual_edge_errata: If true then GPIOs using the wakeirq_map need
* to be aware that their parent can't handle dual
* edge interrupts.
* @gpio_func: Which function number is GPIO (usually 0).
*/
struct msm_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
@@ -134,6 +135,7 @@ struct msm_pinctrl_soc_data {
const struct msm_gpio_wakeirq_map *wakeirq_map;
unsigned int nwakeirq_map;
bool wakeirq_dual_edge_errata;
unsigned int gpio_func;
};
extern const struct dev_pm_ops msm_pinctrl_dev_pm_ops;

View File

@@ -140,12 +140,13 @@ struct litex_soc_ctrl_device {
void __iomem *base;
};
#ifdef CONFIG_OF
static const struct of_device_id litex_soc_ctrl_of_match[] = {
{.compatible = "litex,soc-controller"},
{},
};
MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match);
#endif /* CONFIG_OF */
static int litex_soc_ctrl_probe(struct platform_device *pdev)
{

View File

@@ -1473,22 +1473,26 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
ret = err;
}
/*
* If the inode has dirty timestamps and we need to write them, call
* mark_inode_dirty_sync() to notify the filesystem about it and to
* change I_DIRTY_TIME into I_DIRTY_SYNC.
*/
if ((inode->i_state & I_DIRTY_TIME) &&
(wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
time_after(jiffies, inode->dirtied_time_when +
dirtytime_expire_interval * HZ))) {
trace_writeback_lazytime(inode);
mark_inode_dirty_sync(inode);
}
/*
* Some filesystems may redirty the inode during the writeback
* due to delalloc, clear dirty metadata flags right before
* write_inode()
*/
spin_lock(&inode->i_lock);
dirty = inode->i_state & I_DIRTY;
if ((inode->i_state & I_DIRTY_TIME) &&
((dirty & I_DIRTY_INODE) ||
wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
time_after(jiffies, inode->dirtied_time_when +
dirtytime_expire_interval * HZ))) {
dirty |= I_DIRTY_TIME;
trace_writeback_lazytime(inode);
}
inode->i_state &= ~dirty;
/*
@@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_unlock(&inode->i_lock);
if (dirty & I_DIRTY_TIME)
mark_inode_dirty_sync(inode);
/* Don't write the inode if only I_DIRTY_PAGES was set */
if (dirty & ~I_DIRTY_PAGES) {
int err = write_inode(inode, wbc);

View File

@@ -705,6 +705,7 @@ static int udf_check_vsd(struct super_block *sb)
struct buffer_head *bh = NULL;
int nsr = 0;
struct udf_sb_info *sbi;
loff_t session_offset;
sbi = UDF_SB(sb);
if (sb->s_blocksize < sizeof(struct volStructDesc))
@@ -712,7 +713,8 @@ static int udf_check_vsd(struct super_block *sb)
else
sectorsize = sb->s_blocksize;
sector += (((loff_t)sbi->s_session) << sb->s_blocksize_bits);
session_offset = (loff_t)sbi->s_session << sb->s_blocksize_bits;
sector += session_offset;
udf_debug("Starting at sector %u (%lu byte sectors)\n",
(unsigned int)(sector >> sb->s_blocksize_bits),
@@ -757,8 +759,7 @@ static int udf_check_vsd(struct super_block *sb)
if (nsr > 0)
return 1;
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
VSD_FIRST_SECTOR_OFFSET)
else if (!bh && sector - session_offset == VSD_FIRST_SECTOR_OFFSET)
return -1;
else
return 0;

View File

@@ -1293,11 +1293,16 @@ static size_t info_print_prefix(const struct printk_info *info, bool syslog,
* done:
*
* - Add prefix for each line.
* - Drop truncated lines that no longer fit into the buffer.
* - Add the trailing newline that has been removed in vprintk_store().
* - Drop truncated lines that do not longer fit into the buffer.
* - Add a string terminator.
*
* Since the produced string is always terminated, the maximum possible
* return value is @r->text_buf_size - 1;
*
* Return: The length of the updated/prepared text, including the added
* prefixes and the newline. The dropped line(s) are not counted.
* prefixes and the newline. The terminator is not counted. The dropped
* line(s) are not counted.
*/
static size_t record_print_text(struct printk_record *r, bool syslog,
bool time)
@@ -1340,26 +1345,31 @@ static size_t record_print_text(struct printk_record *r, bool syslog,
/*
* Truncate the text if there is not enough space to add the
* prefix and a trailing newline.
* prefix and a trailing newline and a terminator.
*/
if (len + prefix_len + text_len + 1 > buf_size) {
if (len + prefix_len + text_len + 1 + 1 > buf_size) {
/* Drop even the current line if no space. */
if (len + prefix_len + line_len + 1 > buf_size)
if (len + prefix_len + line_len + 1 + 1 > buf_size)
break;
text_len = buf_size - len - prefix_len - 1;
text_len = buf_size - len - prefix_len - 1 - 1;
truncated = true;
}
memmove(text + prefix_len, text, text_len);
memcpy(text, prefix, prefix_len);
/*
* Increment the prepared length to include the text and
* prefix that were just moved+copied. Also increment for the
* newline at the end of this line. If this is the last line,
* there is no newline, but it will be added immediately below.
*/
len += prefix_len + line_len + 1;
if (text_len == line_len) {
/*
* Add the trailing newline removed in
* vprintk_store().
* This is the last line. Add the trailing newline
* removed in vprintk_store().
*/
text[prefix_len + line_len] = '\n';
break;
@@ -1384,6 +1394,14 @@ static size_t record_print_text(struct printk_record *r, bool syslog,
text_len -= line_len + 1;
}
/*
* If a buffer was provided, it will be terminated. Space for the
* string terminator is guaranteed to be available. The terminator is
* not counted in the return value.
*/
if (buf_size > 0)
text[len] = 0;
return len;
}
@@ -3436,7 +3454,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
while (prb_read_valid_info(prb, seq, &info, &line_count)) {
if (r.info->seq >= dumper->next_seq)
break;
l += get_record_print_text_size(&info, line_count, true, time);
l += get_record_print_text_size(&info, line_count, syslog, time);
seq = r.info->seq + 1;
}
@@ -3446,7 +3464,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
&info, &line_count)) {
if (r.info->seq >= dumper->next_seq)
break;
l -= get_record_print_text_size(&info, line_count, true, time);
l -= get_record_print_text_size(&info, line_count, syslog, time);
seq = r.info->seq + 1;
}

View File

@@ -1718,7 +1718,7 @@ static bool copy_data(struct prb_data_ring *data_ring,
/* Caller interested in the line count? */
if (line_count)
*line_count = count_lines(data, data_size);
*line_count = count_lines(data, len);
/* Caller interested in the data content? */
if (!buf || !buf_size)

View File

@@ -611,7 +611,8 @@ snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_in
if (info->is_midi) {
struct midi_info minf;
snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf);
if (snd_seq_oss_midi_make_info(dp, info->midi_mapped, &minf))
return -ENXIO;
inf->synth_type = SYNTH_TYPE_MIDI;
inf->synth_subtype = 0;
inf->nr_voices = 16;

View File

@@ -2934,7 +2934,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
snd_hdac_leave_pm(&codec->core);
}
static int hda_codec_suspend(struct device *dev)
static int hda_codec_runtime_suspend(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
unsigned int state;
@@ -2953,7 +2953,7 @@ static int hda_codec_suspend(struct device *dev)
return 0;
}
static int hda_codec_resume(struct device *dev)
static int hda_codec_runtime_resume(struct device *dev)
{
struct hda_codec *codec = dev_to_hda_codec(dev);
@@ -2968,16 +2968,6 @@ static int hda_codec_resume(struct device *dev)
return 0;
}
static int hda_codec_runtime_suspend(struct device *dev)
{
return hda_codec_suspend(dev);
}
static int hda_codec_runtime_resume(struct device *dev)
{
return hda_codec_resume(dev);
}
#endif /* CONFIG_PM */
#ifdef CONFIG_PM_SLEEP
@@ -2998,31 +2988,31 @@ static void hda_codec_pm_complete(struct device *dev)
static int hda_codec_pm_suspend(struct device *dev)
{
dev->power.power_state = PMSG_SUSPEND;
return hda_codec_suspend(dev);
return pm_runtime_force_suspend(dev);
}
static int hda_codec_pm_resume(struct device *dev)
{
dev->power.power_state = PMSG_RESUME;
return hda_codec_resume(dev);
return pm_runtime_force_resume(dev);
}
static int hda_codec_pm_freeze(struct device *dev)
{
dev->power.power_state = PMSG_FREEZE;
return hda_codec_suspend(dev);
return pm_runtime_force_suspend(dev);
}
static int hda_codec_pm_thaw(struct device *dev)
{
dev->power.power_state = PMSG_THAW;
return hda_codec_resume(dev);
return pm_runtime_force_resume(dev);
}
static int hda_codec_pm_restore(struct device *dev)
{
dev->power.power_state = PMSG_RESTORE;
return hda_codec_resume(dev);
return pm_runtime_force_resume(dev);
}
#endif /* CONFIG_PM_SLEEP */

View File

@@ -2484,6 +2484,9 @@ static const struct pci_device_id azx_ids[] = {
/* CometLake-S */
{ PCI_DEVICE(0x8086, 0xa3f0),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* CometLake-R */
{ PCI_DEVICE(0x8086, 0xf0c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Icelake */
{ PCI_DEVICE(0x8086, 0x34c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
@@ -2507,6 +2510,9 @@ static const struct pci_device_id azx_ids[] = {
/* Alderlake-S */
{ PCI_DEVICE(0x8086, 0x7ad0),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Alderlake-P */
{ PCI_DEVICE(0x8086, 0x51c8),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
/* Elkhart Lake */
{ PCI_DEVICE(0x8086, 0x4b55),
.driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},

View File

@@ -4346,6 +4346,7 @@ HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x80862814, "DG1 HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x80862815, "Alderlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x8086281c, "Alderlake-P HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x80862816, "Rocketlake HDMI", patch_i915_tgl_hdmi),
HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
HDA_CODEC_ENTRY(0x8086281b, "Elkhartlake HDMI", patch_i915_icl_hdmi),

View File

@@ -6371,6 +6371,7 @@ enum {
ALC256_FIXUP_HP_HEADSET_MIC,
ALC236_FIXUP_DELL_AIO_HEADSET_MIC,
ALC282_FIXUP_ACER_DISABLE_LINEOUT,
ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST,
};
static const struct hda_fixup alc269_fixups[] = {
@@ -7808,6 +7809,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE
},
[ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc269_fixup_limit_int_mic_boost,
.chained = true,
.chain_id = ALC255_FIXUP_ACER_MIC_NO_PRESENCE,
},
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7826,6 +7833,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1065, "Acer Aspire C20-820", ALC269VC_FIXUP_ACER_HEADSET_MIC),
SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
SND_PCI_QUIRK(0x1025, 0x1094, "Acer Aspire E5-575T", ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x1025, 0x1099, "Acer Aspire E5-523G", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x110e, "Acer Aspire ES1-432", ALC255_FIXUP_ACER_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1025, 0x1166, "Acer Veriton N4640G", ALC269_FIXUP_LIFEBOOK),

View File

@@ -113,6 +113,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec)
spec->codec_type = VT1708S;
spec->gen.indep_hp = 1;
spec->gen.keep_eapd_on = 1;
spec->gen.dac_min_mute = 1;
spec->gen.pcm_playback_hook = via_playback_pcm_hook;
spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO;
codec->power_save_node = 1;

View File

@@ -717,7 +717,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component,
void *data)
{
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
int ret = -EOPNOTSUPP;
int ret = -ENOTSUPP;
if (hcp->hcd.ops->hook_plugged_cb) {
hcp->jack = jack;

View File

@@ -90,7 +90,7 @@ static int imx_hdmi_init(struct snd_soc_pcm_runtime *rtd)
}
ret = snd_soc_component_set_jack(component, &data->hdmi_jack, NULL);
if (ret && ret != -EOPNOTSUPP) {
if (ret && ret != -ENOTSUPP) {
dev_err(card->dev, "Can't set HDMI Jack %d\n", ret);
return ret;
}

View File

@@ -63,16 +63,18 @@ static int hda_codec_load_module(struct hda_codec *codec)
}
/* enable controller wake up event for all codecs with jack connectors */
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable)
{
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;
unsigned int mask = 0;
list_for_each_codec(codec, hbus)
if (codec->jacktbl.used)
mask |= BIT(codec->core.addr);
if (enable) {
list_for_each_codec(codec, hbus)
if (codec->jacktbl.used)
mask |= BIT(codec->core.addr);
}
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask);
}
@@ -81,23 +83,18 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
void hda_codec_jack_check(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hdac_bus *bus = sof_to_bus(sdev);
struct hda_codec *codec;
/* disable controller Wake Up event*/
snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, 0);
list_for_each_codec(codec, hbus)
/*
* Wake up all jack-detecting codecs regardless whether an event
* has been recorded in STATESTS
*/
if (codec->jacktbl.used)
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
pm_request_resume(&codec->core.dev);
}
#else
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev) {}
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) {}
void hda_codec_jack_check(struct snd_sof_dev *sdev) {}
#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */
EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC);
@@ -156,7 +153,8 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
if (!hdev->bus->audio_component) {
dev_dbg(sdev->dev,
"iDisp hw present but no driver\n");
goto error;
ret = -ENOENT;
goto out;
}
hda_priv->need_display_power = true;
}
@@ -173,24 +171,23 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
* other return codes without modification
*/
if (ret == 0)
goto error;
ret = -ENOENT;
}
return ret;
error:
snd_hdac_ext_bus_device_exit(hdev);
return -ENOENT;
out:
if (ret < 0) {
snd_hdac_device_unregister(hdev);
put_device(&hdev->dev);
}
#else
hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
if (!hdev)
return -ENOMEM;
ret = snd_hdac_ext_bus_device_init(&hbus->core, address, hdev, HDA_DEV_ASOC);
#endif
return ret;
#endif
}
/* Codec initialization */

View File

@@ -617,7 +617,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
if (runtime_suspend)
hda_codec_jack_wake_enable(sdev);
hda_codec_jack_wake_enable(sdev, true);
/* power down all hda link */
snd_hdac_ext_bus_link_power_down_all(bus);
@@ -683,8 +683,11 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* check jack status */
if (runtime_resume)
hda_codec_jack_check(sdev);
if (runtime_resume) {
hda_codec_jack_wake_enable(sdev, false);
if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
hda_codec_jack_check(sdev);
}
/* turn off the links that were off before suspend */
list_for_each_entry(hlink, &bus->hlink_list, list) {

View File

@@ -650,7 +650,7 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev);
*/
void hda_codec_probe_bus(struct snd_sof_dev *sdev,
bool hda_codec_use_common_hdmi);
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev);
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable);
void hda_codec_jack_check(struct snd_sof_dev *sdev);
#endif /* CONFIG_SND_SOC_SOF_HDA */

View File

@@ -485,18 +485,9 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
const struct audioformat *fmt, int rate)
{
struct usb_device *dev = chip->dev;
struct usb_host_interface *alts;
unsigned int ep;
unsigned char data[3];
int err, crate;
alts = snd_usb_get_host_interface(chip, fmt->iface, fmt->altsetting);
if (!alts)
return -EINVAL;
if (get_iface_desc(alts)->bNumEndpoints < 1)
return -EINVAL;
ep = get_endpoint(alts, 0)->bEndpointAddress;
/* if endpoint doesn't have sampling rate control, bail out */
if (!(fmt->attributes & UAC_EP_CS_ATTR_SAMPLE_RATE))
return 0;
@@ -506,11 +497,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
data[2] = rate >> 16;
err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
data, sizeof(data));
UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
fmt->endpoint, data, sizeof(data));
if (err < 0) {
dev_err(&dev->dev, "%d:%d: cannot set freq %d to ep %#x\n",
fmt->iface, fmt->altsetting, rate, ep);
fmt->iface, fmt->altsetting, rate, fmt->endpoint);
return err;
}
@@ -524,11 +515,11 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip,
err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR,
USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep,
data, sizeof(data));
UAC_EP_CS_ATTR_SAMPLE_RATE << 8,
fmt->endpoint, data, sizeof(data));
if (err < 0) {
dev_err(&dev->dev, "%d:%d: cannot get freq at ep %#x\n",
fmt->iface, fmt->altsetting, ep);
fmt->iface, fmt->altsetting, fmt->endpoint);
chip->sample_rate_read_error++;
return 0; /* some devices don't support reading */
}

View File

@@ -1252,6 +1252,15 @@ int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
/* If the interface has been already set up, just set EP parameters */
if (!ep->iface_ref->need_setup) {
/* sample rate setup of UAC1 is per endpoint, and we need
* to update at each EP configuration
*/
if (ep->cur_audiofmt->protocol == UAC_VERSION_1) {
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt,
ep->cur_rate);
if (err < 0)
goto unlock;
}
err = snd_usb_endpoint_set_params(chip, ep);
if (err < 0)
goto unlock;

View File

@@ -175,11 +175,13 @@ static int add_roland_implicit_fb(struct snd_usb_audio *chip,
ifnum, alts);
}
/* Pioneer devices: playback and capture streams sharing the same iface/altset
/* Playback and capture EPs on Pioneer devices share the same iface/altset,
* but they don't seem working with the implicit fb mode well, hence we
* just return as if the sync were already set up.
*/
static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
struct audioformat *fmt,
struct usb_host_interface *alts)
static int skip_pioneer_sync_ep(struct snd_usb_audio *chip,
struct audioformat *fmt,
struct usb_host_interface *alts)
{
struct usb_endpoint_descriptor *epd;
@@ -194,8 +196,7 @@ static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
(epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
USB_ENDPOINT_USAGE_IMPLICIT_FB))
return 0;
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 1,
alts->desc.bInterfaceNumber, alts);
return 1; /* don't handle with the implicit fb, just skip sync EP */
}
static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
@@ -298,11 +299,11 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
return 1;
}
/* Pioneer devices implicit feedback with vendor spec class */
/* Pioneer devices with vendor spec class */
if (attr == USB_ENDPOINT_SYNC_ASYNC &&
alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
USB_ID_VENDOR(chip->usb_id) == 0x2b73 /* Pioneer */) {
if (add_pioneer_implicit_fb(chip, fmt, alts))
if (skip_pioneer_sync_ep(chip, fmt, alts))
return 1;
}

View File

@@ -663,7 +663,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs,
check_fmts.bits[1] = (u32)(fp->formats >> 32);
snd_mask_intersect(&check_fmts, fmts);
if (snd_mask_empty(&check_fmts)) {
hwc_debug(" > check: no supported format %d\n", fp->format);
hwc_debug(" > check: no supported format 0x%llx\n", fp->formats);
return 0;
}
/* check the channels */
@@ -775,24 +775,11 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
return apply_hw_params_minmax(it, rmin, rmax);
}
static int hw_rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
static int apply_hw_params_format_bits(struct snd_mask *fmt, u64 fbits)
{
struct snd_usb_substream *subs = rule->private;
const struct audioformat *fp;
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
u64 fbits;
u32 oldbits[2];
int changed;
hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
fbits = 0;
list_for_each_entry(fp, &subs->fmt_list, list) {
if (!hw_check_valid_format(subs, params, fp))
continue;
fbits |= fp->formats;
}
oldbits[0] = fmt->bits[0];
oldbits[1] = fmt->bits[1];
fmt->bits[0] &= (u32)fbits;
@@ -806,6 +793,24 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
return changed;
}
static int hw_rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_usb_substream *subs = rule->private;
const struct audioformat *fp;
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
u64 fbits;
hwc_debug("hw_rule_format: %x:%x\n", fmt->bits[0], fmt->bits[1]);
fbits = 0;
list_for_each_entry(fp, &subs->fmt_list, list) {
if (!hw_check_valid_format(subs, params, fp))
continue;
fbits |= fp->formats;
}
return apply_hw_params_format_bits(fmt, fbits);
}
static int hw_rule_period_time(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
@@ -833,64 +838,92 @@ static int hw_rule_period_time(struct snd_pcm_hw_params *params,
return apply_hw_params_minmax(it, pmin, UINT_MAX);
}
/* apply PCM hw constraints from the concurrent sync EP */
static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
struct snd_usb_substream *subs)
/* get the EP or the sync EP for implicit fb when it's already set up */
static const struct snd_usb_endpoint *
get_sync_ep_from_substream(struct snd_usb_substream *subs)
{
struct snd_usb_audio *chip = subs->stream->chip;
struct snd_usb_endpoint *ep;
const struct audioformat *fp;
int err;
const struct snd_usb_endpoint *ep;
list_for_each_entry(fp, &subs->fmt_list, list) {
ep = snd_usb_get_endpoint(chip, fp->endpoint);
if (ep && ep->cur_rate)
goto found;
return ep;
if (!fp->implicit_fb)
continue;
/* for the implicit fb, check the sync ep as well */
ep = snd_usb_get_endpoint(chip, fp->sync_ep);
if (ep && ep->cur_rate)
goto found;
return ep;
}
return 0;
return NULL;
}
found:
if (!find_format(&subs->fmt_list, ep->cur_format, ep->cur_rate,
ep->cur_channels, false, NULL)) {
usb_audio_dbg(chip, "EP 0x%x being used, but not applicable\n",
ep->ep_num);
/* additional hw constraints for implicit feedback mode */
static int hw_rule_format_implicit_fb(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_usb_substream *subs = rule->private;
const struct snd_usb_endpoint *ep;
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
ep = get_sync_ep_from_substream(subs);
if (!ep)
return 0;
}
usb_audio_dbg(chip, "EP 0x%x being used, using fixed params:\n",
ep->ep_num);
usb_audio_dbg(chip, "rate=%d, period_size=%d, periods=%d\n",
ep->cur_rate, ep->cur_period_frames,
ep->cur_buffer_periods);
hwc_debug("applying %s\n", __func__);
return apply_hw_params_format_bits(fmt, pcm_format_to_bits(ep->cur_format));
}
runtime->hw.formats = subs->formats;
runtime->hw.rate_min = runtime->hw.rate_max = ep->cur_rate;
runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
runtime->hw.periods_min = runtime->hw.periods_max =
ep->cur_buffer_periods;
static int hw_rule_rate_implicit_fb(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_usb_substream *subs = rule->private;
const struct snd_usb_endpoint *ep;
struct snd_interval *it;
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
hw_rule_channels, subs,
SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_HW_PARAM_RATE,
-1);
if (err < 0)
return err;
ep = get_sync_ep_from_substream(subs);
if (!ep)
return 0;
err = snd_pcm_hw_constraint_minmax(runtime,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
ep->cur_period_frames,
ep->cur_period_frames);
if (err < 0)
return err;
hwc_debug("applying %s\n", __func__);
it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
return apply_hw_params_minmax(it, ep->cur_rate, ep->cur_rate);
}
return 1; /* notify the finding */
static int hw_rule_period_size_implicit_fb(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_usb_substream *subs = rule->private;
const struct snd_usb_endpoint *ep;
struct snd_interval *it;
ep = get_sync_ep_from_substream(subs);
if (!ep)
return 0;
hwc_debug("applying %s\n", __func__);
it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
return apply_hw_params_minmax(it, ep->cur_period_frames,
ep->cur_period_frames);
}
static int hw_rule_periods_implicit_fb(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
struct snd_usb_substream *subs = rule->private;
const struct snd_usb_endpoint *ep;
struct snd_interval *it;
ep = get_sync_ep_from_substream(subs);
if (!ep)
return 0;
hwc_debug("applying %s\n", __func__);
it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIODS);
return apply_hw_params_minmax(it, ep->cur_buffer_periods,
ep->cur_buffer_periods);
}
/*
@@ -899,20 +932,11 @@ static int apply_hw_constraint_from_sync(struct snd_pcm_runtime *runtime,
static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
{
struct snd_usb_audio *chip = subs->stream->chip;
const struct audioformat *fp;
unsigned int pt, ptmin;
int param_period_time_if_needed = -1;
int err;
mutex_lock(&chip->mutex);
err = apply_hw_constraint_from_sync(runtime, subs);
mutex_unlock(&chip->mutex);
if (err < 0)
return err;
if (err > 0) /* found the matching? */
goto add_extra_rules;
runtime->hw.formats = subs->formats;
runtime->hw.rate_min = 0x7fffffff;
@@ -957,6 +981,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
hw_rule_rate, subs,
SNDRV_PCM_HW_PARAM_RATE,
SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_HW_PARAM_CHANNELS,
param_period_time_if_needed,
@@ -964,9 +989,9 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
if (err < 0)
return err;
add_extra_rules:
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
hw_rule_channels, subs,
SNDRV_PCM_HW_PARAM_CHANNELS,
SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_HW_PARAM_RATE,
param_period_time_if_needed,
@@ -975,6 +1000,7 @@ add_extra_rules:
return err;
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
hw_rule_format, subs,
SNDRV_PCM_HW_PARAM_FORMAT,
SNDRV_PCM_HW_PARAM_RATE,
SNDRV_PCM_HW_PARAM_CHANNELS,
param_period_time_if_needed,
@@ -993,6 +1019,28 @@ add_extra_rules:
return err;
}
/* additional hw constraints for implicit fb */
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
hw_rule_format_implicit_fb, subs,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
return err;
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
hw_rule_rate_implicit_fb, subs,
SNDRV_PCM_HW_PARAM_RATE, -1);
if (err < 0)
return err;
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
hw_rule_period_size_implicit_fb, subs,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1);
if (err < 0)
return err;
err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS,
hw_rule_periods_implicit_fb, subs,
SNDRV_PCM_HW_PARAM_PERIODS, -1);
if (err < 0)
return err;
return 0;
}

View File

@@ -1470,30 +1470,6 @@ static void set_format_emu_quirk(struct snd_usb_substream *subs,
subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
}
/*
* Pioneer DJ DJM-900NXS2
* Device needs to know the sample rate each time substream is started
*/
static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs)
{
unsigned int cur_rate = subs->data_endpoint->cur_rate;
/* Convert sample rate value to little endian */
u8 sr[3];
sr[0] = cur_rate & 0xff;
sr[1] = (cur_rate >> 8) & 0xff;
sr[2] = (cur_rate >> 16) & 0xff;
/* Configure device */
usb_set_interface(subs->dev, 0, 1);
snd_usb_ctl_msg(subs->stream->chip->dev,
usb_rcvctrlpipe(subs->stream->chip->dev, 0),
0x01, 0x22, 0x0100, 0x0082, &sr, 0x0003);
return 0;
}
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
const struct audioformat *fmt)
{
@@ -1504,10 +1480,6 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
set_format_emu_quirk(subs, fmt);
break;
case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */
pioneer_djm_set_format_quirk(subs);
break;
case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
subs->stream_offset_adj = 2;
break;

View File

@@ -107,8 +107,8 @@ int monitor_device(const char *device_name,
ret = -EIO;
break;
}
fprintf(stdout, "GPIO EVENT at %llu on line %d (%d|%d) ",
event.timestamp_ns, event.offset, event.line_seqno,
fprintf(stdout, "GPIO EVENT at %" PRIu64 " on line %d (%d|%d) ",
(uint64_t)event.timestamp_ns, event.offset, event.line_seqno,
event.seqno);
switch (event.id) {
case GPIO_V2_LINE_EVENT_RISING_EDGE:

View File

@@ -10,6 +10,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <linux/gpio.h>
#include <poll.h>
#include <stdbool.h>
@@ -86,8 +87,8 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
printf("line %u: %s at %llu\n",
chg.info.offset, event, chg.timestamp_ns);
printf("line %u: %s at %" PRIu64 "\n",
chg.info.offset, event, (uint64_t)chg.timestamp_ns);
}
}