Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

Conflicts:
	net/netfilter/nf_tables_core.c

The nf_tables_core.c conflict was resolved using a conflict resolution
from Stephen Rothwell as a guide.

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-03-23 22:22:43 -04:00
commit d5c1d8c567
134 changed files with 1389 additions and 1634 deletions

View File

@ -10206,6 +10206,13 @@ S: Maintained
F: Documentation/usb/ohci.txt
F: drivers/usb/host/ohci*
USB OTG FSM (Finite State Machine)
M: Peter Chen <Peter.Chen@freescale.com>
T: git git://github.com/hzpeterchen/linux-usb.git
L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/common/usb-otg-fsm.c
USB OVER IP DRIVER
M: Valentina Manea <valentina.manea.m@gmail.com>
M: Shuah Khan <shuah.kh@samsung.com>

View File

@ -1,7 +1,7 @@
VERSION = 4
PATCHLEVEL = 0
SUBLEVEL = 0
EXTRAVERSION = -rc4
EXTRAVERSION = -rc5
NAME = Hurr durr I'ma sheep
# *DOCUMENTATION*

View File

@ -246,12 +246,9 @@ static int __get_cpu_architecture(void)
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
unsigned int mmfr0;
/* Revised CPUID format. Read the Memory Model Feature
* Register 0 and check for VMSAv7 or PMSAv7 */
asm("mrc p15, 0, %0, c0, c1, 4"
: "=r" (mmfr0));
unsigned int mmfr0 = read_cpuid_ext(CPUID_EXT_MMFR0);
if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
(mmfr0 & 0x000000f0) >= 0x00000030)
cpu_arch = CPU_ARCH_ARMv7;

View File

@ -1131,23 +1131,22 @@ static void __init l2c310_of_parse(const struct device_node *np,
}
ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K);
if (ret)
return;
switch (assoc) {
case 16:
*aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
*aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16;
*aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
break;
case 8:
*aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
*aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
break;
default:
pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n",
assoc);
break;
if (!ret) {
switch (assoc) {
case 16:
*aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
*aux_val |= L310_AUX_CTRL_ASSOCIATIVITY_16;
*aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
break;
case 8:
*aux_val &= ~L2X0_AUX_CTRL_ASSOC_MASK;
*aux_mask &= ~L2X0_AUX_CTRL_ASSOC_MASK;
break;
default:
pr_err("L2C-310 OF cache associativity %d invalid, only 8 or 16 permitted\n",
assoc);
break;
}
}
prefetch = l2x0_saved_regs.prefetch_ctrl;

View File

@ -171,7 +171,7 @@ static int __dma_supported(struct device *dev, u64 mask, bool warn)
*/
if (sizeof(mask) != sizeof(dma_addr_t) &&
mask > (dma_addr_t)~0 &&
dma_to_pfn(dev, ~0) < max_pfn) {
dma_to_pfn(dev, ~0) < max_pfn - 1) {
if (warn) {
dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
mask);

View File

@ -552,6 +552,7 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
pr_alert("Unhandled fault: %s (0x%03x) at 0x%08lx\n",
inf->name, fsr, addr);
show_pte(current->mm, addr);
info.si_signo = inf->sig;
info.si_errno = 0;

View File

@ -49,7 +49,10 @@ static int change_memory_common(unsigned long addr, int numpages,
WARN_ON_ONCE(1);
}
if (!is_module_address(start) || !is_module_address(end - 1))
if (start < MODULES_VADDR || start >= MODULES_END)
return -EINVAL;
if (end < MODULES_VADDR || start >= MODULES_END)
return -EINVAL;
data.set_mask = set_mask;

View File

@ -39,7 +39,11 @@ extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);
#include <asm/memory.h>
#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
#define cpu_switch_mm(pgd,mm) \
do { \
BUG_ON(pgd == swapper_pg_dir); \
cpu_do_switch_mm(virt_to_phys(pgd),mm); \
} while (0)
#define cpu_get_pgd() \
({ \

View File

@ -337,7 +337,11 @@ core_initcall(arm64_dmi_init);
static void efi_set_pgd(struct mm_struct *mm)
{
cpu_switch_mm(mm->pgd, mm);
if (mm == &init_mm)
cpu_set_reserved_ttbr0();
else
cpu_switch_mm(mm->pgd, mm);
flush_tlb_all();
if (icache_is_aivivt())
__flush_icache_all();

View File

@ -51,7 +51,7 @@ static int __init early_coherent_pool(char *p)
}
early_param("coherent_pool", early_coherent_pool);
static void *__alloc_from_pool(size_t size, struct page **ret_page)
static void *__alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags)
{
unsigned long val;
void *ptr = NULL;
@ -67,6 +67,8 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page)
*ret_page = phys_to_page(phys);
ptr = (void *)val;
if (flags & __GFP_ZERO)
memset(ptr, 0, size);
}
return ptr;
@ -101,6 +103,7 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
flags |= GFP_DMA;
if (IS_ENABLED(CONFIG_DMA_CMA) && (flags & __GFP_WAIT)) {
struct page *page;
void *addr;
size = PAGE_ALIGN(size);
page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
@ -109,7 +112,10 @@ static void *__dma_alloc_coherent(struct device *dev, size_t size,
return NULL;
*dma_handle = phys_to_dma(dev, page_to_phys(page));
return page_address(page);
addr = page_address(page);
if (flags & __GFP_ZERO)
memset(addr, 0, size);
return addr;
} else {
return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
}
@ -146,7 +152,7 @@ static void *__dma_alloc(struct device *dev, size_t size,
if (!coherent && !(flags & __GFP_WAIT)) {
struct page *page = NULL;
void *addr = __alloc_from_pool(size, &page);
void *addr = __alloc_from_pool(size, &page, flags);
if (addr)
*dma_handle = phys_to_dma(dev, page_to_phys(page));

View File

@ -2957,6 +2957,17 @@ unsigned long sun4v_t5_set_perfreg(unsigned long reg_num,
unsigned long reg_val);
#endif
#define HV_FAST_M7_GET_PERFREG 0x43
#define HV_FAST_M7_SET_PERFREG 0x44
#ifndef __ASSEMBLY__
unsigned long sun4v_m7_get_perfreg(unsigned long reg_num,
unsigned long *reg_val);
unsigned long sun4v_m7_set_perfreg(unsigned long reg_num,
unsigned long reg_val);
#endif
/* Function numbers for HV_CORE_TRAP. */
#define HV_CORE_SET_VER 0x00
#define HV_CORE_PUTCHAR 0x01
@ -2981,6 +2992,7 @@ unsigned long sun4v_t5_set_perfreg(unsigned long reg_num,
#define HV_GRP_SDIO 0x0108
#define HV_GRP_SDIO_ERR 0x0109
#define HV_GRP_REBOOT_DATA 0x0110
#define HV_GRP_M7_PERF 0x0114
#define HV_GRP_NIAG_PERF 0x0200
#define HV_GRP_FIRE_PERF 0x0201
#define HV_GRP_N2_CPU 0x0202

View File

@ -48,6 +48,7 @@ static struct api_info api_table[] = {
{ .group = HV_GRP_VT_CPU, },
{ .group = HV_GRP_T5_CPU, },
{ .group = HV_GRP_DIAG, .flags = FLAG_PRE_API },
{ .group = HV_GRP_M7_PERF, },
};
static DEFINE_SPINLOCK(hvapi_lock);

View File

@ -837,3 +837,19 @@ ENTRY(sun4v_t5_set_perfreg)
retl
nop
ENDPROC(sun4v_t5_set_perfreg)
ENTRY(sun4v_m7_get_perfreg)
mov %o1, %o4
mov HV_FAST_M7_GET_PERFREG, %o5
ta HV_FAST_TRAP
stx %o1, [%o4]
retl
nop
ENDPROC(sun4v_m7_get_perfreg)
ENTRY(sun4v_m7_set_perfreg)
mov HV_FAST_M7_SET_PERFREG, %o5
ta HV_FAST_TRAP
retl
nop
ENDPROC(sun4v_m7_set_perfreg)

View File

@ -217,6 +217,31 @@ static const struct pcr_ops n5_pcr_ops = {
.pcr_nmi_disable = PCR_N4_PICNPT,
};
static u64 m7_pcr_read(unsigned long reg_num)
{
unsigned long val;
(void) sun4v_m7_get_perfreg(reg_num, &val);
return val;
}
static void m7_pcr_write(unsigned long reg_num, u64 val)
{
(void) sun4v_m7_set_perfreg(reg_num, val);
}
static const struct pcr_ops m7_pcr_ops = {
.read_pcr = m7_pcr_read,
.write_pcr = m7_pcr_write,
.read_pic = n4_pic_read,
.write_pic = n4_pic_write,
.nmi_picl_value = n4_picl_value,
.pcr_nmi_enable = (PCR_N4_PICNPT | PCR_N4_STRACE |
PCR_N4_UTRACE | PCR_N4_TOE |
(26 << PCR_N4_SL_SHIFT)),
.pcr_nmi_disable = PCR_N4_PICNPT,
};
static unsigned long perf_hsvc_group;
static unsigned long perf_hsvc_major;
@ -248,6 +273,10 @@ static int __init register_perf_hsvc(void)
perf_hsvc_group = HV_GRP_T5_CPU;
break;
case SUN4V_CHIP_SPARC_M7:
perf_hsvc_group = HV_GRP_M7_PERF;
break;
default:
return -ENODEV;
}
@ -293,6 +322,10 @@ static int __init setup_sun4v_pcr_ops(void)
pcr_ops = &n5_pcr_ops;
break;
case SUN4V_CHIP_SPARC_M7:
pcr_ops = &m7_pcr_ops;
break;
default:
ret = -ENODEV;
break;

View File

@ -792,6 +792,42 @@ static const struct sparc_pmu niagara4_pmu = {
.num_pic_regs = 4,
};
static void sparc_m7_write_pmc(int idx, u64 val)
{
u64 pcr;
pcr = pcr_ops->read_pcr(idx);
/* ensure ov and ntc are reset */
pcr &= ~(PCR_N4_OV | PCR_N4_NTC);
pcr_ops->write_pic(idx, val & 0xffffffff);
pcr_ops->write_pcr(idx, pcr);
}
static const struct sparc_pmu sparc_m7_pmu = {
.event_map = niagara4_event_map,
.cache_map = &niagara4_cache_map,
.max_events = ARRAY_SIZE(niagara4_perfmon_event_map),
.read_pmc = sparc_vt_read_pmc,
.write_pmc = sparc_m7_write_pmc,
.upper_shift = 5,
.lower_shift = 5,
.event_mask = 0x7ff,
.user_bit = PCR_N4_UTRACE,
.priv_bit = PCR_N4_STRACE,
/* We explicitly don't support hypervisor tracing. */
.hv_bit = 0,
.irq_bit = PCR_N4_TOE,
.upper_nop = 0,
.lower_nop = 0,
.flags = 0,
.max_hw_events = 4,
.num_pcrs = 4,
.num_pic_regs = 4,
};
static const struct sparc_pmu *sparc_pmu __read_mostly;
static u64 event_encoding(u64 event_id, int idx)
@ -960,6 +996,8 @@ static void calculate_single_pcr(struct cpu_hw_events *cpuc)
cpuc->pcr[0] |= cpuc->event[0]->hw.config_base;
}
static void sparc_pmu_start(struct perf_event *event, int flags);
/* On this PMU each PIC has it's own PCR control register. */
static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
{
@ -972,20 +1010,13 @@ static void calculate_multiple_pcrs(struct cpu_hw_events *cpuc)
struct perf_event *cp = cpuc->event[i];
struct hw_perf_event *hwc = &cp->hw;
int idx = hwc->idx;
u64 enc;
if (cpuc->current_idx[i] != PIC_NO_INDEX)
continue;
sparc_perf_event_set_period(cp, hwc, idx);
cpuc->current_idx[i] = idx;
enc = perf_event_get_enc(cpuc->events[i]);
cpuc->pcr[idx] &= ~mask_for_index(idx);
if (hwc->state & PERF_HES_STOPPED)
cpuc->pcr[idx] |= nop_for_index(idx);
else
cpuc->pcr[idx] |= event_encoding(enc, idx);
sparc_pmu_start(cp, PERF_EF_RELOAD);
}
out:
for (i = 0; i < cpuc->n_events; i++) {
@ -1101,7 +1132,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags)
int i;
local_irq_save(flags);
perf_pmu_disable(event->pmu);
for (i = 0; i < cpuc->n_events; i++) {
if (event == cpuc->event[i]) {
@ -1127,7 +1157,6 @@ static void sparc_pmu_del(struct perf_event *event, int _flags)
}
}
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
}
@ -1361,7 +1390,6 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags)
unsigned long flags;
local_irq_save(flags);
perf_pmu_disable(event->pmu);
n0 = cpuc->n_events;
if (n0 >= sparc_pmu->max_hw_events)
@ -1394,7 +1422,6 @@ static int sparc_pmu_add(struct perf_event *event, int ef_flags)
ret = 0;
out:
perf_pmu_enable(event->pmu);
local_irq_restore(flags);
return ret;
}
@ -1667,6 +1694,10 @@ static bool __init supported_pmu(void)
sparc_pmu = &niagara4_pmu;
return true;
}
if (!strcmp(sparc_pmu_type, "sparc-m7")) {
sparc_pmu = &sparc_m7_pmu;
return true;
}
return false;
}

View File

@ -287,6 +287,8 @@ void arch_trigger_all_cpu_backtrace(bool include_self)
printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
gp->tpc, gp->o7, gp->i7, gp->rpc);
}
touch_nmi_watchdog();
}
memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));
@ -362,6 +364,8 @@ static void pmu_snapshot_all_cpus(void)
(cpu == this_cpu ? '*' : ' '), cpu,
pp->pcr[0], pp->pcr[1], pp->pcr[2], pp->pcr[3],
pp->pic[0], pp->pic[1], pp->pic[2], pp->pic[3]);
touch_nmi_watchdog();
}
memset(global_cpu_snapshot, 0, sizeof(global_cpu_snapshot));

View File

@ -8,9 +8,11 @@
.text
ENTRY(memmove) /* o0=dst o1=src o2=len */
mov %o0, %g1
brz,pn %o2, 99f
mov %o0, %g1
cmp %o0, %o1
bleu,pt %xcc, memcpy
bleu,pt %xcc, 2f
add %o1, %o2, %g7
cmp %g7, %o0
bleu,pt %xcc, memcpy
@ -24,7 +26,34 @@ ENTRY(memmove) /* o0=dst o1=src o2=len */
stb %g7, [%o0]
bne,pt %icc, 1b
sub %o0, 1, %o0
99:
retl
mov %g1, %o0
/* We can't just call memcpy for these memmove cases. On some
* chips the memcpy uses cache initializing stores and when dst
* and src are close enough, those can clobber the source data
* before we've loaded it in.
*/
2: or %o0, %o1, %g7
or %o2, %g7, %g7
andcc %g7, 0x7, %g0
bne,pn %xcc, 4f
nop
3: ldx [%o1], %g7
add %o1, 8, %o1
subcc %o2, 8, %o2
add %o0, 8, %o0
bne,pt %icc, 3b
stx %g7, [%o0 - 0x8]
ba,a,pt %xcc, 99b
4: ldub [%o1], %g7
add %o1, 1, %o1
subcc %o2, 1, %o2
add %o0, 1, %o0
bne,pt %icc, 4b
stb %g7, [%o0 - 0x1]
ba,a,pt %xcc, 99b
ENDPROC(memmove)

View File

@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_irq)(struct pci_dev *dev);
extern bool mp_should_keep_irq(struct device *dev);
struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val);

View File

@ -513,31 +513,6 @@ void __init pcibios_set_cache_line_size(void)
}
}
/*
* Some device drivers assume dev->irq won't change after calling
* pci_disable_device(). So delay releasing of IRQ resource to driver
* unbinding time. Otherwise it will break PM subsystem and drivers
* like xen-pciback etc.
*/
static int pci_irq_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
struct pci_dev *dev = to_pci_dev(data);
if (action != BUS_NOTIFY_UNBOUND_DRIVER)
return NOTIFY_DONE;
if (pcibios_disable_irq)
pcibios_disable_irq(dev);
return NOTIFY_OK;
}
static struct notifier_block pci_irq_nb = {
.notifier_call = pci_irq_notifier,
.priority = INT_MIN,
};
int __init pcibios_init(void)
{
if (!raw_pci_ops) {
@ -550,9 +525,6 @@ int __init pcibios_init(void)
if (pci_bf_sort >= pci_force_bf)
pci_sort_breadthfirst();
bus_register_notifier(&pci_bus_type, &pci_irq_nb);
return 0;
}
@ -711,6 +683,12 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return 0;
}
void pcibios_disable_device (struct pci_dev *dev)
{
if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
pcibios_disable_irq(dev);
}
int pci_ext_cfg_avail(void)
{
if (raw_pci_ext_ops)

View File

@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{
if (dev->irq_managed && dev->irq > 0) {
if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
dev->irq > 0) {
mp_unmap_irq(dev->irq);
dev->irq_managed = 0;
dev->irq = 0;
}
}

View File

@ -1256,9 +1256,22 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0;
}
bool mp_should_keep_irq(struct device *dev)
{
if (dev->power.is_prepared)
return true;
#ifdef CONFIG_PM
if (dev->power.runtime_status == RPM_SUSPENDING)
return true;
#endif
return false;
}
static void pirq_disable_irq(struct pci_dev *dev)
{
if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) {
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq);
dev->irq = 0;
dev->irq_managed = 0;

View File

@ -485,6 +485,14 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
if (!pin || !dev->irq_managed || dev->irq <= 0)
return;
/* Keep IOAPIC pin configuration when suspending */
if (dev->dev.power.is_prepared)
return;
#ifdef CONFIG_PM
if (dev->dev.power.runtime_status == RPM_SUSPENDING)
return;
#endif
entry = acpi_pci_irq_lookup(dev, pin);
if (!entry)
return;
@ -505,6 +513,5 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
if (gsi >= 0) {
acpi_unregister_gsi(gsi);
dev->irq_managed = 0;
dev->irq = 0;
}
}

View File

@ -37,11 +37,11 @@ static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
deepidle = true;
ret = mvebu_v7_cpu_suspend(deepidle);
cpu_pm_exit();
if (ret)
return ret;
cpu_pm_exit();
return index;
}
@ -50,17 +50,17 @@ static struct cpuidle_driver armadaxp_idle_driver = {
.states[0] = ARM_CPUIDLE_WFI_STATE,
.states[1] = {
.enter = mvebu_v7_enter_idle,
.exit_latency = 10,
.exit_latency = 100,
.power_usage = 50,
.target_residency = 100,
.target_residency = 1000,
.name = "MV CPU IDLE",
.desc = "CPU power down",
},
.states[2] = {
.enter = mvebu_v7_enter_idle,
.exit_latency = 100,
.exit_latency = 1000,
.power_usage = 5,
.target_residency = 1000,
.target_residency = 10000,
.flags = MVEBU_V7_FLAG_DEEP_IDLE,
.name = "MV CPU DEEP IDLE",
.desc = "CPU and L2 Fabric power down",

View File

@ -97,6 +97,12 @@
#define DRIVER_NAME "pl08xdmac"
#define PL80X_DMA_BUSWIDTHS \
BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \
BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)
static struct amba_driver pl08x_amba_driver;
struct pl08x_driver_data;
@ -2070,6 +2076,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->memcpy.device_pause = pl08x_pause;
pl08x->memcpy.device_resume = pl08x_resume;
pl08x->memcpy.device_terminate_all = pl08x_terminate_all;
pl08x->memcpy.src_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->memcpy.dst_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM);
pl08x->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
/* Initialize slave engine */
dma_cap_set(DMA_SLAVE, pl08x->slave.cap_mask);
@ -2086,6 +2096,10 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->slave.device_pause = pl08x_pause;
pl08x->slave.device_resume = pl08x_resume;
pl08x->slave.device_terminate_all = pl08x_terminate_all;
pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
pl08x->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
/* Get the platform data */
pl08x->pd = dev_get_platdata(&adev->dev);

View File

@ -238,93 +238,126 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first)
}
/*
* atc_get_current_descriptors -
* locate the descriptor which equal to physical address in DSCR
* @atchan: the channel we want to start
* @dscr_addr: physical descriptor address in DSCR
* atc_get_desc_by_cookie - get the descriptor of a cookie
* @atchan: the DMA channel
* @cookie: the cookie to get the descriptor for
*/
static struct at_desc *atc_get_current_descriptors(struct at_dma_chan *atchan,
u32 dscr_addr)
static struct at_desc *atc_get_desc_by_cookie(struct at_dma_chan *atchan,
dma_cookie_t cookie)
{
struct at_desc *desc, *_desc, *child, *desc_cur = NULL;
struct at_desc *desc, *_desc;
list_for_each_entry_safe(desc, _desc, &atchan->queue, desc_node) {
if (desc->txd.cookie == cookie)
return desc;
}
list_for_each_entry_safe(desc, _desc, &atchan->active_list, desc_node) {
if (desc->lli.dscr == dscr_addr) {
desc_cur = desc;
break;
}
list_for_each_entry(child, &desc->tx_list, desc_node) {
if (child->lli.dscr == dscr_addr) {
desc_cur = child;
break;
}
}
if (desc->txd.cookie == cookie)
return desc;
}
return desc_cur;
return NULL;
}
/*
* atc_get_bytes_left -
* Get the number of bytes residue in dma buffer,
* @chan: the channel we want to start
/**
* atc_calc_bytes_left - calculates the number of bytes left according to the
* value read from CTRLA.
*
* @current_len: the number of bytes left before reading CTRLA
* @ctrla: the value of CTRLA
* @desc: the descriptor containing the transfer width
*/
static int atc_get_bytes_left(struct dma_chan *chan)
static inline int atc_calc_bytes_left(int current_len, u32 ctrla,
struct at_desc *desc)
{
return current_len - ((ctrla & ATC_BTSIZE_MAX) << desc->tx_width);
}
/**
* atc_calc_bytes_left_from_reg - calculates the number of bytes left according
* to the current value of CTRLA.
*
* @current_len: the number of bytes left before reading CTRLA
* @atchan: the channel to read CTRLA for
* @desc: the descriptor containing the transfer width
*/
static inline int atc_calc_bytes_left_from_reg(int current_len,
struct at_dma_chan *atchan, struct at_desc *desc)
{
u32 ctrla = channel_readl(atchan, CTRLA);
return atc_calc_bytes_left(current_len, ctrla, desc);
}
/**
* atc_get_bytes_left - get the number of bytes residue for a cookie
* @chan: DMA channel
* @cookie: transaction identifier to check status of
*/
static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie)
{
struct at_dma_chan *atchan = to_at_dma_chan(chan);
struct at_dma *atdma = to_at_dma(chan->device);
int chan_id = atchan->chan_common.chan_id;
struct at_desc *desc_first = atc_first_active(atchan);
struct at_desc *desc_cur;
int ret = 0, count = 0;
struct at_desc *desc;
int ret;
u32 ctrla, dscr;
/*
* Initialize necessary values in the first time.
* remain_desc record remain desc length.
* If the cookie doesn't match to the currently running transfer then
* we can return the total length of the associated DMA transfer,
* because it is still queued.
*/
if (atchan->remain_desc == 0)
/* First descriptor embedds the transaction length */
atchan->remain_desc = desc_first->len;
desc = atc_get_desc_by_cookie(atchan, cookie);
if (desc == NULL)
return -EINVAL;
else if (desc != desc_first)
return desc->total_len;
/*
* This happens when current descriptor transfer complete.
* The residual buffer size should reduce current descriptor length.
*/
if (unlikely(test_bit(ATC_IS_BTC, &atchan->status))) {
clear_bit(ATC_IS_BTC, &atchan->status);
desc_cur = atc_get_current_descriptors(atchan,
channel_readl(atchan, DSCR));
if (!desc_cur) {
ret = -EINVAL;
goto out;
}
/* cookie matches to the currently running transfer */
ret = desc_first->total_len;
count = (desc_cur->lli.ctrla & ATC_BTSIZE_MAX)
<< desc_first->tx_width;
if (atchan->remain_desc < count) {
ret = -EINVAL;
goto out;
}
if (desc_first->lli.dscr) {
/* hardware linked list transfer */
atchan->remain_desc -= count;
ret = atchan->remain_desc;
} else {
/*
* Get residual bytes when current
* descriptor transfer in progress.
* Calculate the residue by removing the length of the child
* descriptors already transferred from the total length.
* To get the current child descriptor we can use the value of
* the channel's DSCR register and compare it against the value
* of the hardware linked list structure of each child
* descriptor.
*/
count = (channel_readl(atchan, CTRLA) & ATC_BTSIZE_MAX)
<< (desc_first->tx_width);
ret = atchan->remain_desc - count;
}
/*
* Check fifo empty.
*/
if (!(dma_readl(atdma, CHSR) & AT_DMA_EMPT(chan_id)))
atc_issue_pending(chan);
out:
ctrla = channel_readl(atchan, CTRLA);
rmb(); /* ensure CTRLA is read before DSCR */
dscr = channel_readl(atchan, DSCR);
/* for the first descriptor we can be more accurate */
if (desc_first->lli.dscr == dscr)
return atc_calc_bytes_left(ret, ctrla, desc_first);
ret -= desc_first->len;
list_for_each_entry(desc, &desc_first->tx_list, desc_node) {
if (desc->lli.dscr == dscr)
break;
ret -= desc->len;
}
/*
* For the last descriptor in the chain we can calculate
* the remaining bytes using the channel's register.
* Note that the transfer width of the first and last
* descriptor may differ.
*/
if (!desc->lli.dscr)
ret = atc_calc_bytes_left_from_reg(ret, atchan, desc);
} else {
/* single transfer */
ret = atc_calc_bytes_left_from_reg(ret, atchan, desc_first);
}
return ret;
}
@ -539,8 +572,6 @@ static irqreturn_t at_dma_interrupt(int irq, void *dev_id)
/* Give information to tasklet */
set_bit(ATC_IS_ERROR, &atchan->status);
}
if (pending & AT_DMA_BTC(i))
set_bit(ATC_IS_BTC, &atchan->status);
tasklet_schedule(&atchan->tasklet);
ret = IRQ_HANDLED;
}
@ -653,14 +684,18 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
desc->lli.ctrlb = ctrlb;
desc->txd.cookie = 0;
desc->len = xfer_count << src_width;
atc_desc_chain(&first, &prev, desc);
}
/* First descriptor of the chain embedds additional information */
first->txd.cookie = -EBUSY;
first->len = len;
first->total_len = len;
/* set transfer width for the calculation of the residue */
first->tx_width = src_width;
prev->tx_width = src_width;
/* set end-of-link to the last link descriptor of list*/
set_desc_eol(desc);
@ -752,6 +787,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
| ATC_SRC_WIDTH(mem_width)
| len >> mem_width;
desc->lli.ctrlb = ctrlb;
desc->len = len;
atc_desc_chain(&first, &prev, desc);
total_len += len;
@ -792,6 +828,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
| ATC_DST_WIDTH(mem_width)
| len >> reg_width;
desc->lli.ctrlb = ctrlb;
desc->len = len;
atc_desc_chain(&first, &prev, desc);
total_len += len;
@ -806,8 +843,11 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
/* First descriptor of the chain embedds additional information */
first->txd.cookie = -EBUSY;
first->len = total_len;
first->total_len = total_len;
/* set transfer width for the calculation of the residue */
first->tx_width = reg_width;
prev->tx_width = reg_width;
/* first link descriptor of list is responsible of flags */
first->txd.flags = flags; /* client is in control of this ack */
@ -872,6 +912,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
| ATC_FC_MEM2PER
| ATC_SIF(atchan->mem_if)
| ATC_DIF(atchan->per_if);
desc->len = period_len;
break;
case DMA_DEV_TO_MEM:
@ -883,6 +924,7 @@ atc_dma_cyclic_fill_desc(struct dma_chan *chan, struct at_desc *desc,
| ATC_FC_PER2MEM
| ATC_SIF(atchan->per_if)
| ATC_DIF(atchan->mem_if);
desc->len = period_len;
break;
default:
@ -964,7 +1006,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
/* First descriptor of the chain embedds additional information */
first->txd.cookie = -EBUSY;
first->len = buf_len;
first->total_len = buf_len;
first->tx_width = reg_width;
return &first->txd;
@ -1118,7 +1160,7 @@ atc_tx_status(struct dma_chan *chan,
spin_lock_irqsave(&atchan->lock, flags);
/* Get number of bytes left in the active transactions */
bytes = atc_get_bytes_left(chan);
bytes = atc_get_bytes_left(chan, cookie);
spin_unlock_irqrestore(&atchan->lock, flags);
@ -1214,7 +1256,6 @@ static int atc_alloc_chan_resources(struct dma_chan *chan)
spin_lock_irqsave(&atchan->lock, flags);
atchan->descs_allocated = i;
atchan->remain_desc = 0;
list_splice(&tmp_list, &atchan->free_list);
dma_cookie_init(chan);
spin_unlock_irqrestore(&atchan->lock, flags);
@ -1257,7 +1298,6 @@ static void atc_free_chan_resources(struct dma_chan *chan)
list_splice_init(&atchan->free_list, &list);
atchan->descs_allocated = 0;
atchan->status = 0;
atchan->remain_desc = 0;
dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
}

View File

@ -181,8 +181,9 @@ struct at_lli {
* @at_lli: hardware lli structure
* @txd: support for the async_tx api
* @desc_node: node on the channed descriptors list
* @len: total transaction bytecount
* @len: descriptor byte count
* @tx_width: transfer width
* @total_len: total transaction byte count
*/
struct at_desc {
/* FIRST values the hardware uses */
@ -194,6 +195,7 @@ struct at_desc {
struct list_head desc_node;
size_t len;
u32 tx_width;
size_t total_len;
};
static inline struct at_desc *
@ -213,7 +215,6 @@ txd_to_at_desc(struct dma_async_tx_descriptor *txd)
enum atc_status {
ATC_IS_ERROR = 0,
ATC_IS_PAUSED = 1,
ATC_IS_BTC = 2,
ATC_IS_CYCLIC = 24,
};
@ -231,7 +232,6 @@ enum atc_status {
* @save_cfg: configuration register that is saved on suspend/resume cycle
* @save_dscr: for cyclic operations, preserve next descriptor address in
* the cyclic list on suspend/resume cycle
* @remain_desc: to save remain desc length
* @dma_sconfig: configuration for slave transfers, passed via
* .device_config
* @lock: serializes enqueue/dequeue operations to descriptors lists
@ -251,7 +251,6 @@ struct at_dma_chan {
struct tasklet_struct tasklet;
u32 save_cfg;
u32 save_dscr;
u32 remain_desc;
struct dma_slave_config dma_sconfig;
spinlock_t lock;

View File

@ -26,6 +26,8 @@
#include "internal.h"
#define DRV_NAME "dw_dmac"
static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
struct of_dma *ofdma)
{
@ -284,7 +286,7 @@ static struct platform_driver dw_driver = {
.remove = dw_remove,
.shutdown = dw_shutdown,
.driver = {
.name = "dw_dmac",
.name = DRV_NAME,
.pm = &dw_dev_pm_ops,
.of_match_table = of_match_ptr(dw_dma_of_id_table),
.acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
@ -305,3 +307,4 @@ module_exit(dw_exit);
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver");
MODULE_ALIAS("platform:" DRV_NAME);

View File

@ -531,6 +531,10 @@ static int sdma_run_channel0(struct sdma_engine *sdma)
dev_err(sdma->dev, "Timeout waiting for CH0 ready\n");
}
/* Set bits of CONFIG register with dynamic context switching */
if (readl(sdma->regs + SDMA_H_CONFIG) == 0)
writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
return ret ? 0 : -ETIMEDOUT;
}
@ -1394,9 +1398,6 @@ static int sdma_init(struct sdma_engine *sdma)
writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR);
/* Set bits of CONFIG register with given context switching mode */
writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG);
/* Initializes channel's priorities */
sdma_set_channel_priority(&sdma->channel[0], 7);

View File

@ -645,6 +645,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
pr_debug(" sdma queue id: %d\n", q->properties.sdma_queue_id);
pr_debug(" sdma engine id: %d\n", q->properties.sdma_engine_id);
init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (retval != 0) {
@ -652,7 +653,14 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
return retval;
}
init_sdma_vm(dqm, q, qpd);
retval = mqd->load_mqd(mqd, q->mqd, 0,
0, NULL);
if (retval != 0) {
deallocate_sdma_queue(dqm, q->sdma_id);
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
return retval;
}
return 0;
}

View File

@ -44,7 +44,7 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
BUG_ON(!kq || !dev);
BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
pr_debug("kfd: In func %s initializing queue type %d size %d\n",
pr_debug("amdkfd: In func %s initializing queue type %d size %d\n",
__func__, KFD_QUEUE_TYPE_HIQ, queue_size);
nop.opcode = IT_NOP;
@ -69,12 +69,16 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
if (prop.doorbell_ptr == NULL)
if (prop.doorbell_ptr == NULL) {
pr_err("amdkfd: error init doorbell");
goto err_get_kernel_doorbell;
}
retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
if (retval != 0)
if (retval != 0) {
pr_err("amdkfd: error init pq queues size (%d)\n", queue_size);
goto err_pq_allocate_vidmem;
}
kq->pq_kernel_addr = kq->pq->cpu_ptr;
kq->pq_gpu_addr = kq->pq->gpu_addr;
@ -165,10 +169,8 @@ static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
err_eop_allocate_vidmem:
kfd_gtt_sa_free(dev, kq->pq);
err_pq_allocate_vidmem:
pr_err("kfd: error init pq\n");
kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
err_get_kernel_doorbell:
pr_err("kfd: error init doorbell");
return false;
}
@ -187,6 +189,8 @@ static void uninitialize(struct kernel_queue *kq)
else if (kq->queue->properties.type == KFD_QUEUE_TYPE_DIQ)
kfd_gtt_sa_free(kq->dev, kq->fence_mem_obj);
kq->mqd->uninit_mqd(kq->mqd, kq->queue->mqd, kq->queue->mqd_mem_obj);
kfd_gtt_sa_free(kq->dev, kq->rptr_mem);
kfd_gtt_sa_free(kq->dev, kq->wptr_mem);
kq->ops_asic_specific.uninitialize(kq);
@ -211,7 +215,7 @@ static int acquire_packet_buffer(struct kernel_queue *kq,
queue_address = (unsigned int *)kq->pq_kernel_addr;
queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t);
pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
pr_debug("amdkfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
__func__, rptr, wptr, queue_address);
available_size = (rptr - 1 - wptr + queue_size_dwords) %
@ -296,7 +300,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
}
if (kq->ops.initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
pr_err("kfd: failed to init kernel queue\n");
pr_err("amdkfd: failed to init kernel queue\n");
kfree(kq);
return NULL;
}
@ -319,7 +323,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
BUG_ON(!dev);
pr_err("kfd: starting kernel queue test\n");
pr_err("amdkfd: starting kernel queue test\n");
kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
BUG_ON(!kq);
@ -330,7 +334,7 @@ static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
buffer[i] = kq->nop_packet;
kq->ops.submit_packet(kq);
pr_err("kfd: ending kernel queue test\n");
pr_err("amdkfd: ending kernel queue test\n");
}

View File

@ -50,7 +50,7 @@ config DRM_EXYNOS_DSI
config DRM_EXYNOS_DP
bool "EXYNOS DRM DP driver support"
depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
depends on (DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON) && ARCH_EXYNOS && (DRM_PTN3460=n || DRM_PTN3460=y || DRM_PTN3460=DRM_EXYNOS)
default DRM_EXYNOS
select DRM_PANEL
help

View File

@ -888,8 +888,8 @@ static int decon_probe(struct platform_device *pdev)
of_node_put(i80_if_timings);
ctx->regs = of_iomap(dev->of_node, 0);
if (IS_ERR(ctx->regs)) {
ret = PTR_ERR(ctx->regs);
if (!ctx->regs) {
ret = -ENOMEM;
goto err_del_component;
}

View File

@ -1,245 +0,0 @@
/*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* Authors:
* Inki Dae <inki.dae@samsung.com>
* Joonyoung Shim <jy0922.shim@samsung.com>
* Seung-Woo Kim <sw0312.kim@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
#include "exynos_drm_connector.h"
#define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\
drm_connector)
struct exynos_drm_connector {
struct drm_connector drm_connector;
uint32_t encoder_id;
struct exynos_drm_display *display;
};
static int exynos_drm_connector_get_modes(struct drm_connector *connector)
{
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
struct exynos_drm_display *display = exynos_connector->display;
struct edid *edid = NULL;
unsigned int count = 0;
int ret;
/*
* if get_edid() exists then get_edid() callback of hdmi side
* is called to get edid data through i2c interface else
* get timing from the FIMD driver(display controller).
*
* P.S. in case of lcd panel, count is always 1 if success
* because lcd panel has only one mode.
*/
if (display->ops->get_edid) {
edid = display->ops->get_edid(display, connector);
if (IS_ERR_OR_NULL(edid)) {
ret = PTR_ERR(edid);
edid = NULL;
DRM_ERROR("Panel operation get_edid failed %d\n", ret);
goto out;
}
count = drm_add_edid_modes(connector, edid);
if (!count) {
DRM_ERROR("Add edid modes failed %d\n", count);
goto out;
}
drm_mode_connector_update_edid_property(connector, edid);
} else {
struct exynos_drm_panel_info *panel;
struct drm_display_mode *mode = drm_mode_create(connector->dev);
if (!mode) {
DRM_ERROR("failed to create a new display mode.\n");
return 0;
}
if (display->ops->get_panel)
panel = display->ops->get_panel(display);
else {
drm_mode_destroy(connector->dev, mode);
return 0;
}
drm_display_mode_from_videomode(&panel->vm, mode);
mode->width_mm = panel->width_mm;
mode->height_mm = panel->height_mm;
connector->display_info.width_mm = mode->width_mm;
connector->display_info.height_mm = mode->height_mm;
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
count = 1;
}
out:
kfree(edid);
return count;
}
static int exynos_drm_connector_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
struct exynos_drm_display *display = exynos_connector->display;
int ret = MODE_BAD;
DRM_DEBUG_KMS("%s\n", __FILE__);
if (display->ops->check_mode)
if (!display->ops->check_mode(display, mode))
ret = MODE_OK;
return ret;
}
static struct drm_encoder *exynos_drm_best_encoder(
struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
return drm_encoder_find(dev, exynos_connector->encoder_id);
}
static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
.get_modes = exynos_drm_connector_get_modes,
.mode_valid = exynos_drm_connector_mode_valid,
.best_encoder = exynos_drm_best_encoder,
};
static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
unsigned int max_width, unsigned int max_height)
{
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
struct exynos_drm_display *display = exynos_connector->display;
unsigned int width, height;
width = max_width;
height = max_height;
/*
* if specific driver want to find desired_mode using maxmum
* resolution then get max width and height from that driver.
*/
if (display->ops->get_max_resol)
display->ops->get_max_resol(display, &width, &height);
return drm_helper_probe_single_connector_modes(connector, width,
height);
}
/* get detection status of display device. */
static enum drm_connector_status
exynos_drm_connector_detect(struct drm_connector *connector, bool force)
{
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
struct exynos_drm_display *display = exynos_connector->display;
enum drm_connector_status status = connector_status_disconnected;
if (display->ops->is_connected) {
if (display->ops->is_connected(display))
status = connector_status_connected;
else
status = connector_status_disconnected;
}
return status;
}
static void exynos_drm_connector_destroy(struct drm_connector *connector)
{
struct exynos_drm_connector *exynos_connector =
to_exynos_connector(connector);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
kfree(exynos_connector);
}
static struct drm_connector_funcs exynos_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.fill_modes = exynos_drm_connector_fill_modes,
.detect = exynos_drm_connector_detect,
.destroy = exynos_drm_connector_destroy,
};
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
struct drm_encoder *encoder)
{
struct exynos_drm_connector *exynos_connector;
struct exynos_drm_display *display = exynos_drm_get_display(encoder);
struct drm_connector *connector;
int type;
int err;
exynos_connector = kzalloc(sizeof(*exynos_connector), GFP_KERNEL);
if (!exynos_connector)
return NULL;
connector = &exynos_connector->drm_connector;
switch (display->type) {
case EXYNOS_DISPLAY_TYPE_HDMI:
type = DRM_MODE_CONNECTOR_HDMIA;
connector->interlace_allowed = true;
connector->polled = DRM_CONNECTOR_POLL_HPD;
break;
case EXYNOS_DISPLAY_TYPE_VIDI:
type = DRM_MODE_CONNECTOR_VIRTUAL;
connector->polled = DRM_CONNECTOR_POLL_HPD;
break;
default:
type = DRM_MODE_CONNECTOR_Unknown;
break;
}
drm_connector_init(dev, connector, &exynos_connector_funcs, type);
drm_connector_helper_add(connector, &exynos_connector_helper_funcs);
err = drm_connector_register(connector);
if (err)
goto err_connector;
exynos_connector->encoder_id = encoder->base.id;
exynos_connector->display = display;
connector->dpms = DRM_MODE_DPMS_OFF;
connector->encoder = encoder;
err = drm_mode_connector_attach_encoder(connector, encoder);
if (err) {
DRM_ERROR("failed to attach a connector to a encoder\n");
goto err_sysfs;
}
DRM_DEBUG_KMS("connector has been created\n");
return connector;
err_sysfs:
drm_connector_unregister(connector);
err_connector:
drm_connector_cleanup(connector);
kfree(exynos_connector);
return NULL;
}

View File

@ -1,20 +0,0 @@
/*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* Authors:
* Inki Dae <inki.dae@samsung.com>
* Joonyoung Shim <jy0922.shim@samsung.com>
* Seung-Woo Kim <sw0312.kim@samsung.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef _EXYNOS_DRM_CONNECTOR_H_
#define _EXYNOS_DRM_CONNECTOR_H_
struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
struct drm_encoder *encoder);
#endif

View File

@ -284,14 +284,9 @@ static void fimd_clear_channel(struct fimd_context *ctx)
}
}
static int fimd_ctx_initialize(struct fimd_context *ctx,
static int fimd_iommu_attach_devices(struct fimd_context *ctx,
struct drm_device *drm_dev)
{
struct exynos_drm_private *priv;
priv = drm_dev->dev_private;
ctx->drm_dev = drm_dev;
ctx->pipe = priv->pipe++;
/* attach this sub driver to iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev)) {
@ -313,7 +308,7 @@ static int fimd_ctx_initialize(struct fimd_context *ctx,
return 0;
}
static void fimd_ctx_remove(struct fimd_context *ctx)
static void fimd_iommu_detach_devices(struct fimd_context *ctx)
{
/* detach this sub driver from iommu mapping if supported. */
if (is_drm_iommu_supported(ctx->drm_dev))
@ -1056,25 +1051,23 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
{
struct fimd_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
struct exynos_drm_private *priv = drm_dev->dev_private;
int ret;
ret = fimd_ctx_initialize(ctx, drm_dev);
if (ret) {
DRM_ERROR("fimd_ctx_initialize failed.\n");
return ret;
}
ctx->drm_dev = drm_dev;
ctx->pipe = priv->pipe++;
ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
EXYNOS_DISPLAY_TYPE_LCD,
&fimd_crtc_ops, ctx);
if (IS_ERR(ctx->crtc)) {
fimd_ctx_remove(ctx);
return PTR_ERR(ctx->crtc);
}
if (ctx->display)
exynos_drm_create_enc_conn(drm_dev, ctx->display);
ret = fimd_iommu_attach_devices(ctx, drm_dev);
if (ret)
return ret;
return 0;
}
@ -1086,10 +1079,10 @@ static void fimd_unbind(struct device *dev, struct device *master,
fimd_dpms(ctx->crtc, DRM_MODE_DPMS_OFF);
fimd_iommu_detach_devices(ctx);
if (ctx->display)
exynos_dpi_remove(ctx->display);
fimd_ctx_remove(ctx);
}
static const struct component_ops fimd_component_ops = {

View File

@ -175,7 +175,7 @@ static int exynos_disable_plane(struct drm_plane *plane)
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
if (exynos_crtc->ops->win_disable)
if (exynos_crtc && exynos_crtc->ops->win_disable)
exynos_crtc->ops->win_disable(exynos_crtc,
exynos_plane->zpos);

View File

@ -37,6 +37,7 @@
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_dp_helper.h>
#include <drm/drm_crtc_helper.h>
@ -2416,6 +2417,14 @@ intel_alloc_plane_obj(struct intel_crtc *crtc,
return false;
}
/* Update plane->state->fb to match plane->fb after driver-internal updates */
static void
update_state_fb(struct drm_plane *plane)
{
if (plane->fb != plane->state->fb)
drm_atomic_set_fb_for_plane(plane->state, plane->fb);
}
static void
intel_find_plane_obj(struct intel_crtc *intel_crtc,
struct intel_initial_plane_config *plane_config)
@ -2462,6 +2471,8 @@ intel_find_plane_obj(struct intel_crtc *intel_crtc,
break;
}
}
update_state_fb(intel_crtc->base.primary);
}
static void i9xx_update_primary_plane(struct drm_crtc *crtc,
@ -6602,6 +6613,10 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
val = I915_READ(DSPCNTR(plane));
if (!(val & DISPLAY_PLANE_ENABLE))
return;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
@ -6610,8 +6625,6 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base;
val = I915_READ(DSPCNTR(plane));
if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED)
plane_config->tiling = I915_TILING_X;
@ -6650,6 +6663,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size);
crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
}
static void chv_crtc_clock_get(struct intel_crtc *crtc,
@ -7643,6 +7657,9 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base;
val = I915_READ(PLANE_CTL(pipe, 0));
if (!(val & PLANE_CTL_ENABLE))
goto error;
if (val & PLANE_CTL_TILED_MASK)
plane_config->tiling = I915_TILING_X;
@ -7687,6 +7704,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size);
crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
return;
error:
@ -7730,6 +7748,10 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
struct drm_framebuffer *fb;
struct intel_framebuffer *intel_fb;
val = I915_READ(DSPCNTR(pipe));
if (!(val & DISPLAY_PLANE_ENABLE))
return;
intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
if (!intel_fb) {
DRM_DEBUG_KMS("failed to alloc fb\n");
@ -7738,8 +7760,6 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
fb = &intel_fb->base;
val = I915_READ(DSPCNTR(pipe));
if (INTEL_INFO(dev)->gen >= 4)
if (val & DISPPLANE_TILED)
plane_config->tiling = I915_TILING_X;
@ -7778,6 +7798,7 @@ ironlake_get_initial_plane_config(struct intel_crtc *crtc,
plane_config->size);
crtc->base.primary->fb = fb;
update_state_fb(crtc->base.primary);
}
static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
@ -9816,6 +9837,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
drm_gem_object_reference(&obj->base);
crtc->primary->fb = fb;
update_state_fb(crtc->primary);
work->pending_flip_obj = obj;
@ -9884,6 +9906,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
cleanup_pending:
atomic_dec(&intel_crtc->unpin_work_count);
crtc->primary->fb = old_fb;
update_state_fb(crtc->primary);
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
mutex_unlock(&dev->struct_mutex);
@ -13718,6 +13741,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
to_intel_crtc(c)->pipe);
drm_framebuffer_unreference(c->primary->fb);
c->primary->fb = NULL;
update_state_fb(c->primary);
}
}
mutex_unlock(&dev->struct_mutex);

View File

@ -340,11 +340,13 @@ nvkm_devobj_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
/* switch mmio to cpu's native endianness */
#ifndef __BIG_ENDIAN
if (ioread32_native(map + 0x000004) != 0x00000000)
if (ioread32_native(map + 0x000004) != 0x00000000) {
#else
if (ioread32_native(map + 0x000004) == 0x00000000)
if (ioread32_native(map + 0x000004) == 0x00000000) {
#endif
iowrite32_native(0x01000001, map + 0x000004);
ioread32_native(map);
}
/* read boot0 and strapping information */
boot0 = ioread32_native(map + 0x000000);

View File

@ -140,6 +140,49 @@ gm100_identify(struct nvkm_device *device)
device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
#endif
break;
case 0x126:
device->cname = "GM206";
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nvkm_bios_oclass;
device->oclass[NVDEV_SUBDEV_GPIO ] = gk104_gpio_oclass;
device->oclass[NVDEV_SUBDEV_I2C ] = gm204_i2c_oclass;
device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass;
#if 0
/* looks to be some non-trivial changes */
device->oclass[NVDEV_SUBDEV_CLK ] = &gk104_clk_oclass;
/* priv ring says no to 0x10eb14 writes */
device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass;
#endif
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
device->oclass[NVDEV_SUBDEV_DEVINIT] = gm204_devinit_oclass;
device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
device->oclass[NVDEV_SUBDEV_BUS ] = gf100_bus_oclass;
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass;
device->oclass[NVDEV_SUBDEV_IBUS ] = &gk104_ibus_oclass;
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
device->oclass[NVDEV_SUBDEV_MMU ] = &gf100_mmu_oclass;
device->oclass[NVDEV_SUBDEV_BAR ] = &gf100_bar_oclass;
device->oclass[NVDEV_SUBDEV_PMU ] = gk208_pmu_oclass;
#if 0
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
#endif
device->oclass[NVDEV_ENGINE_DMAOBJ ] = gf110_dmaeng_oclass;
#if 0
device->oclass[NVDEV_ENGINE_FIFO ] = gk208_fifo_oclass;
device->oclass[NVDEV_ENGINE_SW ] = gf100_sw_oclass;
device->oclass[NVDEV_ENGINE_GR ] = gm107_gr_oclass;
#endif
device->oclass[NVDEV_ENGINE_DISP ] = gm204_disp_oclass;
#if 0
device->oclass[NVDEV_ENGINE_CE0 ] = &gm204_ce0_oclass;
device->oclass[NVDEV_ENGINE_CE1 ] = &gm204_ce1_oclass;
device->oclass[NVDEV_ENGINE_CE2 ] = &gm204_ce2_oclass;
device->oclass[NVDEV_ENGINE_MSVLD ] = &gk104_msvld_oclass;
device->oclass[NVDEV_ENGINE_MSPDEC ] = &gk104_mspdec_oclass;
device->oclass[NVDEV_ENGINE_MSPPP ] = &gf100_msppp_oclass;
#endif
break;
default:

View File

@ -502,72 +502,57 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
{
struct nvkm_device *device = nv_device(subdev);
struct nv04_fifo_priv *priv = (void *)subdev;
uint32_t status, reassign;
int cnt = 0;
u32 mask = nv_rd32(priv, NV03_PFIFO_INTR_EN_0);
u32 stat = nv_rd32(priv, NV03_PFIFO_INTR_0) & mask;
u32 reassign, chid, get, sem;
reassign = nv_rd32(priv, NV03_PFIFO_CACHES) & 1;
while ((status = nv_rd32(priv, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) {
uint32_t chid, get;
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
nv_wr32(priv, NV03_PFIFO_CACHES, 0);
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
chid = nv_rd32(priv, NV03_PFIFO_CACHE1_PUSH1) & priv->base.max;
get = nv_rd32(priv, NV03_PFIFO_CACHE1_GET);
if (status & NV_PFIFO_INTR_CACHE_ERROR) {
nv04_fifo_cache_error(device, priv, chid, get);
status &= ~NV_PFIFO_INTR_CACHE_ERROR;
}
if (status & NV_PFIFO_INTR_DMA_PUSHER) {
nv04_fifo_dma_pusher(device, priv, chid);
status &= ~NV_PFIFO_INTR_DMA_PUSHER;
}
if (status & NV_PFIFO_INTR_SEMAPHORE) {
uint32_t sem;
status &= ~NV_PFIFO_INTR_SEMAPHORE;
nv_wr32(priv, NV03_PFIFO_INTR_0,
NV_PFIFO_INTR_SEMAPHORE);
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
if (device->card_type == NV_50) {
if (status & 0x00000010) {
status &= ~0x00000010;
nv_wr32(priv, 0x002100, 0x00000010);
}
if (status & 0x40000000) {
nv_wr32(priv, 0x002100, 0x40000000);
nvkm_fifo_uevent(&priv->base);
status &= ~0x40000000;
}
}
if (status) {
nv_warn(priv, "unknown intr 0x%08x, ch %d\n",
status, chid);
nv_wr32(priv, NV03_PFIFO_INTR_0, status);
status = 0;
}
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
if (stat & NV_PFIFO_INTR_CACHE_ERROR) {
nv04_fifo_cache_error(device, priv, chid, get);
stat &= ~NV_PFIFO_INTR_CACHE_ERROR;
}
if (status) {
nv_error(priv, "still angry after %d spins, halt\n", cnt);
nv_wr32(priv, 0x002140, 0);
nv_wr32(priv, 0x000140, 0);
if (stat & NV_PFIFO_INTR_DMA_PUSHER) {
nv04_fifo_dma_pusher(device, priv, chid);
stat &= ~NV_PFIFO_INTR_DMA_PUSHER;
}
nv_wr32(priv, 0x000100, 0x00000100);
if (stat & NV_PFIFO_INTR_SEMAPHORE) {
stat &= ~NV_PFIFO_INTR_SEMAPHORE;
nv_wr32(priv, NV03_PFIFO_INTR_0, NV_PFIFO_INTR_SEMAPHORE);
sem = nv_rd32(priv, NV10_PFIFO_CACHE1_SEMAPHORE);
nv_wr32(priv, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1);
nv_wr32(priv, NV03_PFIFO_CACHE1_GET, get + 4);
nv_wr32(priv, NV04_PFIFO_CACHE1_PULL0, 1);
}
if (device->card_type == NV_50) {
if (stat & 0x00000010) {
stat &= ~0x00000010;
nv_wr32(priv, 0x002100, 0x00000010);
}
if (stat & 0x40000000) {
nv_wr32(priv, 0x002100, 0x40000000);
nvkm_fifo_uevent(&priv->base);
stat &= ~0x40000000;
}
}
if (stat) {
nv_warn(priv, "unknown intr 0x%08x\n", stat);
nv_mask(priv, NV03_PFIFO_INTR_EN_0, stat, 0x00000000);
nv_wr32(priv, NV03_PFIFO_INTR_0, stat);
}
nv_wr32(priv, NV03_PFIFO_CACHES, reassign);
}
static int

View File

@ -1032,9 +1032,9 @@ gf100_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b);
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
mmio_refn(info, 0x418808, 0x00000000, s, b);
mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s));
}
void

View File

@ -851,9 +851,9 @@ gk104_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b);
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
mmio_refn(info, 0x418808, 0x00000000, s, b);
mmio_refn(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x41880c, 0x80000000 | (impl->bundle_size >> s));
mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit);
}

View File

@ -871,9 +871,9 @@ gm107_grctx_generate_bundle(struct gf100_grctx *info)
const int s = 8;
const int b = mmio_vram(info, impl->bundle_size, (1 << s), access);
mmio_refn(info, 0x408004, 0x00000000, s, b);
mmio_refn(info, 0x408008, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x408008, 0x80000000 | (impl->bundle_size >> s));
mmio_refn(info, 0x418e24, 0x00000000, s, b);
mmio_refn(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s), 0, b);
mmio_wr32(info, 0x418e28, 0x80000000 | (impl->bundle_size >> s));
mmio_wr32(info, 0x4064c8, (state_limit << 16) | token_limit);
}

View File

@ -74,7 +74,11 @@ dcb_i2c_parse(struct nvkm_bios *bios, u8 idx, struct dcb_i2c_entry *info)
u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
if (ent) {
if (ver >= 0x41) {
if (!(nv_ro32(bios, ent) & 0x80000000))
u32 ent_value = nv_ro32(bios, ent);
u8 i2c_port = (ent_value >> 27) & 0x1f;
u8 dpaux_port = (ent_value >> 22) & 0x1f;
/* value 0x1f means unused according to DCB 4.x spec */
if (i2c_port == 0x1f && dpaux_port == 0x1f)
info->type = DCB_I2C_UNUSED;
else
info->type = DCB_I2C_PMGR;

View File

@ -153,7 +153,7 @@ void radeon_kfd_device_init(struct radeon_device *rdev)
.compute_vmid_bitmap = 0xFF00,
.first_compute_pipe = 1,
.compute_pipe_count = 8 - 1,
.compute_pipe_count = 4 - 1,
};
radeon_doorbell_get_kfd_info(rdev,

View File

@ -173,17 +173,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
else
rbo->placements[i].lpfn = 0;
}
/*
* Use two-ended allocation depending on the buffer size to
* improve fragmentation quality.
* 512kb was measured as the most optimal number.
*/
if (rbo->tbo.mem.size > 512 * 1024) {
for (i = 0; i < c; i++) {
rbo->placements[i].flags |= TTM_PL_FLAG_TOPDOWN;
}
}
}
int radeon_bo_create(struct radeon_device *rdev,

View File

@ -289,9 +289,16 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
struct request_queue *q = bdev_get_queue(where->bdev);
unsigned short logical_block_size = queue_logical_block_size(q);
sector_t num_sectors;
unsigned int uninitialized_var(special_cmd_max_sectors);
/* Reject unsupported discard requests */
if ((rw & REQ_DISCARD) && !blk_queue_discard(q)) {
/*
* Reject unsupported discard and write same requests.
*/
if (rw & REQ_DISCARD)
special_cmd_max_sectors = q->limits.max_discard_sectors;
else if (rw & REQ_WRITE_SAME)
special_cmd_max_sectors = q->limits.max_write_same_sectors;
if ((rw & (REQ_DISCARD | REQ_WRITE_SAME)) && special_cmd_max_sectors == 0) {
dec_count(io, region, -EOPNOTSUPP);
return;
}
@ -317,7 +324,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
store_io_and_region_in_bio(bio, io, region);
if (rw & REQ_DISCARD) {
num_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining);
num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
remaining -= num_sectors;
} else if (rw & REQ_WRITE_SAME) {
@ -326,7 +333,7 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where,
*/
dp->get_page(dp, &page, &len, &offset);
bio_add_page(bio, page, logical_block_size, offset);
num_sectors = min_t(sector_t, q->limits.max_write_same_sectors, remaining);
num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
offset = 0;

View File

@ -20,6 +20,8 @@
#include <linux/log2.h>
#include <linux/dm-kcopyd.h>
#include "dm.h"
#include "dm-exception-store.h"
#define DM_MSG_PREFIX "snapshots"
@ -290,6 +292,16 @@ struct origin {
struct list_head snapshots;
};
/*
* This structure is allocated for each origin target
*/
struct dm_origin {
struct dm_dev *dev;
struct dm_target *ti;
unsigned split_boundary;
struct list_head hash_list;
};
/*
* Size of the hash table for origin volumes. If we make this
* the size of the minors list then it should be nearly perfect
@ -297,6 +309,7 @@ struct origin {
#define ORIGIN_HASH_SIZE 256
#define ORIGIN_MASK 0xFF
static struct list_head *_origins;
static struct list_head *_dm_origins;
static struct rw_semaphore _origins_lock;
static DECLARE_WAIT_QUEUE_HEAD(_pending_exceptions_done);
@ -310,12 +323,22 @@ static int init_origin_hash(void)
_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head),
GFP_KERNEL);
if (!_origins) {
DMERR("unable to allocate memory");
DMERR("unable to allocate memory for _origins");
return -ENOMEM;
}
for (i = 0; i < ORIGIN_HASH_SIZE; i++)
INIT_LIST_HEAD(_origins + i);
_dm_origins = kmalloc(ORIGIN_HASH_SIZE * sizeof(struct list_head),
GFP_KERNEL);
if (!_dm_origins) {
DMERR("unable to allocate memory for _dm_origins");
kfree(_origins);
return -ENOMEM;
}
for (i = 0; i < ORIGIN_HASH_SIZE; i++)
INIT_LIST_HEAD(_dm_origins + i);
init_rwsem(&_origins_lock);
return 0;
@ -324,6 +347,7 @@ static int init_origin_hash(void)
static void exit_origin_hash(void)
{
kfree(_origins);
kfree(_dm_origins);
}
static unsigned origin_hash(struct block_device *bdev)
@ -350,6 +374,30 @@ static void __insert_origin(struct origin *o)
list_add_tail(&o->hash_list, sl);
}
static struct dm_origin *__lookup_dm_origin(struct block_device *origin)
{
struct list_head *ol;
struct dm_origin *o;
ol = &_dm_origins[origin_hash(origin)];
list_for_each_entry (o, ol, hash_list)
if (bdev_equal(o->dev->bdev, origin))
return o;
return NULL;
}
static void __insert_dm_origin(struct dm_origin *o)
{
struct list_head *sl = &_dm_origins[origin_hash(o->dev->bdev)];
list_add_tail(&o->hash_list, sl);
}
static void __remove_dm_origin(struct dm_origin *o)
{
list_del(&o->hash_list);
}
/*
* _origins_lock must be held when calling this function.
* Returns number of snapshots registered using the supplied cow device, plus:
@ -1840,9 +1888,40 @@ static int snapshot_preresume(struct dm_target *ti)
static void snapshot_resume(struct dm_target *ti)
{
struct dm_snapshot *s = ti->private;
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL, *snap_merging = NULL;
struct dm_origin *o;
struct mapped_device *origin_md = NULL;
bool must_restart_merging = false;
down_read(&_origins_lock);
o = __lookup_dm_origin(s->origin->bdev);
if (o)
origin_md = dm_table_get_md(o->ti->table);
if (!origin_md) {
(void) __find_snapshots_sharing_cow(s, NULL, NULL, &snap_merging);
if (snap_merging)
origin_md = dm_table_get_md(snap_merging->ti->table);
}
if (origin_md == dm_table_get_md(ti->table))
origin_md = NULL;
if (origin_md) {
if (dm_hold(origin_md))
origin_md = NULL;
}
up_read(&_origins_lock);
if (origin_md) {
dm_internal_suspend_fast(origin_md);
if (snap_merging && test_bit(RUNNING_MERGE, &snap_merging->state_bits)) {
must_restart_merging = true;
stop_merge(snap_merging);
}
}
down_read(&_origins_lock);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
if (snap_src && snap_dest) {
down_write(&snap_src->lock);
@ -1851,8 +1930,16 @@ static void snapshot_resume(struct dm_target *ti)
up_write(&snap_dest->lock);
up_write(&snap_src->lock);
}
up_read(&_origins_lock);
if (origin_md) {
if (must_restart_merging)
start_merge(snap_merging);
dm_internal_resume_fast(origin_md);
dm_put(origin_md);
}
/* Now we have correct chunk size, reregister */
reregister_snapshot(s);
@ -2133,11 +2220,6 @@ static int origin_write_extent(struct dm_snapshot *merging_snap,
* Origin: maps a linear range of a device, with hooks for snapshotting.
*/
struct dm_origin {
struct dm_dev *dev;
unsigned split_boundary;
};
/*
* Construct an origin mapping: <dev_path>
* The context for an origin is merely a 'struct dm_dev *'
@ -2166,6 +2248,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad_open;
}
o->ti = ti;
ti->private = o;
ti->num_flush_bios = 1;
@ -2180,6 +2263,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv)
static void origin_dtr(struct dm_target *ti)
{
struct dm_origin *o = ti->private;
dm_put_device(ti, o->dev);
kfree(o);
}
@ -2216,6 +2300,19 @@ static void origin_resume(struct dm_target *ti)
struct dm_origin *o = ti->private;
o->split_boundary = get_origin_minimum_chunksize(o->dev->bdev);
down_write(&_origins_lock);
__insert_dm_origin(o);
up_write(&_origins_lock);
}
static void origin_postsuspend(struct dm_target *ti)
{
struct dm_origin *o = ti->private;
down_write(&_origins_lock);
__remove_dm_origin(o);
up_write(&_origins_lock);
}
static void origin_status(struct dm_target *ti, status_type_t type,
@ -2258,12 +2355,13 @@ static int origin_iterate_devices(struct dm_target *ti,
static struct target_type origin_target = {
.name = "snapshot-origin",
.version = {1, 8, 1},
.version = {1, 9, 0},
.module = THIS_MODULE,
.ctr = origin_ctr,
.dtr = origin_dtr,
.map = origin_map,
.resume = origin_resume,
.postsuspend = origin_postsuspend,
.status = origin_status,
.merge = origin_merge,
.iterate_devices = origin_iterate_devices,
@ -2271,7 +2369,7 @@ static struct target_type origin_target = {
static struct target_type snapshot_target = {
.name = "snapshot",
.version = {1, 12, 0},
.version = {1, 13, 0},
.module = THIS_MODULE,
.ctr = snapshot_ctr,
.dtr = snapshot_dtr,
@ -2285,7 +2383,7 @@ static struct target_type snapshot_target = {
static struct target_type merge_target = {
.name = dm_snapshot_merge_target_name,
.version = {1, 2, 0},
.version = {1, 3, 0},
.module = THIS_MODULE,
.ctr = snapshot_ctr,
.dtr = snapshot_dtr,

View File

@ -2358,17 +2358,6 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_REMAPPED;
case -ENODATA:
if (get_pool_mode(tc->pool) == PM_READ_ONLY) {
/*
* This block isn't provisioned, and we have no way
* of doing so.
*/
handle_unserviceable_bio(tc->pool, bio);
cell_defer_no_holder(tc, virt_cell);
return DM_MAPIO_SUBMITTED;
}
/* fall through */
case -EWOULDBLOCK:
thin_defer_cell(tc, virt_cell);
return DM_MAPIO_SUBMITTED;

View File

@ -2616,6 +2616,19 @@ void dm_get(struct mapped_device *md)
BUG_ON(test_bit(DMF_FREEING, &md->flags));
}
int dm_hold(struct mapped_device *md)
{
spin_lock(&_minor_lock);
if (test_bit(DMF_FREEING, &md->flags)) {
spin_unlock(&_minor_lock);
return -EBUSY;
}
dm_get(md);
spin_unlock(&_minor_lock);
return 0;
}
EXPORT_SYMBOL_GPL(dm_hold);
const char *dm_device_name(struct mapped_device *md)
{
return md->name;
@ -2638,10 +2651,16 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
if (dm_request_based(md))
flush_kthread_worker(&md->kworker);
/*
* Take suspend_lock so that presuspend and postsuspend methods
* do not race with internal suspend.
*/
mutex_lock(&md->suspend_lock);
if (!dm_suspended_md(md)) {
dm_table_presuspend_targets(map);
dm_table_postsuspend_targets(map);
}
mutex_unlock(&md->suspend_lock);
/* dm_put_live_table must be before msleep, otherwise deadlock is possible */
dm_put_live_table(md, srcu_idx);
@ -3115,6 +3134,7 @@ void dm_internal_suspend_fast(struct mapped_device *md)
flush_workqueue(md->wq);
dm_wait_for_completion(md, TASK_UNINTERRUPTIBLE);
}
EXPORT_SYMBOL_GPL(dm_internal_suspend_fast);
void dm_internal_resume_fast(struct mapped_device *md)
{
@ -3126,6 +3146,7 @@ void dm_internal_resume_fast(struct mapped_device *md)
done:
mutex_unlock(&md->suspend_lock);
}
EXPORT_SYMBOL_GPL(dm_internal_resume_fast);
/*-----------------------------------------------------------------
* Event notification.

View File

@ -5080,7 +5080,8 @@ int md_run(struct mddev *mddev)
}
if (err) {
mddev_detach(mddev);
pers->free(mddev, mddev->private);
if (mddev->private)
pers->free(mddev, mddev->private);
module_put(pers->owner);
bitmap_destroy(mddev);
return err;

View File

@ -467,8 +467,6 @@ static int raid0_run(struct mddev *mddev)
dump_zones(mddev);
ret = md_integrity_register(mddev);
if (ret)
raid0_free(mddev, conf);
return ret;
}

View File

@ -425,9 +425,10 @@ int ubi_eba_read_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum,
ubi_warn(ubi, "corrupted VID header at PEB %d, LEB %d:%d",
pnum, vol_id, lnum);
err = -EBADMSG;
} else
} else {
err = -EINVAL;
ubi_ro_mode(ubi);
}
}
goto out_free;
} else if (err == UBI_IO_BITFLIPS)

View File

@ -46,8 +46,7 @@ enum cx82310_status {
};
#define CMD_PACKET_SIZE 64
/* first command after power on can take around 8 seconds */
#define CMD_TIMEOUT 15000
#define CMD_TIMEOUT 100
#define CMD_REPLY_RETRY 5
#define CX82310_MTU 1514
@ -78,8 +77,9 @@ static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply,
ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf,
CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT);
if (ret < 0) {
dev_err(&dev->udev->dev, "send command %#x: error %d\n",
cmd, ret);
if (cmd != CMD_GET_LINK_STATUS)
dev_err(&dev->udev->dev, "send command %#x: error %d\n",
cmd, ret);
goto end;
}
@ -90,8 +90,10 @@ static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply,
buf, CMD_PACKET_SIZE, &actual_len,
CMD_TIMEOUT);
if (ret < 0) {
dev_err(&dev->udev->dev,
"reply receive error %d\n", ret);
if (cmd != CMD_GET_LINK_STATUS)
dev_err(&dev->udev->dev,
"reply receive error %d\n",
ret);
goto end;
}
if (actual_len > 0)
@ -134,6 +136,8 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
int ret;
char buf[15];
struct usb_device *udev = dev->udev;
u8 link[3];
int timeout = 50;
/* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0
@ -160,6 +164,20 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
if (!dev->partial_data)
return -ENOMEM;
/* wait for firmware to become ready (indicated by the link being up) */
while (--timeout) {
ret = cx82310_cmd(dev, CMD_GET_LINK_STATUS, true, NULL, 0,
link, sizeof(link));
/* the command can time out during boot - it's not an error */
if (!ret && link[0] == 1 && link[2] == 1)
break;
msleep(500);
};
if (!timeout) {
dev_err(&udev->dev, "firmware not ready in time\n");
return -ETIMEDOUT;
}
/* enable ethernet mode (?) */
ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0);
if (ret) {

View File

@ -715,13 +715,8 @@ static struct device_node *__of_find_node_by_path(struct device_node *parent,
{
struct device_node *child;
int len;
const char *end;
end = strchr(path, ':');
if (!end)
end = strchrnul(path, '/');
len = end - path;
len = strcspn(path, "/:");
if (!len)
return NULL;
@ -1893,10 +1888,8 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
name = of_get_property(of_chosen, "linux,stdout-path", NULL);
if (IS_ENABLED(CONFIG_PPC) && !name)
name = of_get_property(of_aliases, "stdout", NULL);
if (name) {
if (name)
of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
add_preferred_console("stdout-path", 0, NULL);
}
}
if (!of_aliases)

View File

@ -290,7 +290,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
struct device_node *p;
const __be32 *intspec, *tmp, *addr;
u32 intsize, intlen;
int i, res = -EINVAL;
int i, res;
pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index);
@ -323,15 +323,19 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar
/* Get size of interrupt specifier */
tmp = of_get_property(p, "#interrupt-cells", NULL);
if (tmp == NULL)
if (tmp == NULL) {
res = -EINVAL;
goto out;
}
intsize = be32_to_cpu(*tmp);
pr_debug(" intsize=%d intlen=%d\n", intsize, intlen);
/* Check index */
if ((index + 1) * intsize > intlen)
if ((index + 1) * intsize > intlen) {
res = -EINVAL;
goto out;
}
/* Copy intspec into irq structure */
intspec += index * intsize;

View File

@ -97,6 +97,11 @@ static void __init of_selftest_find_node_by_name(void)
"option path test, subcase #1 failed\n");
of_node_put(np);
np = of_find_node_opts_by_path("/testcase-data/testcase-device1:test/option", &options);
selftest(np && !strcmp("test/option", options),
"option path test, subcase #2 failed\n");
of_node_put(np);
np = of_find_node_opts_by_path("/testcase-data:testoption", NULL);
selftest(np, "NULL option path test failed\n");
of_node_put(np);

View File

@ -69,8 +69,7 @@ config YENTA
tristate "CardBus yenta-compatible bridge support"
depends on PCI
select CARDBUS if !EXPERT
select PCCARD_NONSTATIC if PCMCIA != n && ISA
select PCCARD_PCI if PCMCIA !=n && !ISA
select PCCARD_NONSTATIC if PCMCIA != n
---help---
This option enables support for CardBus host bridges. Virtually
all modern PCMCIA bridges are CardBus compatible. A "bridge" is
@ -110,8 +109,7 @@ config YENTA_TOSHIBA
config PD6729
tristate "Cirrus PD6729 compatible bridge support"
depends on PCMCIA && PCI
select PCCARD_NONSTATIC if PCMCIA != n && ISA
select PCCARD_PCI if PCMCIA !=n && !ISA
select PCCARD_NONSTATIC
help
This provides support for the Cirrus PD6729 PCI-to-PCMCIA bridge
device, found in some older laptops and PCMCIA card readers.
@ -119,8 +117,7 @@ config PD6729
config I82092
tristate "i82092 compatible bridge support"
depends on PCMCIA && PCI
select PCCARD_NONSTATIC if PCMCIA != n && ISA
select PCCARD_PCI if PCMCIA !=n && !ISA
select PCCARD_NONSTATIC
help
This provides support for the Intel I82092AA PCI-to-PCMCIA bridge device,
found in some older laptops and more commonly in evaluation boards for the
@ -291,9 +288,6 @@ config ELECTRA_CF
Say Y here to support the CompactFlash controller on the
PA Semi Electra eval board.
config PCCARD_PCI
bool
config PCCARD_NONSTATIC
bool

View File

@ -12,7 +12,6 @@ obj-$(CONFIG_PCMCIA) += pcmcia.o
pcmcia_rsrc-y += rsrc_mgr.o
pcmcia_rsrc-$(CONFIG_PCCARD_NONSTATIC) += rsrc_nonstatic.o
pcmcia_rsrc-$(CONFIG_PCCARD_IODYN) += rsrc_iodyn.o
pcmcia_rsrc-$(CONFIG_PCCARD_PCI) += rsrc_pci.o
obj-$(CONFIG_PCCARD) += pcmcia_rsrc.o

View File

@ -1,173 +0,0 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <pcmcia/ss.h>
#include <pcmcia/cistpl.h>
#include "cs_internal.h"
struct pcmcia_align_data {
unsigned long mask;
unsigned long offset;
};
static resource_size_t pcmcia_align(void *align_data,
const struct resource *res,
resource_size_t size, resource_size_t align)
{
struct pcmcia_align_data *data = align_data;
resource_size_t start;
start = (res->start & ~data->mask) + data->offset;
if (start < res->start)
start += data->mask + 1;
return start;
}
static struct resource *find_io_region(struct pcmcia_socket *s,
unsigned long base, int num,
unsigned long align)
{
struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_IO,
dev_name(&s->dev));
struct pcmcia_align_data data;
int ret;
data.mask = align - 1;
data.offset = base & data.mask;
ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
base, 0, pcmcia_align, &data);
if (ret != 0) {
kfree(res);
res = NULL;
}
return res;
}
static int res_pci_find_io(struct pcmcia_socket *s, unsigned int attr,
unsigned int *base, unsigned int num,
unsigned int align, struct resource **parent)
{
int i, ret = 0;
/* Check for an already-allocated window that must conflict with
* what was asked for. It is a hack because it does not catch all
* potential conflicts, just the most obvious ones.
*/
for (i = 0; i < MAX_IO_WIN; i++) {
if (!s->io[i].res)
continue;
if (!*base)
continue;
if ((s->io[i].res->start & (align-1)) == *base)
return -EBUSY;
}
for (i = 0; i < MAX_IO_WIN; i++) {
struct resource *res = s->io[i].res;
unsigned int try;
if (res && (res->flags & IORESOURCE_BITS) !=
(attr & IORESOURCE_BITS))
continue;
if (!res) {
if (align == 0)
align = 0x10000;
res = s->io[i].res = find_io_region(s, *base, num,
align);
if (!res)
return -EINVAL;
*base = res->start;
s->io[i].res->flags =
((res->flags & ~IORESOURCE_BITS) |
(attr & IORESOURCE_BITS));
s->io[i].InUse = num;
*parent = res;
return 0;
}
/* Try to extend top of window */
try = res->end + 1;
if ((*base == 0) || (*base == try)) {
ret = adjust_resource(s->io[i].res, res->start,
resource_size(res) + num);
if (ret)
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}
/* Try to extend bottom of window */
try = res->start - num;
if ((*base == 0) || (*base == try)) {
ret = adjust_resource(s->io[i].res,
res->start - num,
resource_size(res) + num);
if (ret)
continue;
*base = try;
s->io[i].InUse += num;
*parent = res;
return 0;
}
}
return -EINVAL;
}
static struct resource *res_pci_find_mem(u_long base, u_long num,
u_long align, int low, struct pcmcia_socket *s)
{
struct resource *res = pcmcia_make_resource(0, num, IORESOURCE_MEM,
dev_name(&s->dev));
struct pcmcia_align_data data;
unsigned long min;
int ret;
if (align < 0x20000)
align = 0x20000;
data.mask = align - 1;
data.offset = base & data.mask;
min = 0;
if (!low)
min = 0x100000UL;
ret = pci_bus_alloc_resource(s->cb_dev->bus,
res, num, 1, min, 0,
pcmcia_align, &data);
if (ret != 0) {
kfree(res);
res = NULL;
}
return res;
}
static int res_pci_init(struct pcmcia_socket *s)
{
if (!s->cb_dev || !(s->features & SS_CAP_PAGE_REGS)) {
dev_err(&s->dev, "not supported by res_pci\n");
return -EOPNOTSUPP;
}
return 0;
}
struct pccard_resource_ops pccard_nonstatic_ops = {
.validate_mem = NULL,
.find_io = res_pci_find_io,
.find_mem = res_pci_find_mem,
.init = res_pci_init,
.exit = NULL,
};
EXPORT_SYMBOL(pccard_nonstatic_ops);

View File

@ -37,7 +37,7 @@ static int armada375_usb_phy_init(struct phy *phy)
struct armada375_cluster_phy *cluster_phy;
u32 reg;
cluster_phy = dev_get_drvdata(phy->dev.parent);
cluster_phy = phy_get_drvdata(phy);
if (!cluster_phy)
return -ENODEV;
@ -131,6 +131,7 @@ static int armada375_usb_phy_probe(struct platform_device *pdev)
cluster_phy->reg = usb_cluster_base;
dev_set_drvdata(dev, cluster_phy);
phy_set_drvdata(phy, cluster_phy);
phy_provider = devm_of_phy_provider_register(&pdev->dev,
armada375_usb_phy_xlate);

View File

@ -52,7 +52,9 @@ static void devm_phy_consume(struct device *dev, void *res)
static int devm_phy_match(struct device *dev, void *res, void *match_data)
{
return res == match_data;
struct phy **phy = res;
return *phy == match_data;
}
/**
@ -223,6 +225,7 @@ int phy_init(struct phy *phy)
ret = phy_pm_runtime_get_sync(phy);
if (ret < 0 && ret != -ENOTSUPP)
return ret;
ret = 0; /* Override possible ret == -ENOTSUPP */
mutex_lock(&phy->mutex);
if (phy->init_count == 0 && phy->ops->init) {
@ -231,8 +234,6 @@ int phy_init(struct phy *phy)
dev_err(&phy->dev, "phy init failed --> %d\n", ret);
goto out;
}
} else {
ret = 0; /* Override possible ret == -ENOTSUPP */
}
++phy->init_count;
@ -253,6 +254,7 @@ int phy_exit(struct phy *phy)
ret = phy_pm_runtime_get_sync(phy);
if (ret < 0 && ret != -ENOTSUPP)
return ret;
ret = 0; /* Override possible ret == -ENOTSUPP */
mutex_lock(&phy->mutex);
if (phy->init_count == 1 && phy->ops->exit) {
@ -287,6 +289,7 @@ int phy_power_on(struct phy *phy)
ret = phy_pm_runtime_get_sync(phy);
if (ret < 0 && ret != -ENOTSUPP)
return ret;
ret = 0; /* Override possible ret == -ENOTSUPP */
mutex_lock(&phy->mutex);
if (phy->power_count == 0 && phy->ops->power_on) {
@ -295,8 +298,6 @@ int phy_power_on(struct phy *phy)
dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
goto out;
}
} else {
ret = 0; /* Override possible ret == -ENOTSUPP */
}
++phy->power_count;
mutex_unlock(&phy->mutex);

View File

@ -30,28 +30,13 @@ struct exynos_dp_video_phy {
const struct exynos_dp_video_phy_drvdata *drvdata;
};
static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state,
unsigned int on)
{
unsigned int val;
if (IS_ERR(state->regs))
return;
val = on ? 0 : EXYNOS5_PHY_ENABLE;
regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
EXYNOS5_PHY_ENABLE, val);
}
static int exynos_dp_video_phy_power_on(struct phy *phy)
{
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
/* Disable power isolation on DP-PHY */
exynos_dp_video_phy_pwr_isol(state, 0);
return 0;
return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
EXYNOS5_PHY_ENABLE, EXYNOS5_PHY_ENABLE);
}
static int exynos_dp_video_phy_power_off(struct phy *phy)
@ -59,9 +44,8 @@ static int exynos_dp_video_phy_power_off(struct phy *phy)
struct exynos_dp_video_phy *state = phy_get_drvdata(phy);
/* Enable power isolation on DP-PHY */
exynos_dp_video_phy_pwr_isol(state, 1);
return 0;
return regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset,
EXYNOS5_PHY_ENABLE, 0);
}
static struct phy_ops exynos_dp_video_phy_ops = {

View File

@ -43,7 +43,6 @@ struct exynos_mipi_video_phy {
} phys[EXYNOS_MIPI_PHYS_NUM];
spinlock_t slock;
void __iomem *regs;
struct mutex mutex;
struct regmap *regmap;
};
@ -59,8 +58,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
else
reset = EXYNOS4_MIPI_PHY_SRESETN;
if (state->regmap) {
mutex_lock(&state->mutex);
spin_lock(&state->slock);
if (!IS_ERR(state->regmap)) {
regmap_read(state->regmap, offset, &val);
if (on)
val |= reset;
@ -72,11 +72,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
else if (!(val & EXYNOS4_MIPI_PHY_RESET_MASK))
val &= ~EXYNOS4_MIPI_PHY_ENABLE;
regmap_write(state->regmap, offset, val);
mutex_unlock(&state->mutex);
} else {
addr = state->regs + EXYNOS_MIPI_PHY_CONTROL(id / 2);
spin_lock(&state->slock);
val = readl(addr);
if (on)
val |= reset;
@ -90,9 +88,9 @@ static int __set_phy_state(struct exynos_mipi_video_phy *state,
val &= ~EXYNOS4_MIPI_PHY_ENABLE;
writel(val, addr);
spin_unlock(&state->slock);
}
spin_unlock(&state->slock);
return 0;
}
@ -158,7 +156,6 @@ static int exynos_mipi_video_phy_probe(struct platform_device *pdev)
dev_set_drvdata(dev, state);
spin_lock_init(&state->slock);
mutex_init(&state->mutex);
for (i = 0; i < EXYNOS_MIPI_PHYS_NUM; i++) {
struct phy *phy = devm_phy_create(dev, NULL,

View File

@ -250,7 +250,6 @@ static const struct samsung_usb2_common_phy exynos4210_phys[] = {
.power_on = exynos4210_power_on,
.power_off = exynos4210_power_off,
},
{},
};
const struct samsung_usb2_phy_config exynos4210_usb2_phy_config = {

View File

@ -361,7 +361,6 @@ static const struct samsung_usb2_common_phy exynos4x12_phys[] = {
.power_on = exynos4x12_power_on,
.power_off = exynos4x12_power_off,
},
{},
};
const struct samsung_usb2_phy_config exynos3250_usb2_phy_config = {

View File

@ -531,7 +531,7 @@ static struct phy *exynos5_usbdrd_phy_xlate(struct device *dev,
{
struct exynos5_usbdrd_phy *phy_drd = dev_get_drvdata(dev);
if (WARN_ON(args->args[0] > EXYNOS5_DRDPHYS_NUM))
if (WARN_ON(args->args[0] >= EXYNOS5_DRDPHYS_NUM))
return ERR_PTR(-ENODEV);
return phy_drd->phys[args->args[0]].phy;

View File

@ -391,7 +391,6 @@ static const struct samsung_usb2_common_phy exynos5250_phys[] = {
.power_on = exynos5250_power_on,
.power_off = exynos5250_power_off,
},
{},
};
const struct samsung_usb2_phy_config exynos5250_usb2_phy_config = {

View File

@ -147,6 +147,9 @@ static int hix5hd2_sata_phy_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
priv->base = devm_ioremap(dev, res->start, resource_size(res));
if (!priv->base)
return -ENOMEM;

View File

@ -228,6 +228,7 @@ struct miphy28lp_dev {
struct regmap *regmap;
struct mutex miphy_mutex;
struct miphy28lp_phy **phys;
int nphys;
};
struct miphy_initval {
@ -1116,7 +1117,7 @@ static struct phy *miphy28lp_xlate(struct device *dev,
return ERR_PTR(-EINVAL);
}
for (index = 0; index < of_get_child_count(dev->of_node); index++)
for (index = 0; index < miphy_dev->nphys; index++)
if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
miphy_phy = miphy_dev->phys[index];
break;
@ -1138,6 +1139,7 @@ static struct phy *miphy28lp_xlate(struct device *dev,
static struct phy_ops miphy28lp_ops = {
.init = miphy28lp_init,
.owner = THIS_MODULE,
};
static int miphy28lp_probe_resets(struct device_node *node,
@ -1200,16 +1202,15 @@ static int miphy28lp_probe(struct platform_device *pdev)
struct miphy28lp_dev *miphy_dev;
struct phy_provider *provider;
struct phy *phy;
int chancount, port = 0;
int ret;
int ret, port = 0;
miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
if (!miphy_dev)
return -ENOMEM;
chancount = of_get_child_count(np);
miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
GFP_KERNEL);
miphy_dev->nphys = of_get_child_count(np);
miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys,
sizeof(*miphy_dev->phys), GFP_KERNEL);
if (!miphy_dev->phys)
return -ENOMEM;

View File

@ -150,6 +150,7 @@ struct miphy365x_dev {
struct regmap *regmap;
struct mutex miphy_mutex;
struct miphy365x_phy **phys;
int nphys;
};
/*
@ -485,7 +486,7 @@ static struct phy *miphy365x_xlate(struct device *dev,
return ERR_PTR(-EINVAL);
}
for (index = 0; index < of_get_child_count(dev->of_node); index++)
for (index = 0; index < miphy_dev->nphys; index++)
if (phynode == miphy_dev->phys[index]->phy->dev.of_node) {
miphy_phy = miphy_dev->phys[index];
break;
@ -541,16 +542,15 @@ static int miphy365x_probe(struct platform_device *pdev)
struct miphy365x_dev *miphy_dev;
struct phy_provider *provider;
struct phy *phy;
int chancount, port = 0;
int ret;
int ret, port = 0;
miphy_dev = devm_kzalloc(&pdev->dev, sizeof(*miphy_dev), GFP_KERNEL);
if (!miphy_dev)
return -ENOMEM;
chancount = of_get_child_count(np);
miphy_dev->phys = devm_kzalloc(&pdev->dev, sizeof(phy) * chancount,
GFP_KERNEL);
miphy_dev->nphys = of_get_child_count(np);
miphy_dev->phys = devm_kcalloc(&pdev->dev, miphy_dev->nphys,
sizeof(*miphy_dev->phys), GFP_KERNEL);
if (!miphy_dev->phys)
return -ENOMEM;

View File

@ -360,7 +360,7 @@ static void __exit omap_control_phy_exit(void)
}
module_exit(omap_control_phy_exit);
MODULE_ALIAS("platform: omap_control_phy");
MODULE_ALIAS("platform:omap_control_phy");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_DESCRIPTION("OMAP Control Module PHY Driver");
MODULE_LICENSE("GPL v2");

View File

@ -296,10 +296,11 @@ static int omap_usb2_probe(struct platform_device *pdev)
dev_warn(&pdev->dev,
"found usb_otg_ss_refclk960m, please fix DTS\n");
}
} else {
clk_prepare(phy->optclk);
}
if (!IS_ERR(phy->optclk))
clk_prepare(phy->optclk);
usb_add_phy_dev(&phy->phy);
return 0;
@ -383,7 +384,7 @@ static struct platform_driver omap_usb2_driver = {
module_platform_driver(omap_usb2_driver);
MODULE_ALIAS("platform: omap_usb2");
MODULE_ALIAS("platform:omap_usb2");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_DESCRIPTION("OMAP USB2 phy driver");
MODULE_LICENSE("GPL v2");

View File

@ -61,8 +61,6 @@ static int rockchip_usb_phy_power_off(struct phy *_phy)
return ret;
clk_disable_unprepare(phy->clk);
if (ret)
return ret;
return 0;
}
@ -78,8 +76,10 @@ static int rockchip_usb_phy_power_on(struct phy *_phy)
/* Power up usb phy analog blocks by set siddq 0 */
ret = rockchip_usb_phy_power(phy, 0);
if (ret)
if (ret) {
clk_disable_unprepare(phy->clk);
return ret;
}
return 0;
}

View File

@ -165,15 +165,11 @@ static int ti_pipe3_dpll_wait_lock(struct ti_pipe3 *phy)
cpu_relax();
val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS);
if (val & PLL_LOCK)
break;
return 0;
} while (!time_after(jiffies, timeout));
if (!(val & PLL_LOCK)) {
dev_err(phy->dev, "DPLL failed to lock\n");
return -EBUSY;
}
return 0;
dev_err(phy->dev, "DPLL failed to lock\n");
return -EBUSY;
}
static int ti_pipe3_dpll_program(struct ti_pipe3 *phy)
@ -608,7 +604,7 @@ static struct platform_driver ti_pipe3_driver = {
module_platform_driver(ti_pipe3_driver);
MODULE_ALIAS("platform: ti_pipe3");
MODULE_ALIAS("platform:ti_pipe3");
MODULE_AUTHOR("Texas Instruments Inc.");
MODULE_DESCRIPTION("TI PIPE3 phy driver");
MODULE_LICENSE("GPL v2");

View File

@ -666,7 +666,6 @@ static int twl4030_usb_probe(struct platform_device *pdev)
twl->dev = &pdev->dev;
twl->irq = platform_get_irq(pdev, 0);
twl->vbus_supplied = false;
twl->linkstat = -EINVAL;
twl->linkstat = OMAP_MUSB_UNKNOWN;
twl->phy.dev = twl->dev;

View File

@ -1704,7 +1704,6 @@ static int xgene_phy_probe(struct platform_device *pdev)
for (i = 0; i < MAX_LANE; i++)
ctx->sata_param.speed[i] = 2; /* Default to Gen3 */
ctx->dev = &pdev->dev;
platform_set_drvdata(pdev, ctx);
ctx->phy = devm_phy_create(ctx->dev, NULL, &xgene_phy_ops);

View File

@ -73,7 +73,7 @@
#define TIME_WINDOW_MAX_MSEC 40000
#define TIME_WINDOW_MIN_MSEC 250
#define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */
enum unit_type {
ARBITRARY_UNIT, /* no translation */
POWER_UNIT,
@ -158,6 +158,7 @@ struct rapl_domain {
struct rapl_power_limit rpl[NR_POWER_LIMITS];
u64 attr_map; /* track capabilities */
unsigned int state;
unsigned int domain_energy_unit;
int package_id;
};
#define power_zone_to_rapl_domain(_zone) \
@ -190,6 +191,7 @@ struct rapl_defaults {
void (*set_floor_freq)(struct rapl_domain *rd, bool mode);
u64 (*compute_time_window)(struct rapl_package *rp, u64 val,
bool to_raw);
unsigned int dram_domain_energy_unit;
};
static struct rapl_defaults *rapl_defaults;
@ -227,7 +229,8 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
static int rapl_write_data_raw(struct rapl_domain *rd,
enum rapl_primitives prim,
unsigned long long value);
static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
static u64 rapl_unit_xlate(struct rapl_domain *rd, int package,
enum unit_type type, u64 value,
int to_raw);
static void package_power_limit_irq_save(int package_id);
@ -305,7 +308,9 @@ static int get_energy_counter(struct powercap_zone *power_zone, u64 *energy_raw)
static int get_max_energy_counter(struct powercap_zone *pcd_dev, u64 *energy)
{
*energy = rapl_unit_xlate(0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
struct rapl_domain *rd = power_zone_to_rapl_domain(pcd_dev);
*energy = rapl_unit_xlate(rd, 0, ENERGY_UNIT, ENERGY_STATUS_MASK, 0);
return 0;
}
@ -639,6 +644,11 @@ static void rapl_init_domains(struct rapl_package *rp)
rd->msrs[4] = MSR_DRAM_POWER_INFO;
rd->rpl[0].prim_id = PL1_ENABLE;
rd->rpl[0].name = pl1_name;
rd->domain_energy_unit =
rapl_defaults->dram_domain_energy_unit;
if (rd->domain_energy_unit)
pr_info("DRAM domain energy unit %dpj\n",
rd->domain_energy_unit);
break;
}
if (mask) {
@ -648,11 +658,13 @@ static void rapl_init_domains(struct rapl_package *rp)
}
}
static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
static u64 rapl_unit_xlate(struct rapl_domain *rd, int package,
enum unit_type type, u64 value,
int to_raw)
{
u64 units = 1;
struct rapl_package *rp;
u64 scale = 1;
rp = find_package_by_id(package);
if (!rp)
@ -663,7 +675,12 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
units = rp->power_unit;
break;
case ENERGY_UNIT:
units = rp->energy_unit;
scale = ENERGY_UNIT_SCALE;
/* per domain unit takes precedence */
if (rd && rd->domain_energy_unit)
units = rd->domain_energy_unit;
else
units = rp->energy_unit;
break;
case TIME_UNIT:
return rapl_defaults->compute_time_window(rp, value, to_raw);
@ -673,11 +690,11 @@ static u64 rapl_unit_xlate(int package, enum unit_type type, u64 value,
};
if (to_raw)
return div64_u64(value, units);
return div64_u64(value, units) * scale;
value *= units;
return value;
return div64_u64(value, scale);
}
/* in the order of enum rapl_primitives */
@ -773,7 +790,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd,
final = value & rp->mask;
final = final >> rp->shift;
if (xlate)
*data = rapl_unit_xlate(rd->package_id, rp->unit, final, 0);
*data = rapl_unit_xlate(rd, rd->package_id, rp->unit, final, 0);
else
*data = final;
@ -799,7 +816,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
"failed to read msr 0x%x on cpu %d\n", msr, cpu);
return -EIO;
}
value = rapl_unit_xlate(rd->package_id, rp->unit, value, 1);
value = rapl_unit_xlate(rd, rd->package_id, rp->unit, value, 1);
msr_val &= ~rp->mask;
msr_val |= value << rp->shift;
if (wrmsrl_safe_on_cpu(cpu, msr, msr_val)) {
@ -818,7 +835,7 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
* calculate units differ on different CPUs.
* We convert the units to below format based on CPUs.
* i.e.
* energy unit: microJoules : Represented in microJoules by default
* energy unit: picoJoules : Represented in picoJoules by default
* power unit : microWatts : Represented in milliWatts by default
* time unit : microseconds: Represented in seconds by default
*/
@ -834,7 +851,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
}
value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
rp->energy_unit = 1000000 / (1 << value);
rp->energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value);
value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
rp->power_unit = 1000000 / (1 << value);
@ -842,7 +859,7 @@ static int rapl_check_unit_core(struct rapl_package *rp, int cpu)
value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
rp->time_unit = 1000000 / (1 << value);
pr_debug("Core CPU package %d energy=%duJ, time=%dus, power=%duW\n",
pr_debug("Core CPU package %d energy=%dpJ, time=%dus, power=%duW\n",
rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
return 0;
@ -859,7 +876,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
return -ENODEV;
}
value = (msr_val & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET;
rp->energy_unit = 1 << value;
rp->energy_unit = ENERGY_UNIT_SCALE * 1 << value;
value = (msr_val & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET;
rp->power_unit = (1 << value) * 1000;
@ -867,7 +884,7 @@ static int rapl_check_unit_atom(struct rapl_package *rp, int cpu)
value = (msr_val & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET;
rp->time_unit = 1000000 / (1 << value);
pr_debug("Atom package %d energy=%duJ, time=%dus, power=%duW\n",
pr_debug("Atom package %d energy=%dpJ, time=%dus, power=%duW\n",
rp->id, rp->energy_unit, rp->time_unit, rp->power_unit);
return 0;
@ -1017,6 +1034,13 @@ static const struct rapl_defaults rapl_defaults_core = {
.compute_time_window = rapl_compute_time_window_core,
};
static const struct rapl_defaults rapl_defaults_hsw_server = {
.check_unit = rapl_check_unit_core,
.set_floor_freq = set_floor_freq_default,
.compute_time_window = rapl_compute_time_window_core,
.dram_domain_energy_unit = 15300,
};
static const struct rapl_defaults rapl_defaults_atom = {
.check_unit = rapl_check_unit_atom,
.set_floor_freq = set_floor_freq_atom,
@ -1037,7 +1061,7 @@ static const struct x86_cpu_id rapl_ids[] = {
RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */
RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */
RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */
RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */
RAPL_CPU(0x3f, rapl_defaults_hsw_server),/* Haswell servers */
RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */
RAPL_CPU(0x4C, rapl_defaults_atom),/* Braswell */
RAPL_CPU(0x4A, rapl_defaults_atom),/* Tangier */

View File

@ -324,7 +324,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
ret = IRQ_HANDLED;
}
spin_lock(&suspended_lock);
spin_unlock(&suspended_lock);
return ret;
}

View File

@ -1596,7 +1596,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
/*
* Finally register the new FC Nexus with TCM
*/
__transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess);
transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess);
return 0;
}

View File

@ -330,16 +330,6 @@ static void device_init_registers(struct vnt_private *pDevice)
/* zonetype initial */
pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
/* Get RFType */
pDevice->byRFType = SROMbyReadEmbedded(pDevice->PortOffset, EEP_OFS_RFTYPE);
/* force change RevID for VT3253 emu */
if ((pDevice->byRFType & RF_EMU) != 0)
pDevice->byRevId = 0x80;
pDevice->byRFType &= RF_MASK;
pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType);
if (!pDevice->bZoneRegExist)
pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE];
@ -1187,12 +1177,14 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
PSTxDesc head_td;
u32 dma_idx = TYPE_AC0DMA;
u32 dma_idx;
unsigned long flags;
spin_lock_irqsave(&priv->lock, flags);
if (!ieee80211_is_data(hdr->frame_control))
if (ieee80211_is_data(hdr->frame_control))
dma_idx = TYPE_AC0DMA;
else
dma_idx = TYPE_TXDMA0;
if (AVAIL_TD(priv, dma_idx) < 1) {
@ -1206,6 +1198,9 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
head_td->pTDInfo->skb = skb;
if (dma_idx == TYPE_AC0DMA)
head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
priv->iTDUsed[dma_idx]++;
/* Take ownership */
@ -1234,13 +1229,10 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);
if (dma_idx == TYPE_AC0DMA) {
head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)
MACvTransmitAC0(priv->PortOffset);
} else {
else
MACvTransmit0(priv->PortOffset);
}
spin_unlock_irqrestore(&priv->lock, flags);
@ -1778,6 +1770,12 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent)
MACvInitialize(priv->PortOffset);
MACvReadEtherAddress(priv->PortOffset, priv->abyCurrentNetAddr);
/* Get RFType */
priv->byRFType = SROMbyReadEmbedded(priv->PortOffset, EEP_OFS_RFTYPE);
priv->byRFType &= RF_MASK;
dev_dbg(&pcid->dev, "RF Type = %x\n", priv->byRFType);
device_get_options(priv);
device_set_options(priv);
/* Mask out the options cannot be set to the chip */

View File

@ -794,6 +794,7 @@ bool RFbSetPower(
break;
case RATE_6M:
case RATE_9M:
case RATE_12M:
case RATE_18M:
byPwr = priv->abyOFDMPwrTbl[uCH];
if (priv->byRFType == RF_UW2452)

View File

@ -640,6 +640,7 @@ int vnt_rf_setpower(struct vnt_private *priv, u32 rate, u32 channel)
break;
case RATE_6M:
case RATE_9M:
case RATE_12M:
case RATE_18M:
case RATE_24M:
case RATE_36M:

View File

@ -4256,11 +4256,17 @@ int iscsit_close_connection(
pr_debug("Closing iSCSI connection CID %hu on SID:"
" %u\n", conn->cid, sess->sid);
/*
* Always up conn_logout_comp just in case the RX Thread is sleeping
* and the logout response never got sent because the connection
* failed.
* Always up conn_logout_comp for the traditional TCP case just in case
* the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout
* response never got sent because the connection failed.
*
* However for iser-target, isert_wait4logout() is using conn_logout_comp
* to signal logout response TX interrupt completion. Go ahead and skip
* this for iser since isert_rx_opcode() does not wait on logout failure,
* and to avoid iscsi_conn pointer dereference in iser-target code.
*/
complete(&conn->conn_logout_comp);
if (conn->conn_transport->transport_type == ISCSI_TCP)
complete(&conn->conn_logout_comp);
iscsi_release_thread_set(conn);

View File

@ -22,7 +22,6 @@
#include <target/target_core_fabric.h>
#include <target/iscsi/iscsi_target_core.h>
#include <target/iscsi/iscsi_transport.h>
#include "iscsi_target_seq_pdu_list.h"
#include "iscsi_target_tq.h"
#include "iscsi_target_erl0.h"
@ -940,8 +939,7 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
spin_unlock_bh(&conn->state_lock);
if (conn->conn_transport->transport_type == ISCSI_TCP)
iscsit_close_connection(conn);
iscsit_close_connection(conn);
return;
}

View File

@ -953,11 +953,8 @@ static int tcm_loop_make_nexus(
transport_free_session(tl_nexus->se_sess);
goto out;
}
/*
* Now, register the SAS I_T Nexus as active with the call to
* transport_register_session()
*/
__transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
/* Now, register the SAS I_T Nexus as active. */
transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
tl_nexus->se_sess, tl_nexus);
tl_tpg->tl_nexus = tl_nexus;
pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"

View File

@ -650,6 +650,18 @@ static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
return aligned_max_sectors;
}
bool se_dev_check_wce(struct se_device *dev)
{
bool wce = false;
if (dev->transport->get_write_cache)
wce = dev->transport->get_write_cache(dev);
else if (dev->dev_attrib.emulate_write_cache > 0)
wce = true;
return wce;
}
int se_dev_set_max_unmap_lba_count(
struct se_device *dev,
u32 max_unmap_lba_count)
@ -767,6 +779,16 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag)
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}
if (flag &&
dev->transport->get_write_cache) {
pr_err("emulate_fua_write not supported for this device\n");
return -EINVAL;
}
if (dev->export_count) {
pr_err("emulate_fua_write cannot be changed with active"
" exports: %d\n", dev->export_count);
return -EINVAL;
}
dev->dev_attrib.emulate_fua_write = flag;
pr_debug("dev[%p]: SE Device Forced Unit Access WRITEs: %d\n",
dev, dev->dev_attrib.emulate_fua_write);
@ -801,7 +823,11 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag)
pr_err("emulate_write_cache not supported for this device\n");
return -EINVAL;
}
if (dev->export_count) {
pr_err("emulate_write_cache cannot be changed with active"
" exports: %d\n", dev->export_count);
return -EINVAL;
}
dev->dev_attrib.emulate_write_cache = flag;
pr_debug("dev[%p]: SE Device WRITE_CACHE_EMULATION flag: %d\n",
dev, dev->dev_attrib.emulate_write_cache);
@ -1534,8 +1560,6 @@ int target_configure_device(struct se_device *dev)
ret = dev->transport->configure_device(dev);
if (ret)
goto out;
dev->dev_flags |= DF_CONFIGURED;
/*
* XXX: there is not much point to have two different values here..
*/
@ -1597,6 +1621,8 @@ int target_configure_device(struct se_device *dev)
list_add_tail(&dev->g_dev_node, &g_device_list);
mutex_unlock(&g_device_mutex);
dev->dev_flags |= DF_CONFIGURED;
return 0;
out_free_alua:

View File

@ -1121,7 +1121,7 @@ static u32 pscsi_get_device_type(struct se_device *dev)
struct pscsi_dev_virt *pdv = PSCSI_DEV(dev);
struct scsi_device *sd = pdv->pdv_sd;
return sd->type;
return (sd) ? sd->type : TYPE_NO_LUN;
}
static sector_t pscsi_get_blocks(struct se_device *dev)

View File

@ -708,8 +708,7 @@ sbc_check_dpofua(struct se_device *dev, struct se_cmd *cmd, unsigned char *cdb)
}
}
if (cdb[1] & 0x8) {
if (!dev->dev_attrib.emulate_fua_write ||
!dev->dev_attrib.emulate_write_cache) {
if (!dev->dev_attrib.emulate_fua_write || !se_dev_check_wce(dev)) {
pr_err("Got CDB: 0x%02x with FUA bit set, but device"
" does not advertise support for FUA write\n",
cdb[0]);

View File

@ -454,19 +454,6 @@ spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
}
EXPORT_SYMBOL(spc_emulate_evpd_83);
static bool
spc_check_dev_wce(struct se_device *dev)
{
bool wce = false;
if (dev->transport->get_write_cache)
wce = dev->transport->get_write_cache(dev);
else if (dev->dev_attrib.emulate_write_cache > 0)
wce = true;
return wce;
}
/* Extended INQUIRY Data VPD Page */
static sense_reason_t
spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
@ -490,7 +477,7 @@ spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
buf[5] = 0x07;
/* If WriteCache emulation is enabled, set V_SUP */
if (spc_check_dev_wce(dev))
if (se_dev_check_wce(dev))
buf[6] = 0x01;
/* If an LBA map is present set R_SUP */
spin_lock(&cmd->se_dev->t10_alua.lba_map_lock);
@ -897,7 +884,7 @@ static int spc_modesense_caching(struct se_cmd *cmd, u8 pc, u8 *p)
if (pc == 1)
goto out;
if (spc_check_dev_wce(dev))
if (se_dev_check_wce(dev))
p[2] = 0x04; /* Write Cache Enable */
p[12] = 0x20; /* Disabled Read Ahead */
@ -1009,7 +996,7 @@ static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd)
(cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
spc_modesense_write_protect(&buf[length], type);
if ((spc_check_dev_wce(dev)) &&
if ((se_dev_check_wce(dev)) &&
(dev->dev_attrib.emulate_fua_write > 0))
spc_modesense_dpofua(&buf[length], type);

View File

@ -2389,6 +2389,10 @@ int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list);
out:
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
if (ret && ack_kref)
target_put_sess_cmd(se_sess, se_cmd);
return ret;
}
EXPORT_SYMBOL(target_get_sess_cmd);

View File

@ -359,7 +359,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd)
ep = fc_seq_exch(seq);
if (ep) {
lport = ep->lp;
if (lport && (ep->xid <= lport->lro_xid))
if (lport && (ep->xid <= lport->lro_xid)) {
/*
* "ddp_done" trigger invalidation of HW
* specific DDP context
@ -374,6 +374,7 @@ void ft_invl_hw_context(struct ft_cmd *cmd)
* identified using ep->xid)
*/
cmd->was_ddp_setup = 0;
}
}
}
}

View File

@ -119,7 +119,10 @@ static void dw8250_serial_out(struct uart_port *p, int offset, int value)
dw8250_force_idle(p);
writeb(value, p->membase + (UART_LCR << p->regshift));
}
dev_err(p->dev, "Couldn't set LCR to %d\n", value);
/*
* FIXME: this deadlocks if port->lock is already held
* dev_err(p->dev, "Couldn't set LCR to %d\n", value);
*/
}
}
@ -163,7 +166,10 @@ static void dw8250_serial_outq(struct uart_port *p, int offset, int value)
__raw_writeq(value & 0xff,
p->membase + (UART_LCR << p->regshift));
}
dev_err(p->dev, "Couldn't set LCR to %d\n", value);
/*
* FIXME: this deadlocks if port->lock is already held
* dev_err(p->dev, "Couldn't set LCR to %d\n", value);
*/
}
}
#endif /* CONFIG_64BIT */
@ -187,7 +193,10 @@ static void dw8250_serial_out32(struct uart_port *p, int offset, int value)
dw8250_force_idle(p);
writel(value, p->membase + (UART_LCR << p->regshift));
}
dev_err(p->dev, "Couldn't set LCR to %d\n", value);
/*
* FIXME: this deadlocks if port->lock is already held
* dev_err(p->dev, "Couldn't set LCR to %d\n", value);
*/
}
}

View File

@ -929,6 +929,13 @@ __acquires(hwep->lock)
return retval;
}
static int otg_a_alt_hnp_support(struct ci_hdrc *ci)
{
dev_warn(&ci->gadget.dev,
"connect the device to an alternate port if you want HNP\n");
return isr_setup_status_phase(ci);
}
/**
* isr_setup_packet_handler: setup packet handler
* @ci: UDC descriptor
@ -1061,6 +1068,10 @@ __acquires(ci->lock)
ci);
}
break;
case USB_DEVICE_A_ALT_HNP_SUPPORT:
if (ci_otg_is_fsm_mode(ci))
err = otg_a_alt_hnp_support(ci);
break;
default:
goto delegate;
}

View File

@ -150,9 +150,9 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
break;
case OTG_STATE_B_PERIPHERAL:
otg_chrg_vbus(fsm, 0);
otg_loc_conn(fsm, 1);
otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_GADGET);
otg_loc_conn(fsm, 1);
break;
case OTG_STATE_B_WAIT_ACON:
otg_chrg_vbus(fsm, 0);
@ -213,10 +213,10 @@ static int otg_set_state(struct otg_fsm *fsm, enum usb_otg_state new_state)
break;
case OTG_STATE_A_PERIPHERAL:
otg_loc_conn(fsm, 1);
otg_loc_sof(fsm, 0);
otg_set_protocol(fsm, PROTO_GADGET);
otg_drv_vbus(fsm, 1);
otg_loc_conn(fsm, 1);
otg_add_timer(fsm, A_BIDL_ADIS);
break;
case OTG_STATE_A_WAIT_VFALL:

View File

@ -377,6 +377,9 @@ static void dwc2_handle_disconnect_intr(struct dwc2_hsotg *hsotg)
dwc2_is_host_mode(hsotg) ? "Host" : "Device",
dwc2_op_state_str(hsotg));
if (hsotg->op_state == OTG_STATE_A_HOST)
dwc2_hcd_disconnect(hsotg);
/* Change to L3 (OFF) state */
hsotg->lx_state = DWC2_L3;

View File

@ -289,8 +289,7 @@ static void disable_loopback(struct f_loopback *loop)
struct usb_composite_dev *cdev;
cdev = loop->function.config->cdev;
disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL, NULL,
NULL);
disable_endpoints(cdev, loop->in_ep, loop->out_ep, NULL, NULL);
VDBG(cdev, "%s disabled\n", loop->function.name);
}

View File

@ -23,15 +23,6 @@
#include "gadget_chips.h"
#include "u_f.h"
#define USB_MS_TO_SS_INTERVAL(x) USB_MS_TO_HS_INTERVAL(x)
enum eptype {
EP_CONTROL = 0,
EP_BULK,
EP_ISOC,
EP_INTERRUPT,
};
/*
* SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
* controller drivers.
@ -64,8 +55,6 @@ struct f_sourcesink {
struct usb_ep *out_ep;
struct usb_ep *iso_in_ep;
struct usb_ep *iso_out_ep;
struct usb_ep *int_in_ep;
struct usb_ep *int_out_ep;
int cur_alt;
};
@ -79,10 +68,6 @@ static unsigned isoc_interval;
static unsigned isoc_maxpacket;
static unsigned isoc_mult;
static unsigned isoc_maxburst;
static unsigned int_interval; /* In ms */
static unsigned int_maxpacket;
static unsigned int_mult;
static unsigned int_maxburst;
static unsigned buflen;
/*-------------------------------------------------------------------------*/
@ -107,16 +92,6 @@ static struct usb_interface_descriptor source_sink_intf_alt1 = {
/* .iInterface = DYNAMIC */
};
static struct usb_interface_descriptor source_sink_intf_alt2 = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bAlternateSetting = 2,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
/* .iInterface = DYNAMIC */
};
/* full speed support: */
static struct usb_endpoint_descriptor fs_source_desc = {
@ -155,26 +130,6 @@ static struct usb_endpoint_descriptor fs_iso_sink_desc = {
.bInterval = 4,
};
static struct usb_endpoint_descriptor fs_int_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval = GZERO_INT_INTERVAL,
};
static struct usb_endpoint_descriptor fs_int_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval = GZERO_INT_INTERVAL,
};
static struct usb_descriptor_header *fs_source_sink_descs[] = {
(struct usb_descriptor_header *) &source_sink_intf_alt0,
(struct usb_descriptor_header *) &fs_sink_desc,
@ -185,10 +140,6 @@ static struct usb_descriptor_header *fs_source_sink_descs[] = {
(struct usb_descriptor_header *) &fs_source_desc,
(struct usb_descriptor_header *) &fs_iso_sink_desc,
(struct usb_descriptor_header *) &fs_iso_source_desc,
(struct usb_descriptor_header *) &source_sink_intf_alt2,
#define FS_ALT_IFC_2_OFFSET 8
(struct usb_descriptor_header *) &fs_int_sink_desc,
(struct usb_descriptor_header *) &fs_int_source_desc,
NULL,
};
@ -228,24 +179,6 @@ static struct usb_endpoint_descriptor hs_iso_sink_desc = {
.bInterval = 4,
};
static struct usb_endpoint_descriptor hs_int_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
};
static struct usb_endpoint_descriptor hs_int_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = USB_MS_TO_HS_INTERVAL(GZERO_INT_INTERVAL),
};
static struct usb_descriptor_header *hs_source_sink_descs[] = {
(struct usb_descriptor_header *) &source_sink_intf_alt0,
(struct usb_descriptor_header *) &hs_source_desc,
@ -256,10 +189,6 @@ static struct usb_descriptor_header *hs_source_sink_descs[] = {
(struct usb_descriptor_header *) &hs_sink_desc,
(struct usb_descriptor_header *) &hs_iso_source_desc,
(struct usb_descriptor_header *) &hs_iso_sink_desc,
(struct usb_descriptor_header *) &source_sink_intf_alt2,
#define HS_ALT_IFC_2_OFFSET 8
(struct usb_descriptor_header *) &hs_int_source_desc,
(struct usb_descriptor_header *) &hs_int_sink_desc,
NULL,
};
@ -335,42 +264,6 @@ static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = {
.wBytesPerInterval = cpu_to_le16(1024),
};
static struct usb_endpoint_descriptor ss_int_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
};
static struct usb_ss_ep_comp_descriptor ss_int_source_comp_desc = {
.bLength = USB_DT_SS_EP_COMP_SIZE,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
.bMaxBurst = 0,
.bmAttributes = 0,
.wBytesPerInterval = cpu_to_le16(1024),
};
static struct usb_endpoint_descriptor ss_int_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bmAttributes = USB_ENDPOINT_XFER_INT,
.wMaxPacketSize = cpu_to_le16(1024),
.bInterval = USB_MS_TO_SS_INTERVAL(GZERO_INT_INTERVAL),
};
static struct usb_ss_ep_comp_descriptor ss_int_sink_comp_desc = {
.bLength = USB_DT_SS_EP_COMP_SIZE,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
.bMaxBurst = 0,
.bmAttributes = 0,
.wBytesPerInterval = cpu_to_le16(1024),
};
static struct usb_descriptor_header *ss_source_sink_descs[] = {
(struct usb_descriptor_header *) &source_sink_intf_alt0,
(struct usb_descriptor_header *) &ss_source_desc,
@ -387,12 +280,6 @@ static struct usb_descriptor_header *ss_source_sink_descs[] = {
(struct usb_descriptor_header *) &ss_iso_source_comp_desc,
(struct usb_descriptor_header *) &ss_iso_sink_desc,
(struct usb_descriptor_header *) &ss_iso_sink_comp_desc,
(struct usb_descriptor_header *) &source_sink_intf_alt2,
#define SS_ALT_IFC_2_OFFSET 14
(struct usb_descriptor_header *) &ss_int_source_desc,
(struct usb_descriptor_header *) &ss_int_source_comp_desc,
(struct usb_descriptor_header *) &ss_int_sink_desc,
(struct usb_descriptor_header *) &ss_int_sink_comp_desc,
NULL,
};
@ -414,21 +301,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
};
/*-------------------------------------------------------------------------*/
static const char *get_ep_string(enum eptype ep_type)
{
switch (ep_type) {
case EP_ISOC:
return "ISOC-";
case EP_INTERRUPT:
return "INTERRUPT-";
case EP_CONTROL:
return "CTRL-";
case EP_BULK:
return "BULK-";
default:
return "UNKNOWN-";
}
}
static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
{
@ -456,8 +328,7 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
void disable_endpoints(struct usb_composite_dev *cdev,
struct usb_ep *in, struct usb_ep *out,
struct usb_ep *iso_in, struct usb_ep *iso_out,
struct usb_ep *int_in, struct usb_ep *int_out)
struct usb_ep *iso_in, struct usb_ep *iso_out)
{
disable_ep(cdev, in);
disable_ep(cdev, out);
@ -465,10 +336,6 @@ void disable_endpoints(struct usb_composite_dev *cdev,
disable_ep(cdev, iso_in);
if (iso_out)
disable_ep(cdev, iso_out);
if (int_in)
disable_ep(cdev, int_in);
if (int_out)
disable_ep(cdev, int_out);
}
static int
@ -485,7 +352,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
return id;
source_sink_intf_alt0.bInterfaceNumber = id;
source_sink_intf_alt1.bInterfaceNumber = id;
source_sink_intf_alt2.bInterfaceNumber = id;
/* allocate bulk endpoints */
ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
@ -546,55 +412,14 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
if (isoc_maxpacket > 1024)
isoc_maxpacket = 1024;
/* sanity check the interrupt module parameters */
if (int_interval < 1)
int_interval = 1;
if (int_interval > 4096)
int_interval = 4096;
if (int_mult > 2)
int_mult = 2;
if (int_maxburst > 15)
int_maxburst = 15;
/* fill in the FS interrupt descriptors from the module parameters */
fs_int_source_desc.wMaxPacketSize = int_maxpacket > 64 ?
64 : int_maxpacket;
fs_int_source_desc.bInterval = int_interval > 255 ?
255 : int_interval;
fs_int_sink_desc.wMaxPacketSize = int_maxpacket > 64 ?
64 : int_maxpacket;
fs_int_sink_desc.bInterval = int_interval > 255 ?
255 : int_interval;
/* allocate int endpoints */
ss->int_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_source_desc);
if (!ss->int_in_ep)
goto no_int;
ss->int_in_ep->driver_data = cdev; /* claim */
ss->int_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_int_sink_desc);
if (ss->int_out_ep) {
ss->int_out_ep->driver_data = cdev; /* claim */
} else {
ss->int_in_ep->driver_data = NULL;
ss->int_in_ep = NULL;
no_int:
fs_source_sink_descs[FS_ALT_IFC_2_OFFSET] = NULL;
hs_source_sink_descs[HS_ALT_IFC_2_OFFSET] = NULL;
ss_source_sink_descs[SS_ALT_IFC_2_OFFSET] = NULL;
}
if (int_maxpacket > 1024)
int_maxpacket = 1024;
/* support high speed hardware */
hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress;
/*
* Fill in the HS isoc and interrupt descriptors from the module
* parameters. We assume that the user knows what they are doing and
* won't give parameters that their UDC doesn't support.
* Fill in the HS isoc descriptors from the module parameters.
* We assume that the user knows what they are doing and won't
* give parameters that their UDC doesn't support.
*/
hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
@ -607,17 +432,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
hs_iso_sink_desc.bInterval = isoc_interval;
hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
hs_int_source_desc.wMaxPacketSize = int_maxpacket;
hs_int_source_desc.wMaxPacketSize |= int_mult << 11;
hs_int_source_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
hs_int_source_desc.bEndpointAddress =
fs_int_source_desc.bEndpointAddress;
hs_int_sink_desc.wMaxPacketSize = int_maxpacket;
hs_int_sink_desc.wMaxPacketSize |= int_mult << 11;
hs_int_sink_desc.bInterval = USB_MS_TO_HS_INTERVAL(int_interval);
hs_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
/* support super speed hardware */
ss_source_desc.bEndpointAddress =
fs_source_desc.bEndpointAddress;
@ -625,9 +439,9 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
fs_sink_desc.bEndpointAddress;
/*
* Fill in the SS isoc and interrupt descriptors from the module
* parameters. We assume that the user knows what they are doing and
* won't give parameters that their UDC doesn't support.
* Fill in the SS isoc descriptors from the module parameters.
* We assume that the user knows what they are doing and won't
* give parameters that their UDC doesn't support.
*/
ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
ss_iso_source_desc.bInterval = isoc_interval;
@ -646,37 +460,17 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
ss_int_source_desc.wMaxPacketSize = int_maxpacket;
ss_int_source_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
ss_int_source_comp_desc.bmAttributes = int_mult;
ss_int_source_comp_desc.bMaxBurst = int_maxburst;
ss_int_source_comp_desc.wBytesPerInterval =
int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
ss_int_source_desc.bEndpointAddress =
fs_int_source_desc.bEndpointAddress;
ss_int_sink_desc.wMaxPacketSize = int_maxpacket;
ss_int_sink_desc.bInterval = USB_MS_TO_SS_INTERVAL(int_interval);
ss_int_sink_comp_desc.bmAttributes = int_mult;
ss_int_sink_comp_desc.bMaxBurst = int_maxburst;
ss_int_sink_comp_desc.wBytesPerInterval =
int_maxpacket * (int_mult + 1) * (int_maxburst + 1);
ss_int_sink_desc.bEndpointAddress = fs_int_sink_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, fs_source_sink_descs,
hs_source_sink_descs, ss_source_sink_descs);
if (ret)
return ret;
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s, "
"INT-IN/%s, INT-OUT/%s\n",
DBG(cdev, "%s speed %s: IN/%s, OUT/%s, ISO-IN/%s, ISO-OUT/%s\n",
(gadget_is_superspeed(c->cdev->gadget) ? "super" :
(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")),
f->name, ss->in_ep->name, ss->out_ep->name,
ss->iso_in_ep ? ss->iso_in_ep->name : "<none>",
ss->iso_out_ep ? ss->iso_out_ep->name : "<none>",
ss->int_in_ep ? ss->int_in_ep->name : "<none>",
ss->int_out_ep ? ss->int_out_ep->name : "<none>");
ss->iso_out_ep ? ss->iso_out_ep->name : "<none>");
return 0;
}
@ -807,15 +601,14 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
}
static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
enum eptype ep_type, int speed)
bool is_iso, int speed)
{
struct usb_ep *ep;
struct usb_request *req;
int i, size, status;
for (i = 0; i < 8; i++) {
switch (ep_type) {
case EP_ISOC:
if (is_iso) {
switch (speed) {
case USB_SPEED_SUPER:
size = isoc_maxpacket * (isoc_mult + 1) *
@ -831,28 +624,9 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
}
ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
req = ss_alloc_ep_req(ep, size);
break;
case EP_INTERRUPT:
switch (speed) {
case USB_SPEED_SUPER:
size = int_maxpacket * (int_mult + 1) *
(int_maxburst + 1);
break;
case USB_SPEED_HIGH:
size = int_maxpacket * (int_mult + 1);
break;
default:
size = int_maxpacket > 1023 ?
1023 : int_maxpacket;
break;
}
ep = is_in ? ss->int_in_ep : ss->int_out_ep;
req = ss_alloc_ep_req(ep, size);
break;
default:
} else {
ep = is_in ? ss->in_ep : ss->out_ep;
req = ss_alloc_ep_req(ep, 0);
break;
}
if (!req)
@ -870,12 +644,12 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
cdev = ss->function.config->cdev;
ERROR(cdev, "start %s%s %s --> %d\n",
get_ep_string(ep_type), is_in ? "IN" : "OUT",
ep->name, status);
is_iso ? "ISO-" : "", is_in ? "IN" : "OUT",
ep->name, status);
free_ep_req(ep, req);
}
if (!(ep_type == EP_ISOC))
if (!is_iso)
break;
}
@ -888,7 +662,7 @@ static void disable_source_sink(struct f_sourcesink *ss)
cdev = ss->function.config->cdev;
disable_endpoints(cdev, ss->in_ep, ss->out_ep, ss->iso_in_ep,
ss->iso_out_ep, ss->int_in_ep, ss->int_out_ep);
ss->iso_out_ep);
VDBG(cdev, "%s disabled\n", ss->function.name);
}
@ -900,62 +674,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
int speed = cdev->gadget->speed;
struct usb_ep *ep;
if (alt == 2) {
/* Configure for periodic interrupt endpoint */
ep = ss->int_in_ep;
if (ep) {
result = config_ep_by_speed(cdev->gadget,
&(ss->function), ep);
if (result)
return result;
result = usb_ep_enable(ep);
if (result < 0)
return result;
ep->driver_data = ss;
result = source_sink_start_ep(ss, true, EP_INTERRUPT,
speed);
if (result < 0) {
fail1:
ep = ss->int_in_ep;
if (ep) {
usb_ep_disable(ep);
ep->driver_data = NULL;
}
return result;
}
}
/*
* one interrupt endpoint reads (sinks) anything OUT (from the
* host)
*/
ep = ss->int_out_ep;
if (ep) {
result = config_ep_by_speed(cdev->gadget,
&(ss->function), ep);
if (result)
goto fail1;
result = usb_ep_enable(ep);
if (result < 0)
goto fail1;
ep->driver_data = ss;
result = source_sink_start_ep(ss, false, EP_INTERRUPT,
speed);
if (result < 0) {
ep = ss->int_out_ep;
usb_ep_disable(ep);
ep->driver_data = NULL;
goto fail1;
}
}
goto out;
}
/* one bulk endpoint writes (sources) zeroes IN (to the host) */
ep = ss->in_ep;
result = config_ep_by_speed(cdev->gadget, &(ss->function), ep);
@ -966,7 +684,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
return result;
ep->driver_data = ss;
result = source_sink_start_ep(ss, true, EP_BULK, speed);
result = source_sink_start_ep(ss, true, false, speed);
if (result < 0) {
fail:
ep = ss->in_ep;
@ -985,7 +703,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
goto fail;
ep->driver_data = ss;
result = source_sink_start_ep(ss, false, EP_BULK, speed);
result = source_sink_start_ep(ss, false, false, speed);
if (result < 0) {
fail2:
ep = ss->out_ep;
@ -1008,7 +726,7 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
goto fail2;
ep->driver_data = ss;
result = source_sink_start_ep(ss, true, EP_ISOC, speed);
result = source_sink_start_ep(ss, true, true, speed);
if (result < 0) {
fail3:
ep = ss->iso_in_ep;
@ -1031,14 +749,13 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss,
goto fail3;
ep->driver_data = ss;
result = source_sink_start_ep(ss, false, EP_ISOC, speed);
result = source_sink_start_ep(ss, false, true, speed);
if (result < 0) {
usb_ep_disable(ep);
ep->driver_data = NULL;
goto fail3;
}
}
out:
ss->cur_alt = alt;
@ -1054,8 +771,6 @@ static int sourcesink_set_alt(struct usb_function *f,
if (ss->in_ep->driver_data)
disable_source_sink(ss);
else if (alt == 2 && ss->int_in_ep->driver_data)
disable_source_sink(ss);
return enable_source_sink(cdev, ss, alt);
}
@ -1168,10 +883,6 @@ static struct usb_function *source_sink_alloc_func(
isoc_maxpacket = ss_opts->isoc_maxpacket;
isoc_mult = ss_opts->isoc_mult;
isoc_maxburst = ss_opts->isoc_maxburst;
int_interval = ss_opts->int_interval;
int_maxpacket = ss_opts->int_maxpacket;
int_mult = ss_opts->int_mult;
int_maxburst = ss_opts->int_maxburst;
buflen = ss_opts->bulk_buflen;
ss->function.name = "source/sink";
@ -1468,182 +1179,6 @@ static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
f_ss_opts_bulk_buflen_show,
f_ss_opts_bulk_buflen_store);
static ssize_t f_ss_opts_int_interval_show(struct f_ss_opts *opts, char *page)
{
int result;
mutex_lock(&opts->lock);
result = sprintf(page, "%u", opts->int_interval);
mutex_unlock(&opts->lock);
return result;
}
static ssize_t f_ss_opts_int_interval_store(struct f_ss_opts *opts,
const char *page, size_t len)
{
int ret;
u32 num;
mutex_lock(&opts->lock);
if (opts->refcnt) {
ret = -EBUSY;
goto end;
}
ret = kstrtou32(page, 0, &num);
if (ret)
goto end;
if (num > 4096) {
ret = -EINVAL;
goto end;
}
opts->int_interval = num;
ret = len;
end:
mutex_unlock(&opts->lock);
return ret;
}
static struct f_ss_opts_attribute f_ss_opts_int_interval =
__CONFIGFS_ATTR(int_interval, S_IRUGO | S_IWUSR,
f_ss_opts_int_interval_show,
f_ss_opts_int_interval_store);
static ssize_t f_ss_opts_int_maxpacket_show(struct f_ss_opts *opts, char *page)
{
int result;
mutex_lock(&opts->lock);
result = sprintf(page, "%u", opts->int_maxpacket);
mutex_unlock(&opts->lock);
return result;
}
static ssize_t f_ss_opts_int_maxpacket_store(struct f_ss_opts *opts,
const char *page, size_t len)
{
int ret;
u16 num;
mutex_lock(&opts->lock);
if (opts->refcnt) {
ret = -EBUSY;
goto end;
}
ret = kstrtou16(page, 0, &num);
if (ret)
goto end;
if (num > 1024) {
ret = -EINVAL;
goto end;
}
opts->int_maxpacket = num;
ret = len;
end:
mutex_unlock(&opts->lock);
return ret;
}
static struct f_ss_opts_attribute f_ss_opts_int_maxpacket =
__CONFIGFS_ATTR(int_maxpacket, S_IRUGO | S_IWUSR,
f_ss_opts_int_maxpacket_show,
f_ss_opts_int_maxpacket_store);
static ssize_t f_ss_opts_int_mult_show(struct f_ss_opts *opts, char *page)
{
int result;
mutex_lock(&opts->lock);
result = sprintf(page, "%u", opts->int_mult);
mutex_unlock(&opts->lock);
return result;
}
static ssize_t f_ss_opts_int_mult_store(struct f_ss_opts *opts,
const char *page, size_t len)
{
int ret;
u8 num;
mutex_lock(&opts->lock);
if (opts->refcnt) {
ret = -EBUSY;
goto end;
}
ret = kstrtou8(page, 0, &num);
if (ret)
goto end;
if (num > 2) {
ret = -EINVAL;
goto end;
}
opts->int_mult = num;
ret = len;
end:
mutex_unlock(&opts->lock);
return ret;
}
static struct f_ss_opts_attribute f_ss_opts_int_mult =
__CONFIGFS_ATTR(int_mult, S_IRUGO | S_IWUSR,
f_ss_opts_int_mult_show,
f_ss_opts_int_mult_store);
static ssize_t f_ss_opts_int_maxburst_show(struct f_ss_opts *opts, char *page)
{
int result;
mutex_lock(&opts->lock);
result = sprintf(page, "%u", opts->int_maxburst);
mutex_unlock(&opts->lock);
return result;
}
static ssize_t f_ss_opts_int_maxburst_store(struct f_ss_opts *opts,
const char *page, size_t len)
{
int ret;
u8 num;
mutex_lock(&opts->lock);
if (opts->refcnt) {
ret = -EBUSY;
goto end;
}
ret = kstrtou8(page, 0, &num);
if (ret)
goto end;
if (num > 15) {
ret = -EINVAL;
goto end;
}
opts->int_maxburst = num;
ret = len;
end:
mutex_unlock(&opts->lock);
return ret;
}
static struct f_ss_opts_attribute f_ss_opts_int_maxburst =
__CONFIGFS_ATTR(int_maxburst, S_IRUGO | S_IWUSR,
f_ss_opts_int_maxburst_show,
f_ss_opts_int_maxburst_store);
static struct configfs_attribute *ss_attrs[] = {
&f_ss_opts_pattern.attr,
&f_ss_opts_isoc_interval.attr,
@ -1651,10 +1186,6 @@ static struct configfs_attribute *ss_attrs[] = {
&f_ss_opts_isoc_mult.attr,
&f_ss_opts_isoc_maxburst.attr,
&f_ss_opts_bulk_buflen.attr,
&f_ss_opts_int_interval.attr,
&f_ss_opts_int_maxpacket.attr,
&f_ss_opts_int_mult.attr,
&f_ss_opts_int_maxburst.attr,
NULL,
};
@ -1684,8 +1215,6 @@ static struct usb_function_instance *source_sink_alloc_inst(void)
ss_opts->isoc_interval = GZERO_ISOC_INTERVAL;
ss_opts->isoc_maxpacket = GZERO_ISOC_MAXPACKET;
ss_opts->bulk_buflen = GZERO_BULK_BUFLEN;
ss_opts->int_interval = GZERO_INT_INTERVAL;
ss_opts->int_maxpacket = GZERO_INT_MAXPACKET;
config_group_init_type_name(&ss_opts->func_inst.group, "",
&ss_func_type);

View File

@ -10,8 +10,6 @@
#define GZERO_QLEN 32
#define GZERO_ISOC_INTERVAL 4
#define GZERO_ISOC_MAXPACKET 1024
#define GZERO_INT_INTERVAL 1 /* Default interrupt interval = 1 ms */
#define GZERO_INT_MAXPACKET 1024
struct usb_zero_options {
unsigned pattern;
@ -19,10 +17,6 @@ struct usb_zero_options {
unsigned isoc_maxpacket;
unsigned isoc_mult;
unsigned isoc_maxburst;
unsigned int_interval; /* In ms */
unsigned int_maxpacket;
unsigned int_mult;
unsigned int_maxburst;
unsigned bulk_buflen;
unsigned qlen;
};
@ -34,10 +28,6 @@ struct f_ss_opts {
unsigned isoc_maxpacket;
unsigned isoc_mult;
unsigned isoc_maxburst;
unsigned int_interval; /* In ms */
unsigned int_maxpacket;
unsigned int_mult;
unsigned int_maxburst;
unsigned bulk_buflen;
/*
@ -72,7 +62,6 @@ int lb_modinit(void);
void free_ep_req(struct usb_ep *ep, struct usb_request *req);
void disable_endpoints(struct usb_composite_dev *cdev,
struct usb_ep *in, struct usb_ep *out,
struct usb_ep *iso_in, struct usb_ep *iso_out,
struct usb_ep *int_in, struct usb_ep *int_out);
struct usb_ep *iso_in, struct usb_ep *iso_out);
#endif /* __G_ZERO_H */

View File

@ -1740,10 +1740,9 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
goto err_session;
}
/*
* Now register the TCM vHost virtual I_T Nexus as active with the
* call to __transport_register_session()
* Now register the TCM vHost virtual I_T Nexus as active.
*/
__transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
tv_nexus->tvn_se_sess, tv_nexus);
tpg->tpg_nexus = tv_nexus;
mutex_unlock(&tpg->tpg_mutex);

Some files were not shown because too many files have changed in this diff Show More