Merge branch 'fix' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6
This commit is contained in:
Коммит
04228460a3
|
@ -516,6 +516,7 @@ int main(int argc, char *argv[])
|
|||
default:
|
||||
fprintf(stderr, "Unknown nla_type %d\n",
|
||||
na->nla_type);
|
||||
case TASKSTATS_TYPE_NULL:
|
||||
break;
|
||||
}
|
||||
na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
|
||||
|
|
|
@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
reset_devices [KNL] Force drivers to reset the underlying device
|
||||
during initialization.
|
||||
|
||||
resource_alloc_from_bottom
|
||||
Allocate new resources from the beginning of available
|
||||
space, not the end. If you need to use this, please
|
||||
report a bug.
|
||||
|
||||
resume= [SWSUSP]
|
||||
Specify the partition device for software suspend
|
||||
|
||||
|
|
|
@ -1044,9 +1044,9 @@ Details:
|
|||
|
||||
|
||||
/**
|
||||
* queuecommand - queue scsi command, invoke 'done' on completion
|
||||
* queuecommand - queue scsi command, invoke scp->scsi_done on completion
|
||||
* @shost: pointer to the scsi host object
|
||||
* @scp: pointer to scsi command object
|
||||
* @done: function pointer to be invoked on completion
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*
|
||||
|
@ -1074,42 +1074,45 @@ Details:
|
|||
*
|
||||
* Other types of errors that are detected immediately may be
|
||||
* flagged by setting scp->result to an appropriate value,
|
||||
* invoking the 'done' callback, and then returning 0 from this
|
||||
* function. If the command is not performed immediately (and the
|
||||
* LLD is starting (or will start) the given command) then this
|
||||
* function should place 0 in scp->result and return 0.
|
||||
* invoking the scp->scsi_done callback, and then returning 0
|
||||
* from this function. If the command is not performed
|
||||
* immediately (and the LLD is starting (or will start) the given
|
||||
* command) then this function should place 0 in scp->result and
|
||||
* return 0.
|
||||
*
|
||||
* Command ownership. If the driver returns zero, it owns the
|
||||
* command and must take responsibility for ensuring the 'done'
|
||||
* callback is executed. Note: the driver may call done before
|
||||
* returning zero, but after it has called done, it may not
|
||||
* return any value other than zero. If the driver makes a
|
||||
* non-zero return, it must not execute the command's done
|
||||
* callback at any time.
|
||||
* command and must take responsibility for ensuring the
|
||||
* scp->scsi_done callback is executed. Note: the driver may
|
||||
* call scp->scsi_done before returning zero, but after it has
|
||||
* called scp->scsi_done, it may not return any value other than
|
||||
* zero. If the driver makes a non-zero return, it must not
|
||||
* execute the command's scsi_done callback at any time.
|
||||
*
|
||||
* Locks: struct Scsi_Host::host_lock held on entry (with "irqsave")
|
||||
* and is expected to be held on return.
|
||||
* Locks: up to and including 2.6.36, struct Scsi_Host::host_lock
|
||||
* held on entry (with "irqsave") and is expected to be
|
||||
* held on return. From 2.6.37 onwards, queuecommand is
|
||||
* called without any locks held.
|
||||
*
|
||||
* Calling context: in interrupt (soft irq) or process context
|
||||
*
|
||||
* Notes: This function should be relatively fast. Normally it will
|
||||
* not wait for IO to complete. Hence the 'done' callback is invoked
|
||||
* (often directly from an interrupt service routine) some time after
|
||||
* this function has returned. In some cases (e.g. pseudo adapter
|
||||
* drivers that manufacture the response to a SCSI INQUIRY)
|
||||
* the 'done' callback may be invoked before this function returns.
|
||||
* If the 'done' callback is not invoked within a certain period
|
||||
* the SCSI mid level will commence error processing.
|
||||
* If a status of CHECK CONDITION is placed in "result" when the
|
||||
* 'done' callback is invoked, then the LLD driver should
|
||||
* perform autosense and fill in the struct scsi_cmnd::sense_buffer
|
||||
* Notes: This function should be relatively fast. Normally it
|
||||
* will not wait for IO to complete. Hence the scp->scsi_done
|
||||
* callback is invoked (often directly from an interrupt service
|
||||
* routine) some time after this function has returned. In some
|
||||
* cases (e.g. pseudo adapter drivers that manufacture the
|
||||
* response to a SCSI INQUIRY) the scp->scsi_done callback may be
|
||||
* invoked before this function returns. If the scp->scsi_done
|
||||
* callback is not invoked within a certain period the SCSI mid
|
||||
* level will commence error processing. If a status of CHECK
|
||||
* CONDITION is placed in "result" when the scp->scsi_done
|
||||
* callback is invoked, then the LLD driver should perform
|
||||
* autosense and fill in the struct scsi_cmnd::sense_buffer
|
||||
* array. The scsi_cmnd::sense_buffer array is zeroed prior to
|
||||
* the mid level queuing a command to an LLD.
|
||||
*
|
||||
* Defined in: LLD
|
||||
**/
|
||||
int queuecommand(struct scsi_cmnd * scp,
|
||||
void (*done)(struct scsi_cmnd *))
|
||||
int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp)
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -373,9 +373,18 @@ EVENT_PROCESS:
|
|||
print " $regex_lru_isolate/o\n";
|
||||
next;
|
||||
}
|
||||
my $isolate_mode = $1;
|
||||
my $nr_scanned = $4;
|
||||
my $nr_contig_dirty = $7;
|
||||
$perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
|
||||
|
||||
# To closer match vmstat scanning statistics, only count isolate_both
|
||||
# and isolate_inactive as scanning. isolate_active is rotation
|
||||
# isolate_inactive == 0
|
||||
# isolate_active == 1
|
||||
# isolate_both == 2
|
||||
if ($isolate_mode != 1) {
|
||||
$perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned;
|
||||
}
|
||||
$perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty;
|
||||
} elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") {
|
||||
$details = $5;
|
||||
|
|
|
@ -405,7 +405,7 @@ S: Supported
|
|||
F: drivers/usb/gadget/amd5536udc.*
|
||||
|
||||
AMD GEODE PROCESSOR/CHIPSET SUPPORT
|
||||
P: Jordan Crouse
|
||||
P: Andres Salomon <dilinger@queued.net>
|
||||
L: linux-geode@lists.infradead.org (moderated for non-subscribers)
|
||||
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
|
||||
S: Supported
|
||||
|
@ -4605,7 +4605,7 @@ F: drivers/pcmcia/
|
|||
F: include/pcmcia/
|
||||
|
||||
PCNET32 NETWORK DRIVER
|
||||
M: Don Fry <pcnet32@verizon.net>
|
||||
M: Don Fry <pcnet32@frontier.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/pcnet32.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 37
|
||||
EXTRAVERSION = -rc6
|
||||
EXTRAVERSION = -rc8
|
||||
NAME = Flesh-Eating Bats with Fangs
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys)
|
|||
return pci_scan_bus(nr, &it8152_ops, sys);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dma_set_coherent_mask);
|
||||
|
|
|
@ -76,6 +76,7 @@ extern unsigned long it8152_base_address;
|
|||
IT8152_PD_IRQ(0) Audio controller (ACR)
|
||||
*/
|
||||
#define IT8152_IRQ(x) (IRQ_BOARD_START + (x))
|
||||
#define IT8152_LAST_IRQ (IRQ_BOARD_START + 40)
|
||||
|
||||
/* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
|
||||
#define IT8152_LD_IRQ_COUNT 9
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
#define AT91_MCI_TRTYP_BLOCK (0 << 19)
|
||||
#define AT91_MCI_TRTYP_MULTIPLE (1 << 19)
|
||||
#define AT91_MCI_TRTYP_STREAM (2 << 19)
|
||||
#define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19)
|
||||
#define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19)
|
||||
|
||||
#define AT91_MCI_BLKR 0x18 /* Block Register */
|
||||
#define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */
|
||||
|
|
|
@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
|
|||
|
||||
EXPORT_SYMBOL(ixp4xx_pci_read);
|
||||
EXPORT_SYMBOL(ixp4xx_pci_write);
|
||||
|
||||
EXPORT_SYMBOL(dma_set_coherent_mask);
|
||||
|
|
|
@ -353,8 +353,8 @@ resume_turn_on_mmu:
|
|||
|
||||
@ Let us ensure we jump to resume_after_mmu only when the mcr above
|
||||
@ actually took effect. They call it the "cpwait" operation.
|
||||
mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15
|
||||
sub pc, r2, r1, lsr #32 @ jump to virtual addr
|
||||
mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15
|
||||
sub pc, r2, r0, lsr #32 @ jump to virtual addr
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
|
|
@ -28,9 +28,16 @@ config S3C2412_DMA
|
|||
|
||||
config S3C2412_PM
|
||||
bool
|
||||
select S3C2412_PM_SLEEP
|
||||
help
|
||||
Internal config node to apply S3C2412 power management
|
||||
|
||||
config S3C2412_PM_SLEEP
|
||||
bool
|
||||
help
|
||||
Internal config node to apply sleep for S3C2412 power management.
|
||||
Can be selected by another SoCs with similar sleep procedure.
|
||||
|
||||
# Note, the S3C2412 IOtiming support is in plat-s3c24xx
|
||||
|
||||
config S3C2412_CPUFREQ
|
||||
|
|
|
@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o
|
|||
obj-$(CONFIG_CPU_S3C2412) += clock.o
|
||||
obj-$(CONFIG_CPU_S3C2412) += gpio.o
|
||||
obj-$(CONFIG_S3C2412_DMA) += dma.o
|
||||
obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o
|
||||
obj-$(CONFIG_S3C2412_PM) += pm.o
|
||||
obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o
|
||||
obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o
|
||||
|
||||
# Machine support
|
||||
|
|
|
@ -27,6 +27,7 @@ config S3C2416_DMA
|
|||
|
||||
config S3C2416_PM
|
||||
bool
|
||||
select S3C2412_PM_SLEEP
|
||||
help
|
||||
Internal config node to apply S3C2416 power management
|
||||
|
||||
|
|
|
@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = {
|
|||
static struct max8998_platform_data aquila_max8998_pdata = {
|
||||
.num_regulators = ARRAY_SIZE(aquila_regulators),
|
||||
.regulators = aquila_regulators,
|
||||
.buck1_set1 = S5PV210_GPH0(3),
|
||||
.buck1_set2 = S5PV210_GPH0(4),
|
||||
.buck2_set3 = S5PV210_GPH0(5),
|
||||
.buck1_max_voltage1 = 1200000,
|
||||
.buck1_max_voltage2 = 1200000,
|
||||
.buck2_max_voltage = 1200000,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = {
|
|||
static struct max8998_platform_data goni_max8998_pdata = {
|
||||
.num_regulators = ARRAY_SIZE(goni_regulators),
|
||||
.regulators = goni_regulators,
|
||||
.buck1_set1 = S5PV210_GPH0(3),
|
||||
.buck1_set2 = S5PV210_GPH0(4),
|
||||
.buck2_set3 = S5PV210_GPH0(5),
|
||||
.buck1_max_voltage1 = 1200000,
|
||||
.buck1_max_voltage2 = 1200000,
|
||||
.buck2_max_voltage = 1200000,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010 Magnus Damm
|
||||
* Copyright (C) 2008 Renesas Solutions Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -14,24 +15,45 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#define INTCA_BASE 0xe6980000
|
||||
#define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */
|
||||
#define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */
|
||||
#define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */
|
||||
#define INTLVLB_OFFS 0x00000034 /* previous priority level */
|
||||
|
||||
.macro disable_fiq
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_preamble, base, tmp
|
||||
ldr \base, =INTFLGA
|
||||
ldr \base, =INTCA_BASE
|
||||
.endm
|
||||
|
||||
.macro arch_ret_to_user, tmp1, tmp2
|
||||
.endm
|
||||
|
||||
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
|
||||
ldr \irqnr, [\base]
|
||||
/* The single INTFLGA read access below results in the following:
|
||||
*
|
||||
* 1. INTLVLB is updated with old priority value from INTLVLA
|
||||
* 2. Highest priority interrupt is accepted
|
||||
* 3. INTLVLA is updated to contain priority of accepted interrupt
|
||||
* 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA
|
||||
*/
|
||||
ldr \irqnr, [\base, #INTFLGA_OFFS]
|
||||
|
||||
/* Restore INTLVLA with the value saved in INTLVLB.
|
||||
* This is required to support interrupt priorities properly.
|
||||
*/
|
||||
ldrb \tmp, [\base, #INTLVLB_OFFS]
|
||||
strb \tmp, [\base, #INTLVLA_OFFS]
|
||||
|
||||
/* Handle invalid vector number case */
|
||||
cmp \irqnr, #0
|
||||
beq 1000f
|
||||
/* intevt to irq number */
|
||||
|
||||
/* Convert vector to irq number, same as the evt2irq() macro */
|
||||
lsr \irqnr, \irqnr, #0x5
|
||||
subs \irqnr, \irqnr, #16
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
#define __ASM_MACH_VMALLOC_H
|
||||
|
||||
/* Vmalloc at ... - 0xe5ffffff */
|
||||
#define VMALLOC_END 0xe6000000
|
||||
#define VMALLOC_END 0xe6000000UL
|
||||
|
||||
#endif /* __ASM_MACH_VMALLOC_H */
|
||||
|
|
|
@ -8,7 +8,7 @@ config PLAT_S3C24XX
|
|||
default y
|
||||
select NO_IOPORT
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select S3C_DEVICE_NAND
|
||||
select S3C_DEV_NAND
|
||||
select S3C_GPIO_CFG_S3C24XX
|
||||
help
|
||||
Base platform code for any Samsung S3C24XX device
|
||||
|
|
|
@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = {
|
|||
*/
|
||||
static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
|
||||
{
|
||||
unsigned int config2 = read_c0_config2();
|
||||
unsigned int tmp;
|
||||
|
||||
/* Check the bypass bit (L2B) */
|
||||
switch (c->cputype) {
|
||||
case CPU_34K:
|
||||
|
@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c)
|
|||
c->scache.linesz = 2 << tmp;
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int __init mips_sc_probe(void)
|
||||
|
|
|
@ -40,21 +40,17 @@ unsigned long long sched_clock(void)
|
|||
unsigned long long ll;
|
||||
unsigned l[2];
|
||||
} tsc64, result;
|
||||
unsigned long tsc, tmp;
|
||||
unsigned long tmp;
|
||||
unsigned product[3]; /* 96-bit intermediate value */
|
||||
|
||||
/* cnt32_to_63() is not safe with preemption */
|
||||
preempt_disable();
|
||||
|
||||
/* read the TSC value
|
||||
*/
|
||||
tsc = get_cycles();
|
||||
|
||||
/* expand to 64-bits.
|
||||
/* expand the tsc to 64-bits.
|
||||
* - sched_clock() must be called once a minute or better or the
|
||||
* following will go horribly wrong - see cnt32_to_63()
|
||||
*/
|
||||
tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
|
||||
tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
|
||||
|
||||
preempt_enable();
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include <linux/of_gpio.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/watchdog.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
|
|
@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void)
|
|||
make_se7206_irq(IRQ1_IRQ); /* ATA */
|
||||
make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */
|
||||
|
||||
__raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */
|
||||
__raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */
|
||||
|
||||
/* FPGA System register setup*/
|
||||
__raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */
|
||||
|
|
|
@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12};
|
|||
|
||||
static void master_clk_init(struct clk *clk)
|
||||
{
|
||||
return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
|
||||
clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007];
|
||||
}
|
||||
|
||||
static struct clk_ops sh7201_master_clk_ops = {
|
||||
|
|
|
@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk)
|
|||
for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
|
||||
int divisor = frqcr3_divisors[i];
|
||||
|
||||
if (clk->ops->set_rate(clk, clk->parent->rate /
|
||||
divisor, 0) == 0)
|
||||
if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
|
||||
struct pt_regs;
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
|
||||
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
|
||||
void do_signal(struct pt_regs *regs);
|
||||
#endif
|
||||
|
|
|
@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* The assembly shim for this function arranges to ignore the return value. */
|
||||
long compat_sys_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct compat_rt_sigframe __user *frame =
|
||||
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
|
||||
sigset_t set;
|
||||
long r0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
|
||||
goto badframe;
|
||||
|
||||
return r0;
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
|
|
|
@ -1342,8 +1342,8 @@ handle_syscall:
|
|||
lw r20, r20
|
||||
|
||||
/* Jump to syscall handler. */
|
||||
jalr r20; .Lhandle_syscall_link:
|
||||
FEEDBACK_REENTER(handle_syscall)
|
||||
jalr r20
|
||||
.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
|
||||
|
||||
/*
|
||||
* Write our r0 onto the stack so it gets restored instead
|
||||
|
@ -1352,6 +1352,9 @@ handle_syscall:
|
|||
PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
|
||||
sw r29, r0
|
||||
|
||||
.Lsyscall_sigreturn_skip:
|
||||
FEEDBACK_REENTER(handle_syscall)
|
||||
|
||||
/* Do syscall trace again, if requested. */
|
||||
lw r30, r31
|
||||
andi r30, r30, _TIF_SYSCALL_TRACE
|
||||
|
@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
|
|||
}; \
|
||||
STD_ENDPROC(_##x)
|
||||
|
||||
/*
|
||||
* Special-case sigreturn to not write r0 to the stack on return.
|
||||
* This is technically more efficient, but it also avoids difficulties
|
||||
* in the 64-bit OS when handling 32-bit compat code, since we must not
|
||||
* sign-extend r0 for the sigreturn return-value case.
|
||||
*/
|
||||
#define PTREGS_SYSCALL_SIGRETURN(x, reg) \
|
||||
STD_ENTRY(_##x); \
|
||||
addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
|
||||
{ \
|
||||
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
|
||||
j x \
|
||||
}; \
|
||||
STD_ENDPROC(_##x)
|
||||
|
||||
PTREGS_SYSCALL(sys_execve, r3)
|
||||
PTREGS_SYSCALL(sys_sigaltstack, r2)
|
||||
PTREGS_SYSCALL(sys_rt_sigreturn, r0)
|
||||
PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
|
||||
PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)
|
||||
|
||||
/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
|
||||
|
|
|
@ -211,6 +211,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
|
|||
childregs->regs[0] = 0; /* return value is zero */
|
||||
childregs->sp = sp; /* override with new user stack pointer */
|
||||
|
||||
/*
|
||||
* If CLONE_SETTLS is set, set "tp" in the new task to "r4",
|
||||
* which is passed in as arg #5 to sys_clone().
|
||||
*/
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
childregs->tp = regs->regs[4];
|
||||
|
||||
/*
|
||||
* Copy the callee-saved registers from the passed pt_regs struct
|
||||
* into the context-switch callee-saved registers area.
|
||||
|
@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
|
|||
return __switch_to(prev, next, next_current_ksp0(next));
|
||||
}
|
||||
|
||||
/* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
|
||||
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
||||
void __user *, parent_tidptr, void __user *, child_tidptr,
|
||||
struct pt_regs *, regs)
|
||||
|
|
|
@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
|
|||
*/
|
||||
|
||||
int restore_sigcontext(struct pt_regs *regs,
|
||||
struct sigcontext __user *sc, long *pr0)
|
||||
struct sigcontext __user *sc)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
|
@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,
|
|||
|
||||
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
||||
|
||||
err |= __get_user(*pr0, &sc->gregs[0]);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sigreturn() returns long since it restores r0 in the interrupted code. */
|
||||
/* The assembly shim for this function arranges to ignore the return value. */
|
||||
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame =
|
||||
(struct rt_sigframe __user *)(regs->sp);
|
||||
sigset_t set;
|
||||
long r0;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return r0;
|
||||
return 0;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
|
|
|
@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,
|
|||
if (heap > 0x3fffffffffffUL)
|
||||
error("Destination address too large");
|
||||
#else
|
||||
if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
|
||||
if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
|
||||
error("Destination address too large");
|
||||
#endif
|
||||
#ifndef CONFIG_RELOCATABLE
|
||||
|
|
|
@ -72,6 +72,9 @@ struct e820map {
|
|||
#define BIOS_BEGIN 0x000a0000
|
||||
#define BIOS_END 0x00100000
|
||||
|
||||
#define BIOS_ROM_BASE 0xffe00000
|
||||
#define BIOS_ROM_END 0xffffffff
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* see comment in arch/x86/kernel/e820.c */
|
||||
extern struct e820map e820;
|
||||
|
|
|
@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
|
|||
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
|
||||
obj-y += tsc.o io_delay.o rtc.o
|
||||
obj-y += pci-iommu_table.o
|
||||
obj-y += resource.o
|
||||
|
||||
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
|
||||
obj-y += process.o
|
||||
|
|
|
@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void)
|
|||
|
||||
setup_apic_nmi_watchdog(NULL);
|
||||
apic_pm_activate();
|
||||
|
||||
/*
|
||||
* Now that local APIC setup is completed for BP, configure the fault
|
||||
* handling for interrupt remapping.
|
||||
*/
|
||||
if (!smp_processor_id() && intr_remapping_enabled)
|
||||
enable_drhd_fault_handling();
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_X2APIC
|
||||
|
|
|
@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data)
|
|||
{
|
||||
struct irq_cfg *cfg = data->chip_data;
|
||||
int i, do_unmask_irq = 0, irq = data->irq;
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
unsigned long v;
|
||||
|
||||
irq_complete_move(cfg);
|
||||
#ifdef CONFIG_GENERIC_PENDING_IRQ
|
||||
/* If we are moving the irq we need to mask it */
|
||||
if (unlikely(desc->status & IRQ_MOVE_PENDING)) {
|
||||
if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
|
||||
do_unmask_irq = 1;
|
||||
mask_ioapic(cfg);
|
||||
}
|
||||
|
@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
|
|||
msg.data |= MSI_DATA_VECTOR(cfg->vector);
|
||||
msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
|
||||
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
|
||||
msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest);
|
||||
|
||||
dmar_msi_write(irq, &msg);
|
||||
|
||||
|
|
|
@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void)
|
|||
/* need to update phys_pkg_id */
|
||||
apic->phys_pkg_id = apicid_phys_pkg_id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that apic routing model is selected, configure the
|
||||
* fault handling for intr remapping.
|
||||
*/
|
||||
if (intr_remapping_enabled)
|
||||
enable_drhd_fault_handling();
|
||||
}
|
||||
|
||||
/* Same for both flat and physical. */
|
||||
|
|
|
@ -60,16 +60,18 @@
|
|||
#define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD)
|
||||
#endif
|
||||
|
||||
/* Number of possible pages in the lowmem region */
|
||||
LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT)
|
||||
|
||||
/* Enough space to fit pagetables for the low memory linear map */
|
||||
MAPPING_BEYOND_END = \
|
||||
PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT
|
||||
MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT
|
||||
|
||||
/*
|
||||
* Worst-case size of the kernel mapping we need to make:
|
||||
* the worst-case size of the kernel itself, plus the extra we need
|
||||
* to map for the linear map.
|
||||
* a relocatable kernel can live anywhere in lowmem, so we need to be able
|
||||
* to map all of lowmem.
|
||||
*/
|
||||
KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT
|
||||
KERNEL_PAGES = LOWMEM_PAGES
|
||||
|
||||
INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm
|
||||
RESERVE_BRK(pagetables, INIT_MAP_SIZE)
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
#define HPET_DEV_FSB_CAP 0x1000
|
||||
#define HPET_DEV_PERI_CAP 0x2000
|
||||
|
||||
#define HPET_MIN_CYCLES 128
|
||||
#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1))
|
||||
|
||||
#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
|
||||
|
||||
/*
|
||||
|
@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void)
|
|||
/* Calculate the min / max delta */
|
||||
hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
|
||||
&hpet_clockevent);
|
||||
/* 5 usec minimum reprogramming delta. */
|
||||
hpet_clockevent.min_delta_ns = 5000;
|
||||
/* Setup minimum reprogramming delta. */
|
||||
hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
|
||||
&hpet_clockevent);
|
||||
|
||||
/*
|
||||
* Start hpet with the boot cpu mask and make it
|
||||
|
@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta,
|
|||
* the wraparound into account) nor a simple count down event
|
||||
* mode. Further the write to the comparator register is
|
||||
* delayed internally up to two HPET clock cycles in certain
|
||||
* chipsets (ATI, ICH9,10). We worked around that by reading
|
||||
* back the compare register, but that required another
|
||||
* workaround for ICH9,10 chips where the first readout after
|
||||
* write can return the old stale value. We already have a
|
||||
* minimum delta of 5us enforced, but a NMI or SMI hitting
|
||||
* chipsets (ATI, ICH9,10). Some newer AMD chipsets have even
|
||||
* longer delays. We worked around that by reading back the
|
||||
* compare register, but that required another workaround for
|
||||
* ICH9,10 chips where the first readout after write can
|
||||
* return the old stale value. We already had a minimum
|
||||
* programming delta of 5us enforced, but a NMI or SMI hitting
|
||||
* between the counter readout and the comparator write can
|
||||
* move us behind that point easily. Now instead of reading
|
||||
* the compare register back several times, we make the ETIME
|
||||
* decision based on the following: Return ETIME if the
|
||||
* counter value after the write is less than 8 HPET cycles
|
||||
* counter value after the write is less than HPET_MIN_CYCLES
|
||||
* away from the event or if the counter is already ahead of
|
||||
* the event.
|
||||
* the event. The minimum programming delta for the generic
|
||||
* clockevents code is set to 1.5 * HPET_MIN_CYCLES.
|
||||
*/
|
||||
res = (s32)(cnt - hpet_readl(HPET_COUNTER));
|
||||
|
||||
return res < 8 ? -ETIME : 0;
|
||||
return res < HPET_MIN_CYCLES ? -ETIME : 0;
|
||||
}
|
||||
|
||||
static void hpet_legacy_set_mode(enum clock_event_mode mode,
|
||||
|
|
|
@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
|
||||
/* For performance reasons, reuse mc area when possible */
|
||||
if (!mc || mc_size > curr_mc_size) {
|
||||
if (mc)
|
||||
vfree(mc);
|
||||
vfree(mc);
|
||||
mc = vmalloc(mc_size);
|
||||
if (!mc)
|
||||
break;
|
||||
|
@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
|
||||
if (get_ucode_data(mc, ucode_ptr, mc_size) ||
|
||||
microcode_sanity_check(mc) < 0) {
|
||||
vfree(mc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
|
||||
if (new_mc)
|
||||
vfree(new_mc);
|
||||
vfree(new_mc);
|
||||
new_rev = mc_header.rev;
|
||||
new_mc = mc;
|
||||
mc = NULL; /* trigger new vmalloc */
|
||||
|
@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
leftover -= mc_size;
|
||||
}
|
||||
|
||||
if (mc)
|
||||
vfree(mc);
|
||||
vfree(mc);
|
||||
|
||||
if (leftover) {
|
||||
if (new_mc)
|
||||
vfree(new_mc);
|
||||
vfree(new_mc);
|
||||
state = UCODE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (uci->mc)
|
||||
vfree(uci->mc);
|
||||
vfree(uci->mc);
|
||||
uci->mc = (struct microcode_intel *)new_mc;
|
||||
|
||||
pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n",
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#include <linux/ioport.h>
|
||||
#include <asm/e820.h>
|
||||
|
||||
static void resource_clip(struct resource *res, resource_size_t start,
|
||||
resource_size_t end)
|
||||
{
|
||||
resource_size_t low = 0, high = 0;
|
||||
|
||||
if (res->end < start || res->start > end)
|
||||
return; /* no conflict */
|
||||
|
||||
if (res->start < start)
|
||||
low = start - res->start;
|
||||
|
||||
if (res->end > end)
|
||||
high = res->end - end;
|
||||
|
||||
/* Keep the area above or below the conflict, whichever is larger */
|
||||
if (low > high)
|
||||
res->end = start - 1;
|
||||
else
|
||||
res->start = end + 1;
|
||||
}
|
||||
|
||||
static void remove_e820_regions(struct resource *avail)
|
||||
{
|
||||
int i;
|
||||
struct e820entry *entry;
|
||||
|
||||
for (i = 0; i < e820.nr_map; i++) {
|
||||
entry = &e820.map[i];
|
||||
|
||||
resource_clip(avail, entry->addr,
|
||||
entry->addr + entry->size - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void arch_remove_reservations(struct resource *avail)
|
||||
{
|
||||
/* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */
|
||||
if (avail->flags & IORESOURCE_MEM) {
|
||||
if (avail->start < BIOS_END)
|
||||
avail->start = BIOS_END;
|
||||
resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
|
||||
|
||||
remove_e820_regions(avail);
|
||||
}
|
||||
}
|
|
@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void)
|
|||
return total << PAGE_SHIFT;
|
||||
}
|
||||
|
||||
#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF
|
||||
/*
|
||||
* Keep the crash kernel below this limit. On 32 bits earlier kernels
|
||||
* would limit the kernel to the low 512 MiB due to mapping restrictions.
|
||||
* On 64 bits, kexec-tools currently limits us to 896 MiB; increase this
|
||||
* limit once kexec-tools are fixed.
|
||||
*/
|
||||
#ifdef CONFIG_X86_32
|
||||
# define CRASH_KERNEL_ADDR_MAX (512 << 20)
|
||||
#else
|
||||
# define CRASH_KERNEL_ADDR_MAX (896 << 20)
|
||||
#endif
|
||||
|
||||
static void __init reserve_crashkernel(void)
|
||||
{
|
||||
unsigned long long total_mem;
|
||||
|
@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void)
|
|||
const unsigned long long alignment = 16<<20; /* 16M */
|
||||
|
||||
/*
|
||||
* kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX
|
||||
* kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
|
||||
*/
|
||||
crash_base = memblock_find_in_range(alignment,
|
||||
DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment);
|
||||
CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
|
||||
|
||||
if (crash_base == MEMBLOCK_ERROR) {
|
||||
pr_info("crashkernel reservation failed - No suitable area found.\n");
|
||||
|
@ -769,7 +780,6 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
x86_init.oem.arch_setup();
|
||||
|
||||
resource_alloc_from_bottom = 0;
|
||||
iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1;
|
||||
setup_memory_map();
|
||||
parse_setup_data();
|
||||
|
|
|
@ -394,7 +394,8 @@ static void __init setup_xstate_init(void)
|
|||
* Setup init_xstate_buf to represent the init state of
|
||||
* all the features managed by the xsave
|
||||
*/
|
||||
init_xstate_buf = alloc_bootmem(xstate_size);
|
||||
init_xstate_buf = alloc_bootmem_align(xstate_size,
|
||||
__alignof__(struct xsave_struct));
|
||||
init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT;
|
||||
|
||||
clts();
|
||||
|
|
|
@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res,
|
|||
resource_size_t size, resource_size_t align)
|
||||
{
|
||||
struct pci_dev *dev = data;
|
||||
resource_size_t start = round_down(res->end - size + 1, align);
|
||||
resource_size_t start = res->start;
|
||||
|
||||
if (res->flags & IORESOURCE_IO) {
|
||||
|
||||
/*
|
||||
* If we're avoiding ISA aliases, the largest contiguous I/O
|
||||
* port space is 256 bytes. Clearing bits 9 and 10 preserves
|
||||
* all 256-byte and smaller alignments, so the result will
|
||||
* still be correctly aligned.
|
||||
*/
|
||||
if (!skip_isa_ioresource_align(dev))
|
||||
start &= ~0x300;
|
||||
} else if (res->flags & IORESOURCE_MEM) {
|
||||
if (start < BIOS_END)
|
||||
start = res->end; /* fail; no space */
|
||||
if (skip_isa_ioresource_align(dev))
|
||||
return start;
|
||||
if (start & 0x300)
|
||||
start = (start + 0x3ff) & ~0x3ff;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y)
|
|||
|
||||
export CPPFLAGS_vdso.lds += -P -C
|
||||
|
||||
VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \
|
||||
VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \
|
||||
-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
|
||||
|
||||
$(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
|
||||
|
@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter
|
|||
vdso32-images = $(vdso32.so-y:%=vdso32-%.so)
|
||||
|
||||
CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds)
|
||||
VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1
|
||||
VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1
|
||||
|
||||
# This makes sure the $(obj) subdirectory exists even though vdso32/
|
||||
# is not a kbuild sub-make subdirectory.
|
||||
|
|
|
@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
|||
for (i = 0; i < iov_count; i++) {
|
||||
unsigned long uaddr = (unsigned long)iov[i].iov_base;
|
||||
|
||||
if (!iov[i].iov_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (uaddr & queue_dma_alignment(q)) {
|
||||
unaligned = 1;
|
||||
break;
|
||||
}
|
||||
if (!iov[i].iov_len)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unaligned || (q->dma_pad_mask & len) || map_data)
|
||||
|
|
|
@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
|
|||
return 0;
|
||||
|
||||
fbio = bio;
|
||||
cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
|
||||
cluster = blk_queue_cluster(q);
|
||||
seg_size = 0;
|
||||
nr_phys_segs = 0;
|
||||
for_each_bio(bio) {
|
||||
|
@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments);
|
|||
static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
|
||||
struct bio *nxt)
|
||||
{
|
||||
if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
|
||||
if (!blk_queue_cluster(q))
|
||||
return 0;
|
||||
|
||||
if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
|
||||
|
@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
|
|||
int nsegs, cluster;
|
||||
|
||||
nsegs = 0;
|
||||
cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
|
||||
cluster = blk_queue_cluster(q);
|
||||
|
||||
/*
|
||||
* for each bio in rq
|
||||
|
|
|
@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim)
|
|||
lim->alignment_offset = 0;
|
||||
lim->io_opt = 0;
|
||||
lim->misaligned = 0;
|
||||
lim->no_cluster = 0;
|
||||
lim->cluster = 1;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_set_default_limits);
|
||||
|
||||
|
@ -229,8 +229,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask)
|
|||
EXPORT_SYMBOL(blk_queue_bounce_limit);
|
||||
|
||||
/**
|
||||
* blk_queue_max_hw_sectors - set max sectors for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request
|
||||
* @limits: the queue limits
|
||||
* @max_hw_sectors: max hardware sectors in the usual 512b unit
|
||||
*
|
||||
* Description:
|
||||
|
@ -244,7 +244,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit);
|
|||
* per-device basis in /sys/block/<device>/queue/max_sectors_kb.
|
||||
* The soft limit can not exceed max_hw_sectors.
|
||||
**/
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
|
||||
void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors)
|
||||
{
|
||||
if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) {
|
||||
max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
|
||||
|
@ -252,9 +252,23 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto
|
|||
__func__, max_hw_sectors);
|
||||
}
|
||||
|
||||
q->limits.max_hw_sectors = max_hw_sectors;
|
||||
q->limits.max_sectors = min_t(unsigned int, max_hw_sectors,
|
||||
BLK_DEF_MAX_SECTORS);
|
||||
limits->max_hw_sectors = max_hw_sectors;
|
||||
limits->max_sectors = min_t(unsigned int, max_hw_sectors,
|
||||
BLK_DEF_MAX_SECTORS);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_limits_max_hw_sectors);
|
||||
|
||||
/**
|
||||
* blk_queue_max_hw_sectors - set max sectors for a request for this queue
|
||||
* @q: the request queue for the device
|
||||
* @max_hw_sectors: max hardware sectors in the usual 512b unit
|
||||
*
|
||||
* Description:
|
||||
* See description for blk_limits_max_hw_sectors().
|
||||
**/
|
||||
void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors)
|
||||
{
|
||||
blk_limits_max_hw_sectors(&q->limits, max_hw_sectors);
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_max_hw_sectors);
|
||||
|
||||
|
@ -464,15 +478,6 @@ EXPORT_SYMBOL(blk_queue_io_opt);
|
|||
void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
|
||||
{
|
||||
blk_stack_limits(&t->limits, &b->limits, 0);
|
||||
|
||||
if (!t->queue_lock)
|
||||
WARN_ON_ONCE(1);
|
||||
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(t->queue_lock, flags);
|
||||
queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
|
||||
spin_unlock_irqrestore(t->queue_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(blk_queue_stack_limits);
|
||||
|
||||
|
@ -545,7 +550,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
|
|||
t->io_min = max(t->io_min, b->io_min);
|
||||
t->io_opt = lcm(t->io_opt, b->io_opt);
|
||||
|
||||
t->no_cluster |= b->no_cluster;
|
||||
t->cluster &= b->cluster;
|
||||
t->discard_zeroes_data &= b->discard_zeroes_data;
|
||||
|
||||
/* Physical block size a multiple of the logical block size? */
|
||||
|
@ -641,7 +646,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
|||
sector_t offset)
|
||||
{
|
||||
struct request_queue *t = disk->queue;
|
||||
struct request_queue *b = bdev_get_queue(bdev);
|
||||
|
||||
if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
|
||||
char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
|
||||
|
@ -652,17 +656,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
|
|||
printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
|
||||
top, bottom);
|
||||
}
|
||||
|
||||
if (!t->queue_lock)
|
||||
WARN_ON_ONCE(1);
|
||||
else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(t->queue_lock, flags);
|
||||
if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
|
||||
queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
|
||||
spin_unlock_irqrestore(t->queue_lock, flags);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(disk_stack_limits);
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *
|
|||
|
||||
static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
|
||||
{
|
||||
if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
|
||||
if (blk_queue_cluster(q))
|
||||
return queue_var_show(queue_max_segment_size(q), (page));
|
||||
|
||||
return queue_var_show(PAGE_CACHE_SIZE, (page));
|
||||
|
|
|
@ -355,6 +355,12 @@ throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
|
|||
tg->slice_end[rw], jiffies);
|
||||
}
|
||||
|
||||
static inline void throtl_set_slice_end(struct throtl_data *td,
|
||||
struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
|
||||
{
|
||||
tg->slice_end[rw] = roundup(jiffy_end, throtl_slice);
|
||||
}
|
||||
|
||||
static inline void throtl_extend_slice(struct throtl_data *td,
|
||||
struct throtl_grp *tg, bool rw, unsigned long jiffy_end)
|
||||
{
|
||||
|
@ -391,6 +397,16 @@ throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw)
|
|||
if (throtl_slice_used(td, tg, rw))
|
||||
return;
|
||||
|
||||
/*
|
||||
* A bio has been dispatched. Also adjust slice_end. It might happen
|
||||
* that initially cgroup limit was very low resulting in high
|
||||
* slice_end, but later limit was bumped up and bio was dispached
|
||||
* sooner, then we need to reduce slice_end. A high bogus slice_end
|
||||
* is bad because it does not allow new slice to start.
|
||||
*/
|
||||
|
||||
throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice);
|
||||
|
||||
time_elapsed = jiffies - tg->slice_start[rw];
|
||||
|
||||
nr_slices = time_elapsed / throtl_slice;
|
||||
|
@ -709,26 +725,21 @@ static void throtl_process_limit_change(struct throtl_data *td)
|
|||
struct throtl_grp *tg;
|
||||
struct hlist_node *pos, *n;
|
||||
|
||||
/*
|
||||
* Make sure atomic_inc() effects from
|
||||
* throtl_update_blkio_group_read_bps(), group of functions are
|
||||
* visible.
|
||||
* Is this required or smp_mb__after_atomic_inc() was suffcient
|
||||
* after the atomic_inc().
|
||||
*/
|
||||
smp_rmb();
|
||||
if (!atomic_read(&td->limits_changed))
|
||||
return;
|
||||
|
||||
throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed));
|
||||
|
||||
hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
|
||||
/*
|
||||
* Do I need an smp_rmb() here to make sure tg->limits_changed
|
||||
* update is visible. I am relying on smp_rmb() at the
|
||||
* beginning of function and not putting a new one here.
|
||||
*/
|
||||
/*
|
||||
* Make sure updates from throtl_update_blkio_group_read_bps() group
|
||||
* of functions to tg->limits_changed are visible. We do not
|
||||
* want update td->limits_changed to be visible but update to
|
||||
* tg->limits_changed not being visible yet on this cpu. Hence
|
||||
* the read barrier.
|
||||
*/
|
||||
smp_rmb();
|
||||
|
||||
hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) {
|
||||
if (throtl_tg_on_rr(tg) && tg->limits_changed) {
|
||||
throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu"
|
||||
" riops=%u wiops=%u", tg->bps[READ],
|
||||
|
|
|
@ -408,6 +408,9 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
|||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/* Disable the GPE in case it's been enabled already. */
|
||||
(void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
|
||||
|
||||
/*
|
||||
* Add the GPE information from above to the gpe_event_info block for
|
||||
* use during dispatch of this GPE.
|
||||
|
|
|
@ -130,8 +130,6 @@ struct acpi_battery {
|
|||
unsigned long flags;
|
||||
};
|
||||
|
||||
static int acpi_battery_update(struct acpi_battery *battery);
|
||||
|
||||
#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
|
||||
|
||||
inline int acpi_battery_present(struct acpi_battery *battery)
|
||||
|
@ -186,9 +184,6 @@ static int acpi_battery_get_property(struct power_supply *psy,
|
|||
int ret = 0;
|
||||
struct acpi_battery *battery = to_acpi_battery(psy);
|
||||
|
||||
if (acpi_battery_update(battery))
|
||||
return -ENODEV;
|
||||
|
||||
if (acpi_battery_present(battery)) {
|
||||
/* run battery update only if it is present */
|
||||
acpi_battery_get_state(battery);
|
||||
|
|
|
@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
|
|||
}
|
||||
|
||||
static acpi_status
|
||||
acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device,
|
||||
union acpi_object *package)
|
||||
acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
|
||||
struct acpi_device_wakeup *wakeup)
|
||||
{
|
||||
int i = 0;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *package = NULL;
|
||||
union acpi_object *element = NULL;
|
||||
acpi_status status;
|
||||
int i = 0;
|
||||
|
||||
if (!device || !package || (package->package.count < 2))
|
||||
if (!wakeup)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
/* _PRW */
|
||||
status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
|
||||
return status;
|
||||
}
|
||||
|
||||
package = (union acpi_object *)buffer.pointer;
|
||||
|
||||
if (!package || (package->package.count < 2)) {
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
element = &(package->package.elements[0]);
|
||||
if (!element)
|
||||
return AE_BAD_PARAMETER;
|
||||
if (!element) {
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
if (element->type == ACPI_TYPE_PACKAGE) {
|
||||
if ((element->package.count < 2) ||
|
||||
(element->package.elements[0].type !=
|
||||
ACPI_TYPE_LOCAL_REFERENCE)
|
||||
|| (element->package.elements[1].type != ACPI_TYPE_INTEGER))
|
||||
return AE_BAD_DATA;
|
||||
device->wakeup.gpe_device =
|
||||
|| (element->package.elements[1].type != ACPI_TYPE_INTEGER)) {
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
wakeup->gpe_device =
|
||||
element->package.elements[0].reference.handle;
|
||||
device->wakeup.gpe_number =
|
||||
wakeup->gpe_number =
|
||||
(u32) element->package.elements[1].integer.value;
|
||||
} else if (element->type == ACPI_TYPE_INTEGER) {
|
||||
device->wakeup.gpe_number = element->integer.value;
|
||||
} else
|
||||
return AE_BAD_DATA;
|
||||
wakeup->gpe_device = NULL;
|
||||
wakeup->gpe_number = element->integer.value;
|
||||
} else {
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
element = &(package->package.elements[1]);
|
||||
if (element->type != ACPI_TYPE_INTEGER) {
|
||||
return AE_BAD_DATA;
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
device->wakeup.sleep_state = element->integer.value;
|
||||
wakeup->sleep_state = element->integer.value;
|
||||
|
||||
if ((package->package.count - 2) > ACPI_MAX_HANDLES) {
|
||||
return AE_NO_MEMORY;
|
||||
status = AE_NO_MEMORY;
|
||||
goto out;
|
||||
}
|
||||
device->wakeup.resources.count = package->package.count - 2;
|
||||
for (i = 0; i < device->wakeup.resources.count; i++) {
|
||||
wakeup->resources.count = package->package.count - 2;
|
||||
for (i = 0; i < wakeup->resources.count; i++) {
|
||||
element = &(package->package.elements[i + 2]);
|
||||
if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
|
||||
return AE_BAD_DATA;
|
||||
if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
|
||||
status = AE_BAD_DATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
device->wakeup.resources.handles[i] = element->reference.handle;
|
||||
wakeup->resources.handles[i] = element->reference.handle;
|
||||
}
|
||||
|
||||
acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number);
|
||||
acpi_gpe_can_wake(wakeup->gpe_device, wakeup->gpe_number);
|
||||
|
||||
return AE_OK;
|
||||
out:
|
||||
kfree(buffer.pointer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
|
||||
|
@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
|
|||
static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
|
||||
{
|
||||
acpi_status status = 0;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *package = NULL;
|
||||
int psw_error;
|
||||
|
||||
/* _PRW */
|
||||
status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW"));
|
||||
goto end;
|
||||
}
|
||||
|
||||
package = (union acpi_object *)buffer.pointer;
|
||||
status = acpi_bus_extract_wakeup_device_power_package(device, package);
|
||||
status = acpi_bus_extract_wakeup_device_power_package(device->handle,
|
||||
&device->wakeup);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package"));
|
||||
goto end;
|
||||
}
|
||||
|
||||
kfree(buffer.pointer);
|
||||
|
||||
device->wakeup.flags.valid = 1;
|
||||
device->wakeup.prepare_count = 0;
|
||||
acpi_bus_set_run_wake_flags(device);
|
||||
|
@ -1351,6 +1371,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
|
|||
struct acpi_bus_ops *ops = context;
|
||||
int type;
|
||||
unsigned long long sta;
|
||||
struct acpi_device_wakeup wakeup;
|
||||
struct acpi_device *device;
|
||||
acpi_status status;
|
||||
int result;
|
||||
|
@ -1360,8 +1381,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
|
|||
return AE_OK;
|
||||
|
||||
if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
|
||||
!(sta & ACPI_STA_DEVICE_FUNCTIONING))
|
||||
!(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
|
||||
acpi_bus_extract_wakeup_device_power_package(handle, &wakeup);
|
||||
return AE_CTRL_DEPTH;
|
||||
}
|
||||
|
||||
/*
|
||||
* We may already have an acpi_device from a previous enumeration. If
|
||||
|
|
|
@ -128,16 +128,6 @@ config PDC_ADMA
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_MPC52xx
|
||||
tristate "Freescale MPC52xx SoC internal IDE"
|
||||
depends on PPC_MPC52xx && PPC_BESTCOMM
|
||||
select PPC_BESTCOMM_ATA
|
||||
help
|
||||
This option enables support for integrated IDE controller
|
||||
of the Freescale MPC52xx SoC.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_OCTEON_CF
|
||||
tristate "OCTEON Boot Bus Compact Flash support"
|
||||
depends on CPU_CAVIUM_OCTEON
|
||||
|
@ -366,7 +356,7 @@ config PATA_CS5535
|
|||
|
||||
config PATA_CS5536
|
||||
tristate "CS5536 PATA support"
|
||||
depends on PCI && X86 && !X86_64
|
||||
depends on PCI
|
||||
help
|
||||
This option enables support for the AMD CS5536
|
||||
companion chip used with the Geode LX processor family.
|
||||
|
@ -491,6 +481,16 @@ config PATA_MARVELL
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_MPC52xx
|
||||
tristate "Freescale MPC52xx SoC internal IDE"
|
||||
depends on PPC_MPC52xx && PPC_BESTCOMM
|
||||
select PPC_BESTCOMM_ATA
|
||||
help
|
||||
This option enables support for integrated IDE controller
|
||||
of the Freescale MPC52xx SoC.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PATA_NETCELL
|
||||
tristate "NETCELL Revolution RAID support"
|
||||
depends on PCI
|
||||
|
|
|
@ -11,7 +11,6 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
|
|||
|
||||
# SFF w/ custom DMA
|
||||
obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
|
||||
obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
|
||||
obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o
|
||||
obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o
|
||||
obj-$(CONFIG_SATA_SX4) += sata_sx4.o
|
||||
|
@ -52,6 +51,7 @@ obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
|
|||
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
|
||||
obj-$(CONFIG_PATA_MACIO) += pata_macio.o
|
||||
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
|
||||
obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
|
||||
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
|
||||
obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o
|
||||
obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o
|
||||
|
|
|
@ -4807,9 +4807,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
|
|||
{
|
||||
struct ata_device *dev = qc->dev;
|
||||
|
||||
if (ata_tag_internal(qc->tag))
|
||||
return;
|
||||
|
||||
if (ata_is_nodata(qc->tf.protocol))
|
||||
return;
|
||||
|
||||
|
@ -4858,14 +4855,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
|||
if (unlikely(qc->err_mask))
|
||||
qc->flags |= ATA_QCFLAG_FAILED;
|
||||
|
||||
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
|
||||
/* always fill result TF for failed qc */
|
||||
/*
|
||||
* Finish internal commands without any further processing
|
||||
* and always with the result TF filled.
|
||||
*/
|
||||
if (unlikely(ata_tag_internal(qc->tag))) {
|
||||
fill_result_tf(qc);
|
||||
__ata_qc_complete(qc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ata_tag_internal(qc->tag))
|
||||
ata_qc_schedule_eh(qc);
|
||||
else
|
||||
__ata_qc_complete(qc);
|
||||
/*
|
||||
* Non-internal qc has failed. Fill the result TF and
|
||||
* summon EH.
|
||||
*/
|
||||
if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
|
||||
fill_result_tf(qc);
|
||||
ata_qc_schedule_eh(qc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -3275,6 +3275,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;
|
||||
struct ata_eh_context *ehc = &link->eh_context;
|
||||
struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL;
|
||||
enum ata_lpm_policy old_policy = link->lpm_policy;
|
||||
unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;
|
||||
unsigned int err_mask;
|
||||
int rc;
|
||||
|
@ -3338,6 +3339,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Low level driver acked the transition. Issue DIPM command
|
||||
* with the new policy set.
|
||||
*/
|
||||
link->lpm_policy = policy;
|
||||
if (ap && ap->slave_link)
|
||||
ap->slave_link->lpm_policy = policy;
|
||||
|
||||
/* host config updated, enable DIPM if transitioning to MIN_POWER */
|
||||
ata_for_each_dev(dev, link, ENABLED) {
|
||||
if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) {
|
||||
|
@ -3353,12 +3362,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
|
|||
}
|
||||
}
|
||||
|
||||
link->lpm_policy = policy;
|
||||
if (ap && ap->slave_link)
|
||||
ap->slave_link->lpm_policy = policy;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
/* restore the old policy */
|
||||
link->lpm_policy = old_policy;
|
||||
if (ap && ap->slave_link)
|
||||
ap->slave_link->lpm_policy = old_policy;
|
||||
|
||||
/* if no device or only one more chance is left, disable LPM */
|
||||
if (!dev || ehc->tries[dev->devno] <= 2) {
|
||||
ata_link_printk(link, KERN_WARNING,
|
||||
|
|
|
@ -1532,11 +1532,10 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap,
|
|||
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
|
||||
return ata_sff_idle_irq(ap);
|
||||
break;
|
||||
case HSM_ST:
|
||||
case HSM_ST_LAST:
|
||||
break;
|
||||
default:
|
||||
case HSM_ST_IDLE:
|
||||
return ata_sff_idle_irq(ap);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* check main status, clearing INTRQ if needed */
|
||||
|
|
|
@ -37,10 +37,22 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/libata.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
#include <asm/msr.h>
|
||||
static int use_msr;
|
||||
module_param_named(msr, use_msr, int, 0644);
|
||||
MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
|
||||
#else
|
||||
#undef rdmsr /* avoid accidental MSR usage on, e.g. x86-64 */
|
||||
#undef wrmsr
|
||||
#define rdmsr(x, y, z) do { } while (0)
|
||||
#define wrmsr(x, y, z) do { } while (0)
|
||||
#define use_msr 0
|
||||
#endif
|
||||
|
||||
#define DRV_NAME "pata_cs5536"
|
||||
#define DRV_VERSION "0.0.7"
|
||||
#define DRV_VERSION "0.0.8"
|
||||
|
||||
enum {
|
||||
CFG = 0,
|
||||
|
@ -75,8 +87,6 @@ enum {
|
|||
IDE_ETC_NODMA = 0x03,
|
||||
};
|
||||
|
||||
static int use_msr;
|
||||
|
||||
static const u32 msr_reg[4] = {
|
||||
MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC,
|
||||
};
|
||||
|
@ -88,7 +98,7 @@ static const u8 pci_reg[4] = {
|
|||
static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
|
||||
{
|
||||
if (unlikely(use_msr)) {
|
||||
u32 dummy;
|
||||
u32 dummy __maybe_unused;
|
||||
|
||||
rdmsr(msr_reg[reg], *val, dummy);
|
||||
return 0;
|
||||
|
@ -294,8 +304,6 @@ MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_DEVICE_TABLE(pci, cs5536);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
module_param_named(msr, use_msr, int, 0644);
|
||||
MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
|
||||
|
||||
module_init(cs5536_init);
|
||||
module_exit(cs5536_exit);
|
||||
|
|
|
@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk)
|
|||
InquiryData_struct *inq_buff = NULL;
|
||||
|
||||
for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
|
||||
if (!h->drv[logvol])
|
||||
continue;
|
||||
if (memcmp(h->drv[logvol]->LunID, drv->LunID,
|
||||
sizeof(drv->LunID)) == 0) {
|
||||
FOUND = 1;
|
||||
|
|
|
@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev)
|
|||
}
|
||||
|
||||
shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header);
|
||||
rv = drbd_recv(mdev, &header->h80.payload, shs);
|
||||
if (unlikely(rv != shs)) {
|
||||
dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) {
|
||||
dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (shs) {
|
||||
rv = drbd_recv(mdev, &header->h80.payload, shs);
|
||||
if (unlikely(rv != shs)) {
|
||||
dev_err(DEV, "short read while reading sub header: rv=%d\n", rv);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs);
|
||||
|
||||
if (unlikely(!rv)) {
|
||||
|
|
|
@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what)
|
|||
}
|
||||
|
||||
/* completion of master bio is outside of spinlock.
|
||||
* If you need it irqsave, do it your self! */
|
||||
* If you need it irqsave, do it your self!
|
||||
* Which means: don't use from bio endio callback. */
|
||||
static inline int req_mod(struct drbd_request *req,
|
||||
enum drbd_req_event what)
|
||||
{
|
||||
|
|
|
@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error)
|
|||
*/
|
||||
void drbd_endio_pri(struct bio *bio, int error)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct drbd_request *req = bio->bi_private;
|
||||
struct drbd_conf *mdev = req->mdev;
|
||||
struct bio_and_error m;
|
||||
enum drbd_req_event what;
|
||||
int uptodate = bio_flagged(bio, BIO_UPTODATE);
|
||||
|
||||
|
@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error)
|
|||
bio_put(req->private_bio);
|
||||
req->private_bio = ERR_PTR(error);
|
||||
|
||||
req_mod(req, what);
|
||||
/* not req_mod(), we need irqsave here! */
|
||||
spin_lock_irqsave(&mdev->req_lock, flags);
|
||||
__req_mod(req, what, &m);
|
||||
spin_unlock_irqrestore(&mdev->req_lock, flags);
|
||||
|
||||
if (m.bio)
|
||||
complete_master_bio(mdev, &m);
|
||||
}
|
||||
|
||||
int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
|
||||
|
|
|
@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty)
|
|||
|
||||
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
|
||||
hu->proto->close(hu);
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
if (hdev) {
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1192,12 +1192,19 @@ static void i9xx_chipset_flush(void)
|
|||
writel(1, intel_private.i9xx_flush_page);
|
||||
}
|
||||
|
||||
static void i965_write_entry(dma_addr_t addr, unsigned int entry,
|
||||
static void i965_write_entry(dma_addr_t addr,
|
||||
unsigned int entry,
|
||||
unsigned int flags)
|
||||
{
|
||||
u32 pte_flags;
|
||||
|
||||
pte_flags = I810_PTE_VALID;
|
||||
if (flags == AGP_USER_CACHED_MEMORY)
|
||||
pte_flags |= I830_PTE_SYSTEM_CACHED;
|
||||
|
||||
/* Shift high bits down */
|
||||
addr |= (addr >> 28) & 0xf0;
|
||||
writel(addr | I810_PTE_VALID, intel_private.gtt + entry);
|
||||
writel(addr | pte_flags, intel_private.gtt + entry);
|
||||
}
|
||||
|
||||
static bool gen6_check_flags(unsigned int flags)
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <linux/ramoops.h>
|
||||
|
||||
#define RAMOOPS_KERNMSG_HDR "===="
|
||||
#define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval))
|
||||
|
||||
#define RECORD_SIZE 4096
|
||||
|
||||
|
@ -65,8 +64,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
|
|||
struct ramoops_context, dump);
|
||||
unsigned long s1_start, s2_start;
|
||||
unsigned long l1_cpy, l2_cpy;
|
||||
int res;
|
||||
char *buf;
|
||||
int res, hdr_size;
|
||||
char *buf, *buf_orig;
|
||||
struct timeval timestamp;
|
||||
|
||||
/* Only dump oopses if dump_oops is set */
|
||||
|
@ -74,6 +73,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
|
|||
return;
|
||||
|
||||
buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE));
|
||||
buf_orig = buf;
|
||||
|
||||
memset(buf, '\0', RECORD_SIZE);
|
||||
res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR);
|
||||
buf += res;
|
||||
|
@ -81,8 +82,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper,
|
|||
res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec);
|
||||
buf += res;
|
||||
|
||||
l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE));
|
||||
l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy);
|
||||
hdr_size = buf - buf_orig;
|
||||
l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size));
|
||||
l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy);
|
||||
|
||||
s2_start = l2 - l2_cpy;
|
||||
s1_start = l1 - l1_cpy;
|
||||
|
|
|
@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p,
|
|||
} while (delay);
|
||||
}
|
||||
|
||||
static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
|
||||
{
|
||||
if (delta > p->max_match_value)
|
||||
dev_warn(&p->pdev->dev, "delta out of range\n");
|
||||
|
||||
p->next_match_value = delta;
|
||||
sh_cmt_clock_event_program_verify(p, 0);
|
||||
}
|
||||
|
||||
static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (delta > p->max_match_value)
|
||||
dev_warn(&p->pdev->dev, "delta out of range\n");
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
p->next_match_value = delta;
|
||||
sh_cmt_clock_event_program_verify(p, 0);
|
||||
__sh_cmt_set_next(p, delta);
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
|
@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag)
|
|||
|
||||
/* setup timeout if no clockevent */
|
||||
if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT)))
|
||||
sh_cmt_set_next(p, p->max_match_value);
|
||||
__sh_cmt_set_next(p, p->max_match_value);
|
||||
out:
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
|
||||
|
@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag)
|
|||
|
||||
/* adjust the timeout to maximum if only clocksource left */
|
||||
if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE))
|
||||
sh_cmt_set_next(p, p->max_match_value);
|
||||
__sh_cmt_set_next(p, p->max_match_value);
|
||||
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
|
|
@ -56,15 +56,26 @@ static struct cs5535_gpio_chip {
|
|||
* registers, see include/linux/cs5535.h.
|
||||
*/
|
||||
|
||||
static void errata_outl(u32 val, unsigned long addr)
|
||||
static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
|
||||
unsigned int reg)
|
||||
{
|
||||
unsigned long addr = chip->base + 0x80 + reg;
|
||||
|
||||
/*
|
||||
* According to the CS5536 errata (#36), after suspend
|
||||
* a write to the high bank GPIO register will clear all
|
||||
* non-selected bits; the recommended workaround is a
|
||||
* read-modify-write operation.
|
||||
*
|
||||
* Don't apply this errata to the edge status GPIOs, as writing
|
||||
* to their lower bits will clear them.
|
||||
*/
|
||||
val |= inl(addr);
|
||||
if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
|
||||
if (val & 0xffff)
|
||||
val |= (inl(addr) & 0xffff); /* ignore the high bits */
|
||||
else
|
||||
val |= (inl(addr) ^ (val >> 16));
|
||||
}
|
||||
outl(val, addr);
|
||||
}
|
||||
|
||||
|
@ -76,7 +87,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
|
|||
outl(1 << offset, chip->base + reg);
|
||||
else
|
||||
/* high bank register */
|
||||
errata_outl(1 << (offset - 16), chip->base + 0x80 + reg);
|
||||
errata_outl(chip, 1 << (offset - 16), reg);
|
||||
}
|
||||
|
||||
void cs5535_gpio_set(unsigned offset, unsigned int reg)
|
||||
|
@ -98,7 +109,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
|
|||
outl(1 << (offset + 16), chip->base + reg);
|
||||
else
|
||||
/* high bank register */
|
||||
errata_outl(1 << offset, chip->base + 0x80 + reg);
|
||||
errata_outl(chip, 1 << offset, reg);
|
||||
}
|
||||
|
||||
void cs5535_gpio_clear(unsigned offset, unsigned int reg)
|
||||
|
|
|
@ -1281,6 +1281,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
|
|||
err = gpio_direction_output(gpio,
|
||||
(flags & GPIOF_INIT_HIGH) ? 1 : 0);
|
||||
|
||||
if (err)
|
||||
gpio_free(gpio);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpio_request_one);
|
||||
|
|
|
@ -135,7 +135,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)
|
|||
struct rdc321x_gpio *rdc321x_gpio_dev;
|
||||
struct rdc321x_gpio_pdata *pdata;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
pdata = platform_get_drvdata(pdev);
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data supplied\n");
|
||||
return -ENODEV;
|
||||
|
|
|
@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)
|
|||
}
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) {
|
||||
if (!drm_helper_encoder_in_use(encoder)) {
|
||||
drm_encoder_disable(encoder);
|
||||
/* disconnector encoder from any connector */
|
||||
encoder->crtc = NULL;
|
||||
|
@ -874,7 +874,10 @@ static void output_poll_execute(struct work_struct *work)
|
|||
continue;
|
||||
|
||||
connector->status = connector->funcs->detect(connector, false);
|
||||
DRM_DEBUG_KMS("connector status updated to %d\n", connector->status);
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
|
||||
connector->base.id,
|
||||
drm_get_connector_name(connector),
|
||||
old_status, connector->status);
|
||||
if (old_status != connector->status)
|
||||
changed = true;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
|
|||
general->ssc_freq ? 66 : 48;
|
||||
else if (IS_GEN5(dev) || IS_GEN6(dev))
|
||||
dev_priv->lvds_ssc_freq =
|
||||
general->ssc_freq ? 100 : 120;
|
||||
general->ssc_freq ? 120 : 100;
|
||||
else
|
||||
dev_priv->lvds_ssc_freq =
|
||||
general->ssc_freq ? 100 : 96;
|
||||
|
|
|
@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
|||
uint16_t address = algo_data->address;
|
||||
uint8_t msg[5];
|
||||
uint8_t reply[2];
|
||||
unsigned retry;
|
||||
int msg_bytes;
|
||||
int reply_bytes;
|
||||
int ret;
|
||||
|
@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
|||
break;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ret = intel_dp_aux_ch(intel_dp,
|
||||
msg, msg_bytes,
|
||||
reply, reply_bytes);
|
||||
for (retry = 0; retry < 5; retry++) {
|
||||
ret = intel_dp_aux_ch(intel_dp,
|
||||
msg, msg_bytes,
|
||||
reply, reply_bytes);
|
||||
if (ret < 0) {
|
||||
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (reply[0] & AUX_NATIVE_REPLY_MASK) {
|
||||
case AUX_NATIVE_REPLY_ACK:
|
||||
/* I2C-over-AUX Reply field is only valid
|
||||
* when paired with AUX ACK.
|
||||
*/
|
||||
break;
|
||||
case AUX_NATIVE_REPLY_NACK:
|
||||
DRM_DEBUG_KMS("aux_ch native nack\n");
|
||||
return -EREMOTEIO;
|
||||
case AUX_NATIVE_REPLY_DEFER:
|
||||
udelay(100);
|
||||
continue;
|
||||
default:
|
||||
DRM_ERROR("aux_ch invalid native reply 0x%02x\n",
|
||||
reply[0]);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
switch (reply[0] & AUX_I2C_REPLY_MASK) {
|
||||
case AUX_I2C_REPLY_ACK:
|
||||
if (mode == MODE_I2C_READ) {
|
||||
|
@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
|
|||
}
|
||||
return reply_bytes - 1;
|
||||
case AUX_I2C_REPLY_NACK:
|
||||
DRM_DEBUG_KMS("aux_ch nack\n");
|
||||
DRM_DEBUG_KMS("aux_i2c nack\n");
|
||||
return -EREMOTEIO;
|
||||
case AUX_I2C_REPLY_DEFER:
|
||||
DRM_DEBUG_KMS("aux_ch defer\n");
|
||||
DRM_DEBUG_KMS("aux_i2c defer\n");
|
||||
udelay(100);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
|
||||
DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_ERROR("too many retries, giving up\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -696,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev,
|
|||
drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
u32 head;
|
||||
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head) {
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
if (ring->space >= n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
trace_i915_ring_wait_begin (dev);
|
||||
end = jiffies + 3 * HZ;
|
||||
do {
|
||||
ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
|
||||
/* If the reported head position has wrapped or hasn't advanced,
|
||||
* fallback to the slow and accurate path.
|
||||
*/
|
||||
head = intel_read_status_page(ring, 4);
|
||||
if (head < ring->actual_head)
|
||||
head = I915_READ_HEAD(ring);
|
||||
ring->actual_head = head;
|
||||
ring->head = head & HEAD_ADDR;
|
||||
ring->space = ring->head - (ring->tail + 8);
|
||||
if (ring->space < 0)
|
||||
ring->space += ring->size;
|
||||
|
|
|
@ -30,8 +30,9 @@ struct intel_ring_buffer {
|
|||
struct drm_device *dev;
|
||||
struct drm_gem_object *gem_object;
|
||||
|
||||
unsigned int head;
|
||||
unsigned int tail;
|
||||
u32 actual_head;
|
||||
u32 head;
|
||||
u32 tail;
|
||||
int space;
|
||||
struct intel_hw_status_page status_page;
|
||||
|
||||
|
|
|
@ -1908,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv,
|
|||
speed = mapping->i2c_speed;
|
||||
}
|
||||
|
||||
sdvo->i2c = &dev_priv->gmbus[pin].adapter;
|
||||
intel_gmbus_set_speed(sdvo->i2c, speed);
|
||||
intel_gmbus_force_bit(sdvo->i2c, true);
|
||||
if (pin < GMBUS_NUM_PORTS) {
|
||||
sdvo->i2c = &dev_priv->gmbus[pin].adapter;
|
||||
intel_gmbus_set_speed(sdvo->i2c, speed);
|
||||
intel_gmbus_force_bit(sdvo->i2c, true);
|
||||
} else
|
||||
sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter;
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -253,7 +253,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode)
|
|||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id);
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (radeon_crtc->enabled)
|
||||
atombios_blank_crtc(crtc, ATOM_ENABLE);
|
||||
if (ASIC_IS_DCE3(rdev))
|
||||
atombios_enable_crtc_memreq(crtc, ATOM_DISABLE);
|
||||
atombios_enable_crtc(crtc, ATOM_DISABLE);
|
||||
|
@ -530,7 +531,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
|||
dp_clock = dig_connector->dp_clock;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* doesn't work properly on some laptops */
|
||||
/* use recommended ref_div for ss */
|
||||
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
|
||||
if (ss_enabled) {
|
||||
|
@ -540,7 +541,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (ASIC_IS_AVIVO(rdev)) {
|
||||
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
|
||||
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
|
||||
|
|
|
@ -748,6 +748,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
|
|||
unsigned i;
|
||||
u32 tmp;
|
||||
|
||||
WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
|
||||
|
||||
WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
|
||||
for (i = 0; i < rdev->usec_timeout; i++) {
|
||||
/* read MC_STATUS */
|
||||
|
@ -1922,7 +1924,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev)
|
|||
static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
||||
{
|
||||
struct evergreen_mc_save save;
|
||||
u32 srbm_reset = 0;
|
||||
u32 grbm_reset = 0;
|
||||
|
||||
dev_info(rdev->dev, "GPU softreset \n");
|
||||
|
@ -1961,16 +1962,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
|||
udelay(50);
|
||||
WREG32(GRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(GRBM_SOFT_RESET);
|
||||
|
||||
/* reset all the system blocks */
|
||||
srbm_reset = SRBM_SOFT_RESET_ALL_MASK;
|
||||
|
||||
dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
|
||||
WREG32(SRBM_SOFT_RESET, srbm_reset);
|
||||
(void)RREG32(SRBM_SOFT_RESET);
|
||||
udelay(50);
|
||||
WREG32(SRBM_SOFT_RESET, 0);
|
||||
(void)RREG32(SRBM_SOFT_RESET);
|
||||
/* Wait a little for things to settle down */
|
||||
udelay(50);
|
||||
dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n",
|
||||
|
@ -1981,10 +1972,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
|
|||
RREG32(GRBM_STATUS_SE1));
|
||||
dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n",
|
||||
RREG32(SRBM_STATUS));
|
||||
/* After reset we need to reinit the asic as GPU often endup in an
|
||||
* incoherent state.
|
||||
*/
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
evergreen_mc_resume(rdev, &save);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2596,6 +2583,11 @@ int evergreen_resume(struct radeon_device *rdev)
|
|||
{
|
||||
int r;
|
||||
|
||||
/* reset the asic, the gfx blocks are often in a bad state
|
||||
* after the driver is unloaded or after a resume
|
||||
*/
|
||||
if (radeon_asic_reset(rdev))
|
||||
dev_warn(rdev->dev, "GPU reset failed !\n");
|
||||
/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
|
||||
* posting will perform necessary task to bring back GPU into good
|
||||
* shape.
|
||||
|
@ -2712,6 +2704,11 @@ int evergreen_init(struct radeon_device *rdev)
|
|||
r = radeon_atombios_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* reset the asic, the gfx blocks are often in a bad state
|
||||
* after the driver is unloaded or after a resume
|
||||
*/
|
||||
if (radeon_asic_reset(rdev))
|
||||
dev_warn(rdev->dev, "GPU reset failed !\n");
|
||||
/* Post card if necessary */
|
||||
if (!evergreen_card_posted(rdev)) {
|
||||
if (!rdev->bios) {
|
||||
|
|
|
@ -174,6 +174,7 @@
|
|||
#define HDP_NONSURFACE_BASE 0x2C04
|
||||
#define HDP_NONSURFACE_INFO 0x2C08
|
||||
#define HDP_NONSURFACE_SIZE 0x2C0C
|
||||
#define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480
|
||||
#define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0
|
||||
#define HDP_TILING_CONFIG 0x2F3C
|
||||
|
||||
|
|
|
@ -1342,13 +1342,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
|
|||
u32 srbm_status;
|
||||
u32 grbm_status;
|
||||
u32 grbm_status2;
|
||||
struct r100_gpu_lockup *lockup;
|
||||
int r;
|
||||
|
||||
if (rdev->family >= CHIP_RV770)
|
||||
lockup = &rdev->config.rv770.lockup;
|
||||
else
|
||||
lockup = &rdev->config.r600.lockup;
|
||||
|
||||
srbm_status = RREG32(R_000E50_SRBM_STATUS);
|
||||
grbm_status = RREG32(R_008010_GRBM_STATUS);
|
||||
grbm_status2 = RREG32(R_008014_GRBM_STATUS2);
|
||||
if (!G_008010_GUI_ACTIVE(grbm_status)) {
|
||||
r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp);
|
||||
r100_gpu_lockup_update(lockup, &rdev->cp);
|
||||
return false;
|
||||
}
|
||||
/* force CP activities */
|
||||
|
@ -1360,7 +1366,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev)
|
|||
radeon_ring_unlock_commit(rdev);
|
||||
}
|
||||
rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
|
||||
return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp);
|
||||
return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp);
|
||||
}
|
||||
|
||||
int r600_asic_reset(struct radeon_device *rdev)
|
||||
|
|
|
@ -315,11 +315,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
|
|||
if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
|
||||
/* the initial DDX does bad things with the CB size occasionally */
|
||||
/* it rounds up height too far for slice tile max but the BO is smaller */
|
||||
tmp = (height - 7) * 8 * bpe;
|
||||
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
|
||||
dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
return -EINVAL;
|
||||
}
|
||||
/* r600c,g also seem to flush at bad times in some apps resulting in
|
||||
* bogus values here. So for linear just allow anything to avoid breaking
|
||||
* broken userspace.
|
||||
*/
|
||||
} else {
|
||||
dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i]));
|
||||
return -EINVAL;
|
||||
|
|
|
@ -910,11 +910,6 @@ int radeon_resume_kms(struct drm_device *dev)
|
|||
radeon_pm_resume(rdev);
|
||||
radeon_restore_bios_scratch_regs(rdev);
|
||||
|
||||
/* turn on display hw */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
|
||||
radeon_fbdev_set_suspend(rdev, 0);
|
||||
release_console_sem();
|
||||
|
||||
|
@ -922,6 +917,10 @@ int radeon_resume_kms(struct drm_device *dev)
|
|||
radeon_hpd_init(rdev);
|
||||
/* blat the mode back in */
|
||||
drm_helper_resume_force_mode(dev);
|
||||
/* turn on display hw */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -232,9 +232,28 @@ static struct drm_driver driver_old = {
|
|||
|
||||
static struct drm_driver kms_driver;
|
||||
|
||||
static void radeon_kick_out_firmware_fb(struct pci_dev *pdev)
|
||||
{
|
||||
struct apertures_struct *ap;
|
||||
bool primary = false;
|
||||
|
||||
ap = alloc_apertures(1);
|
||||
ap->ranges[0].base = pci_resource_start(pdev, 0);
|
||||
ap->ranges[0].size = pci_resource_len(pdev, 0);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
|
||||
#endif
|
||||
remove_conflicting_framebuffers(ap, "radeondrmfb", primary);
|
||||
kfree(ap);
|
||||
}
|
||||
|
||||
static int __devinit
|
||||
radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
/* Get rid of things like offb */
|
||||
radeon_kick_out_firmware_fb(pdev);
|
||||
|
||||
return drm_get_pci_dev(pdev, ent, &kms_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
|
|||
goto out_unref;
|
||||
}
|
||||
info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
|
||||
info->apertures->ranges[0].size = rdev->mc.real_vram_size;
|
||||
info->apertures->ranges[0].size = rdev->mc.aper_size;
|
||||
|
||||
info->fix.mmio_start = 0;
|
||||
info->fix.mmio_len = 0;
|
||||
|
|
|
@ -267,7 +267,7 @@ void led_blink_set(struct led_classdev *led_cdev,
|
|||
unsigned long *delay_off)
|
||||
{
|
||||
if (led_cdev->blink_set &&
|
||||
led_cdev->blink_set(led_cdev, delay_on, delay_off))
|
||||
!led_cdev->blink_set(led_cdev, delay_on, delay_off))
|
||||
return;
|
||||
|
||||
/* blink with 1 Hz as default if nothing specified */
|
||||
|
|
|
@ -517,9 +517,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
|
|||
*/
|
||||
|
||||
if (q->merge_bvec_fn && !ti->type->merge)
|
||||
limits->max_sectors =
|
||||
min_not_zero(limits->max_sectors,
|
||||
(unsigned int) (PAGE_SIZE >> 9));
|
||||
blk_limits_max_hw_sectors(limits,
|
||||
(unsigned int) (PAGE_SIZE >> 9));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_set_device_limits);
|
||||
|
@ -1131,11 +1130,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
|
|||
*/
|
||||
q->limits = *limits;
|
||||
|
||||
if (limits->no_cluster)
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
|
||||
else
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
|
||||
|
||||
if (!dm_table_supports_discards(t))
|
||||
queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
|
||||
else
|
||||
|
|
|
@ -4295,9 +4295,6 @@ static int md_alloc(dev_t dev, char *name)
|
|||
goto abort;
|
||||
mddev->queue->queuedata = mddev;
|
||||
|
||||
/* Can be unlocked because the queue is new: no concurrency */
|
||||
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
|
||||
|
||||
blk_queue_make_request(mddev->queue, md_make_request);
|
||||
|
||||
disk = alloc_disk(1 << shift);
|
||||
|
|
|
@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = {
|
|||
|
||||
{ 0x800f040a, KEY_DELETE },
|
||||
{ 0x800f040b, KEY_ENTER },
|
||||
{ 0x800f040c, KEY_POWER },
|
||||
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
|
||||
{ 0x800f040c, KEY_POWER }, /* PC Power */
|
||||
{ 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
|
||||
{ 0x800f040e, KEY_MUTE },
|
||||
{ 0x800f040f, KEY_INFO },
|
||||
|
||||
|
@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = {
|
|||
{ 0x800f0422, KEY_OK },
|
||||
{ 0x800f0423, KEY_EXIT },
|
||||
{ 0x800f0424, KEY_DVD },
|
||||
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
|
||||
{ 0x800f0426, KEY_EPG }, /* Guide */
|
||||
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
|
||||
{ 0x800f0425, KEY_TUNER }, /* LiveTV */
|
||||
{ 0x800f0426, KEY_EPG }, /* Guide */
|
||||
{ 0x800f0427, KEY_ZOOM }, /* Aspect */
|
||||
|
||||
{ 0x800f043a, KEY_BRIGHTNESSUP },
|
||||
|
||||
{ 0x800f0446, KEY_TV },
|
||||
{ 0x800f0447, KEY_AUDIO }, /* My Music */
|
||||
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
|
||||
{ 0x800f0447, KEY_AUDIO }, /* My Music */
|
||||
{ 0x800f0448, KEY_PVR }, /* RecordedTV */
|
||||
{ 0x800f0449, KEY_CAMERA },
|
||||
{ 0x800f044a, KEY_VIDEO },
|
||||
{ 0x800f044c, KEY_LANGUAGE },
|
||||
{ 0x800f044d, KEY_TITLE },
|
||||
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
|
||||
{ 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */
|
||||
|
||||
{ 0x800f0450, KEY_RADIO },
|
||||
|
||||
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
|
||||
{ 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
|
||||
{ 0x800f045b, KEY_RED },
|
||||
{ 0x800f045c, KEY_GREEN },
|
||||
{ 0x800f045d, KEY_YELLOW },
|
||||
{ 0x800f045e, KEY_BLUE },
|
||||
|
||||
{ 0x800f0465, KEY_POWER2 }, /* TV Power */
|
||||
{ 0x800f046e, KEY_PLAYPAUSE },
|
||||
{ 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
|
||||
{ 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */
|
||||
|
||||
{ 0x800f0480, KEY_BRIGHTNESSDOWN },
|
||||
{ 0x800f0481, KEY_PLAYPAUSE },
|
||||
|
|
|
@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
|
|||
|
||||
dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
|
||||
|
||||
if (!ir->attached) {
|
||||
mutex_unlock(&ir->irctl_lock);
|
||||
if (!ir->attached)
|
||||
return POLLERR;
|
||||
}
|
||||
|
||||
poll_wait(file, &ir->buf->wait_poll, wait);
|
||||
|
||||
|
@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file,
|
|||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mutex_lock_interruptible(&ir->irctl_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (mutex_lock_interruptible(&ir->irctl_lock)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto out_unlocked;
|
||||
}
|
||||
if (!ir->attached) {
|
||||
mutex_unlock(&ir->irctl_lock);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
if (length % ir->chunk_size) {
|
||||
dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
|
||||
ir->d.name, ir->d.minor);
|
||||
mutex_unlock(&ir->irctl_lock);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out_locked;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file,
|
|||
lirc_buffer_read(ir->buf, buf);
|
||||
ret = copy_to_user((void *)buffer+written, buf,
|
||||
ir->buf->chunk_size);
|
||||
written += ir->buf->chunk_size;
|
||||
if (!ret)
|
||||
written += ir->buf->chunk_size;
|
||||
else
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
remove_wait_queue(&ir->buf->wait_poll, &wait);
|
||||
set_current_state(TASK_RUNNING);
|
||||
|
||||
out_locked:
|
||||
mutex_unlock(&ir->irctl_lock);
|
||||
|
||||
out_unlocked:
|
||||
kfree(buf);
|
||||
dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
|
||||
ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
|
||||
ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret);
|
||||
|
||||
return ret ? ret : written;
|
||||
}
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/input.h>
|
||||
#include <media/ir-core.h>
|
||||
#include <media/ir-common.h>
|
||||
|
||||
#define DRIVER_VERSION "1.91"
|
||||
#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
|
||||
|
@ -49,6 +49,7 @@
|
|||
#define USB_BUFLEN 32 /* USB reception buffer length */
|
||||
#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
|
||||
#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
|
||||
#define MS_TO_NS(msec) ((msec) * 1000)
|
||||
|
||||
/* MCE constants */
|
||||
#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
|
||||
|
@ -74,6 +75,7 @@
|
|||
#define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */
|
||||
|
||||
/* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */
|
||||
#define MCE_CMD_SIG_END 0x01 /* End of signal */
|
||||
#define MCE_CMD_PING 0x03 /* Ping device */
|
||||
#define MCE_CMD_UNKNOWN 0x04 /* Unknown */
|
||||
#define MCE_CMD_UNKNOWN2 0x05 /* Unknown */
|
||||
|
@ -91,6 +93,7 @@
|
|||
#define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */
|
||||
#define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */
|
||||
#define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */
|
||||
#define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */
|
||||
#define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */
|
||||
#define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */
|
||||
#define MCE_CMD_UNKNOWN7 0x18 /* Unknown */
|
||||
|
@ -146,14 +149,16 @@ enum mceusb_model_type {
|
|||
MCE_GEN3,
|
||||
MCE_GEN2_TX_INV,
|
||||
POLARIS_EVK,
|
||||
CX_HYBRID_TV,
|
||||
};
|
||||
|
||||
struct mceusb_model {
|
||||
u32 mce_gen1:1;
|
||||
u32 mce_gen2:1;
|
||||
u32 mce_gen3:1;
|
||||
u32 tx_mask_inverted:1;
|
||||
u32 tx_mask_normal:1;
|
||||
u32 is_polaris:1;
|
||||
u32 no_tx:1;
|
||||
|
||||
const char *rc_map; /* Allow specify a per-board map */
|
||||
const char *name; /* per-board name */
|
||||
|
@ -162,18 +167,18 @@ struct mceusb_model {
|
|||
static const struct mceusb_model mceusb_model[] = {
|
||||
[MCE_GEN1] = {
|
||||
.mce_gen1 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
.tx_mask_normal = 1,
|
||||
},
|
||||
[MCE_GEN2] = {
|
||||
.mce_gen2 = 1,
|
||||
},
|
||||
[MCE_GEN2_TX_INV] = {
|
||||
.mce_gen2 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
.tx_mask_normal = 1,
|
||||
},
|
||||
[MCE_GEN3] = {
|
||||
.mce_gen3 = 1,
|
||||
.tx_mask_inverted = 1,
|
||||
.tx_mask_normal = 1,
|
||||
},
|
||||
[POLARIS_EVK] = {
|
||||
.is_polaris = 1,
|
||||
|
@ -183,7 +188,12 @@ static const struct mceusb_model mceusb_model[] = {
|
|||
* to allow testing it
|
||||
*/
|
||||
.rc_map = RC_MAP_RC5_HAUPPAUGE_NEW,
|
||||
.name = "cx231xx MCE IR",
|
||||
.name = "Conexant Hybrid TV (cx231xx) MCE IR",
|
||||
},
|
||||
[CX_HYBRID_TV] = {
|
||||
.is_polaris = 1,
|
||||
.no_tx = 1, /* tx isn't wired up at all */
|
||||
.name = "Conexant Hybrid TV (cx231xx) MCE IR",
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -273,6 +283,8 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
|
||||
/* Formosa Industrial Computing */
|
||||
{ USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
|
||||
/* Fintek eHome Infrared Transceiver (HP branded) */
|
||||
{ USB_DEVICE(VENDOR_FINTEK, 0x5168) },
|
||||
/* Fintek eHome Infrared Transceiver */
|
||||
{ USB_DEVICE(VENDOR_FINTEK, 0x0602) },
|
||||
/* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
|
||||
|
@ -292,9 +304,12 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
|
||||
/* TiVo PC IR Receiver */
|
||||
{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
|
||||
/* Conexant SDK */
|
||||
/* Conexant Hybrid TV "Shelby" Polaris SDK */
|
||||
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
|
||||
.driver_info = POLARIS_EVK },
|
||||
/* Conexant Hybrid TV RDU253S Polaris */
|
||||
{ USB_DEVICE(VENDOR_CONEXANT, 0x58a5),
|
||||
.driver_info = CX_HYBRID_TV },
|
||||
/* Terminating entry */
|
||||
{ }
|
||||
};
|
||||
|
@ -303,7 +318,10 @@ static struct usb_device_id mceusb_dev_table[] = {
|
|||
struct mceusb_dev {
|
||||
/* ir-core bits */
|
||||
struct ir_dev_props *props;
|
||||
struct ir_raw_event rawir;
|
||||
|
||||
/* optional features we can enable */
|
||||
bool carrier_report_enabled;
|
||||
bool learning_enabled;
|
||||
|
||||
/* core device bits */
|
||||
struct device *dev;
|
||||
|
@ -318,6 +336,8 @@ struct mceusb_dev {
|
|||
/* buffers and dma */
|
||||
unsigned char *buf_in;
|
||||
unsigned int len_in;
|
||||
dma_addr_t dma_in;
|
||||
dma_addr_t dma_out;
|
||||
|
||||
enum {
|
||||
CMD_HEADER = 0,
|
||||
|
@ -325,15 +345,14 @@ struct mceusb_dev {
|
|||
CMD_DATA,
|
||||
PARSE_IRDATA,
|
||||
} parser_state;
|
||||
u8 cmd, rem; /* Remaining IR data bytes in packet */
|
||||
|
||||
dma_addr_t dma_in;
|
||||
dma_addr_t dma_out;
|
||||
u8 cmd, rem; /* Remaining IR data bytes in packet */
|
||||
|
||||
struct {
|
||||
u32 connected:1;
|
||||
u32 tx_mask_inverted:1;
|
||||
u32 tx_mask_normal:1;
|
||||
u32 microsoft_gen1:1;
|
||||
u32 no_tx:1;
|
||||
} flags;
|
||||
|
||||
/* transmit support */
|
||||
|
@ -408,9 +427,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd)
|
|||
case MCE_CMD_UNKNOWN:
|
||||
case MCE_CMD_S_CARRIER:
|
||||
case MCE_CMD_S_TIMEOUT:
|
||||
case MCE_CMD_G_RXSENSOR:
|
||||
case MCE_RSP_PULSE_COUNT:
|
||||
datasize = 2;
|
||||
break;
|
||||
case MCE_CMD_SIG_END:
|
||||
case MCE_CMD_S_TXMASK:
|
||||
case MCE_CMD_S_RXSENSOR:
|
||||
datasize = 1;
|
||||
|
@ -433,7 +453,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
|||
return;
|
||||
|
||||
/* skip meaningless 0xb1 0x60 header bytes on orig receiver */
|
||||
if (ir->flags.microsoft_gen1 && !out)
|
||||
if (ir->flags.microsoft_gen1 && !out && !offset)
|
||||
skip = 2;
|
||||
|
||||
if (len <= skip)
|
||||
|
@ -491,6 +511,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
|||
break;
|
||||
case MCE_COMMAND_HEADER:
|
||||
switch (subcmd) {
|
||||
case MCE_CMD_SIG_END:
|
||||
dev_info(dev, "End of signal\n");
|
||||
break;
|
||||
case MCE_CMD_PING:
|
||||
dev_info(dev, "Ping\n");
|
||||
break;
|
||||
|
@ -525,10 +548,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
|||
inout, data1 == 0x02 ? "short" : "long");
|
||||
break;
|
||||
case MCE_CMD_G_RXSENSOR:
|
||||
if (len == 2)
|
||||
/* aka MCE_RSP_PULSE_COUNT */
|
||||
if (out)
|
||||
dev_info(dev, "Get receive sensor\n");
|
||||
else
|
||||
dev_info(dev, "Received pulse count is %d\n",
|
||||
else if (ir->learning_enabled)
|
||||
dev_info(dev, "RX pulse count: %d\n",
|
||||
((data1 << 8) | data2));
|
||||
break;
|
||||
case MCE_RSP_CMD_INVALID:
|
||||
|
@ -724,16 +748,16 @@ out:
|
|||
return ret ? ret : n;
|
||||
}
|
||||
|
||||
/* Sets active IR outputs -- mce devices typically (all?) have two */
|
||||
/* Sets active IR outputs -- mce devices typically have two */
|
||||
static int mceusb_set_tx_mask(void *priv, u32 mask)
|
||||
{
|
||||
struct mceusb_dev *ir = priv;
|
||||
|
||||
if (ir->flags.tx_mask_inverted)
|
||||
if (ir->flags.tx_mask_normal)
|
||||
ir->tx_mask = mask;
|
||||
else
|
||||
ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ?
|
||||
mask ^ MCE_DEFAULT_TX_MASK : mask) << 1;
|
||||
else
|
||||
ir->tx_mask = mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -752,7 +776,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
|
||||
if (carrier == 0) {
|
||||
ir->carrier = carrier;
|
||||
cmdbuf[2] = 0x01;
|
||||
cmdbuf[2] = MCE_CMD_SIG_END;
|
||||
cmdbuf[3] = MCE_IRDATA_TRAILER;
|
||||
dev_dbg(ir->dev, "%s: disabling carrier "
|
||||
"modulation\n", __func__);
|
||||
|
@ -782,6 +806,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier)
|
|||
return carrier;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't do anything but print debug spew for many of the command bits
|
||||
* we receive from the hardware, but some of them are useful information
|
||||
* we want to store so that we can use them.
|
||||
*/
|
||||
static void mceusb_handle_command(struct mceusb_dev *ir, int index)
|
||||
{
|
||||
u8 hi = ir->buf_in[index + 1] & 0xff;
|
||||
u8 lo = ir->buf_in[index + 2] & 0xff;
|
||||
|
||||
switch (ir->buf_in[index]) {
|
||||
/* 2-byte return value commands */
|
||||
case MCE_CMD_S_TIMEOUT:
|
||||
ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2);
|
||||
break;
|
||||
|
||||
/* 1-byte return value commands */
|
||||
case MCE_CMD_S_TXMASK:
|
||||
ir->tx_mask = hi;
|
||||
break;
|
||||
case MCE_CMD_S_RXSENSOR:
|
||||
ir->learning_enabled = (hi == 0x02);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
||||
{
|
||||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
|
@ -791,39 +843,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
|||
if (ir->flags.microsoft_gen1)
|
||||
i = 2;
|
||||
|
||||
/* if there's no data, just return now */
|
||||
if (buf_len <= i)
|
||||
return;
|
||||
|
||||
for (; i < buf_len; i++) {
|
||||
switch (ir->parser_state) {
|
||||
case SUBCMD:
|
||||
ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]);
|
||||
mceusb_dev_printdata(ir, ir->buf_in, i - 1,
|
||||
ir->rem + 2, false);
|
||||
mceusb_handle_command(ir, i);
|
||||
ir->parser_state = CMD_DATA;
|
||||
break;
|
||||
case PARSE_IRDATA:
|
||||
ir->rem--;
|
||||
rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
|
||||
rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
|
||||
* MCE_TIME_UNIT * 1000;
|
||||
|
||||
if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
|
||||
if (ir->rawir.pulse == rawir.pulse) {
|
||||
ir->rawir.duration += rawir.duration;
|
||||
} else {
|
||||
ir->rawir.duration = rawir.duration;
|
||||
ir->rawir.pulse = rawir.pulse;
|
||||
}
|
||||
if (ir->rem)
|
||||
break;
|
||||
}
|
||||
rawir.duration += ir->rawir.duration;
|
||||
ir->rawir.duration = 0;
|
||||
ir->rawir.pulse = rawir.pulse;
|
||||
* MS_TO_NS(MCE_TIME_UNIT);
|
||||
|
||||
dev_dbg(ir->dev, "Storing %s with duration %d\n",
|
||||
rawir.pulse ? "pulse" : "space",
|
||||
rawir.duration);
|
||||
|
||||
ir_raw_event_store(ir->idev, &rawir);
|
||||
ir_raw_event_store_with_filter(ir->idev, &rawir);
|
||||
break;
|
||||
case CMD_DATA:
|
||||
ir->rem--;
|
||||
|
@ -839,17 +882,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
|
|||
continue;
|
||||
}
|
||||
ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK);
|
||||
mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false);
|
||||
if (ir->rem) {
|
||||
mceusb_dev_printdata(ir, ir->buf_in,
|
||||
i, ir->rem + 1, false);
|
||||
if (ir->rem)
|
||||
ir->parser_state = PARSE_IRDATA;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* a package with len=0 (e. g. 0x80) means end of
|
||||
* data. We could use it to do the call to
|
||||
* ir_raw_event_handle(). For now, we don't need to
|
||||
* use it.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -984,9 +1020,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir)
|
|||
mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
|
||||
mce_sync_in(ir, NULL, maxp);
|
||||
|
||||
/* get the transmitter bitmask */
|
||||
mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
|
||||
mce_sync_in(ir, NULL, maxp);
|
||||
if (!ir->flags.no_tx) {
|
||||
/* get the transmitter bitmask */
|
||||
mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
|
||||
mce_sync_in(ir, NULL, maxp);
|
||||
}
|
||||
|
||||
/* get receiver timeout value */
|
||||
mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
|
||||
|
@ -1035,12 +1073,18 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
|
|||
props->priv = ir;
|
||||
props->driver_type = RC_DRIVER_IR_RAW;
|
||||
props->allowed_protos = IR_TYPE_ALL;
|
||||
props->s_tx_mask = mceusb_set_tx_mask;
|
||||
props->s_tx_carrier = mceusb_set_tx_carrier;
|
||||
props->tx_ir = mceusb_tx_ir;
|
||||
props->timeout = MS_TO_NS(1000);
|
||||
if (!ir->flags.no_tx) {
|
||||
props->s_tx_mask = mceusb_set_tx_mask;
|
||||
props->s_tx_carrier = mceusb_set_tx_carrier;
|
||||
props->tx_ir = mceusb_tx_ir;
|
||||
}
|
||||
|
||||
ir->props = props;
|
||||
|
||||
usb_to_input_id(ir->usbdev, &idev->id);
|
||||
idev->dev.parent = ir->dev;
|
||||
|
||||
if (mceusb_model[ir->model].rc_map)
|
||||
rc_map = mceusb_model[ir->model].rc_map;
|
||||
|
||||
|
@ -1074,16 +1118,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
enum mceusb_model_type model = id->driver_info;
|
||||
bool is_gen3;
|
||||
bool is_microsoft_gen1;
|
||||
bool tx_mask_inverted;
|
||||
bool tx_mask_normal;
|
||||
bool is_polaris;
|
||||
|
||||
dev_dbg(&intf->dev, ": %s called\n", __func__);
|
||||
dev_dbg(&intf->dev, "%s called\n", __func__);
|
||||
|
||||
idesc = intf->cur_altsetting;
|
||||
|
||||
is_gen3 = mceusb_model[model].mce_gen3;
|
||||
is_microsoft_gen1 = mceusb_model[model].mce_gen1;
|
||||
tx_mask_inverted = mceusb_model[model].tx_mask_inverted;
|
||||
tx_mask_normal = mceusb_model[model].tx_mask_normal;
|
||||
is_polaris = mceusb_model[model].is_polaris;
|
||||
|
||||
if (is_polaris) {
|
||||
|
@ -1107,7 +1151,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
ep_in = ep;
|
||||
ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
|
||||
ep_in->bInterval = 1;
|
||||
dev_dbg(&intf->dev, ": acceptable inbound endpoint "
|
||||
dev_dbg(&intf->dev, "acceptable inbound endpoint "
|
||||
"found\n");
|
||||
}
|
||||
|
||||
|
@ -1122,12 +1166,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
ep_out = ep;
|
||||
ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
|
||||
ep_out->bInterval = 1;
|
||||
dev_dbg(&intf->dev, ": acceptable outbound endpoint "
|
||||
dev_dbg(&intf->dev, "acceptable outbound endpoint "
|
||||
"found\n");
|
||||
}
|
||||
}
|
||||
if (ep_in == NULL) {
|
||||
dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
|
||||
dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1150,11 +1194,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
ir->dev = &intf->dev;
|
||||
ir->len_in = maxp;
|
||||
ir->flags.microsoft_gen1 = is_microsoft_gen1;
|
||||
ir->flags.tx_mask_inverted = tx_mask_inverted;
|
||||
ir->flags.tx_mask_normal = tx_mask_normal;
|
||||
ir->flags.no_tx = mceusb_model[model].no_tx;
|
||||
ir->model = model;
|
||||
|
||||
init_ir_raw_event(&ir->rawir);
|
||||
|
||||
/* Saving usb interface data for use by the transmitter routine */
|
||||
ir->usb_ep_in = ep_in;
|
||||
ir->usb_ep_out = ep_out;
|
||||
|
@ -1191,7 +1234,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf,
|
|||
|
||||
mceusb_get_parameters(ir);
|
||||
|
||||
mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
|
||||
if (!ir->flags.no_tx)
|
||||
mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
|
||||
|
||||
usb_set_intfdata(intf, ir);
|
||||
|
||||
|
|
|
@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
|||
count = nvt->pkts;
|
||||
nvt_dbg_verbose("Processing buffer of len %d", count);
|
||||
|
||||
init_ir_raw_event(&rawir);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nvt->pkts--;
|
||||
sample = nvt->buf[i];
|
||||
|
@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt)
|
|||
* indicates end of IR signal, but new data incoming. In both
|
||||
* cases, it means we're ready to call ir_raw_event_handle
|
||||
*/
|
||||
if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) &&
|
||||
(sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE))
|
||||
if ((sample == BUF_PULSE_BIT) && nvt->pkts) {
|
||||
nvt_dbg("Calling ir_raw_event_handle (signal end)\n");
|
||||
ir_raw_event_handle(nvt->rdev);
|
||||
}
|
||||
}
|
||||
|
||||
nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n");
|
||||
ir_raw_event_handle(nvt->rdev);
|
||||
|
||||
if (nvt->pkts) {
|
||||
nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts);
|
||||
nvt->pkts = 0;
|
||||
|
|
|
@ -34,8 +34,9 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/input.h>
|
||||
#include <media/ir-core.h>
|
||||
|
||||
#define DRIVER_VERSION "1.61"
|
||||
|
@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = {
|
|||
|
||||
static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
|
||||
{
|
||||
ir_raw_event_store(sz->idev, &rawir);
|
||||
dev_dbg(sz->dev, "Storing %s with duration %u us\n",
|
||||
(rawir.pulse ? "pulse" : "space"), rawir.duration);
|
||||
ir_raw_event_store_with_filter(sz->idev, &rawir);
|
||||
}
|
||||
|
||||
static void sz_push_full_pulse(struct streamzap_ir *sz,
|
||||
|
@ -167,7 +170,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
|
|||
rawir.duration *= 1000;
|
||||
rawir.duration &= IR_MAX_DURATION;
|
||||
}
|
||||
dev_dbg(sz->dev, "ls %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
|
||||
sz->idle = false;
|
||||
|
@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz,
|
|||
sz->sum += rawir.duration;
|
||||
rawir.duration *= 1000;
|
||||
rawir.duration &= IR_MAX_DURATION;
|
||||
dev_dbg(sz->dev, "p %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
}
|
||||
|
||||
|
@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz,
|
|||
rawir.duration += SZ_RESOLUTION / 2;
|
||||
sz->sum += rawir.duration;
|
||||
rawir.duration *= 1000;
|
||||
dev_dbg(sz->dev, "s %u\n", rawir.duration);
|
||||
sz_push(sz, rawir);
|
||||
}
|
||||
|
||||
|
@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb)
|
|||
struct streamzap_ir *sz;
|
||||
unsigned int i;
|
||||
int len;
|
||||
static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
|
||||
IR_MAX_DURATION) | 0x03000000);
|
||||
|
||||
if (!urb)
|
||||
return;
|
||||
|
@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb)
|
|||
|
||||
dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
|
||||
for (i = 0; i < len; i++) {
|
||||
dev_dbg(sz->dev, "sz idx %d: %x\n",
|
||||
dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
|
||||
i, (unsigned char)sz->buf_in[i]);
|
||||
switch (sz->decoder_state) {
|
||||
case PulseSpace:
|
||||
|
@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb)
|
|||
DEFINE_IR_RAW_EVENT(rawir);
|
||||
|
||||
rawir.pulse = false;
|
||||
rawir.duration = timeout;
|
||||
rawir.duration = sz->props->timeout;
|
||||
sz->idle = true;
|
||||
if (sz->timeout_enabled)
|
||||
sz_push(sz, rawir);
|
||||
|
@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
|
|||
|
||||
sz->props = props;
|
||||
|
||||
usb_to_input_id(sz->usbdev, &idev->id);
|
||||
idev->dev.parent = sz->dev;
|
||||
|
||||
ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "remote input device register failed\n");
|
||||
|
@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf,
|
|||
sz->decoder_state = PulseSpace;
|
||||
/* FIXME: don't yet have a way to set this */
|
||||
sz->timeout_enabled = true;
|
||||
sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) &
|
||||
IR_MAX_DURATION) | 0x03000000);
|
||||
#if 0
|
||||
/* not yet supported, depends on patches from maxim */
|
||||
/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
|
||||
|
|
|
@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e
|
|||
static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
|
||||
{
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
|
||||
|
||||
int b_depth = vv->ov_fmt->depth;
|
||||
int b_bpl = vv->ov_fb.fmt.bytesperline;
|
||||
|
@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71
|
|||
struct saa7146_vv *vv = dev->vv_data;
|
||||
struct saa7146_video_dma vdma1;
|
||||
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
int width = buf->fmt->width;
|
||||
int height = buf->fmt->height;
|
||||
|
@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71
|
|||
struct saa7146_video_dma vdma2;
|
||||
struct saa7146_video_dma vdma3;
|
||||
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
int width = buf->fmt->width;
|
||||
int height = buf->fmt->height;
|
||||
|
@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar)
|
|||
|
||||
void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
|
||||
{
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
u32 vdma1_prot_addr;
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ static struct saa7146_format formats[] = {
|
|||
|
||||
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
|
||||
|
||||
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
|
||||
struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
|
||||
{
|
||||
int i, j = NUM_FORMATS;
|
||||
|
||||
|
@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
|
|||
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
|
||||
struct scatterlist *list = dma->sglist;
|
||||
int length = dma->sglen;
|
||||
struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
|
||||
|
||||
|
@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh)
|
|||
}
|
||||
}
|
||||
|
||||
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
|
@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
/* we need to have a valid format set here */
|
||||
BUG_ON(NULL == fmt);
|
||||
|
||||
|
@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
|
|||
return -EPERM;
|
||||
|
||||
/* check args */
|
||||
fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
|
||||
if (NULL == fmt)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
|
|||
|
||||
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
|
||||
|
||||
fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
|
||||
fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
|
||||
if (NULL == fmt)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q,
|
|||
buf->fmt = &fh->video_fmt;
|
||||
buf->vb.field = fh->video_fmt.field;
|
||||
|
||||
sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
|
||||
|
||||
release_all_pagetables(dev, buf);
|
||||
if( 0 != IS_PLANAR(sfmt->trans)) {
|
||||
|
@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
|
|||
fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||
fh->video_fmt.bytesperline = 0;
|
||||
fh->video_fmt.field = V4L2_FIELD_ANY;
|
||||
sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
|
||||
fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
|
||||
|
||||
videobuf_queue_sg_init(&fh->video_q, &video_qops,
|
||||
|
|
|
@ -854,7 +854,6 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
|
|||
xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM;
|
||||
|
||||
/* is it free? */
|
||||
mutex_lock(&btv->lock);
|
||||
if (btv->resources & xbits) {
|
||||
/* no, someone else uses it */
|
||||
goto fail;
|
||||
|
@ -884,11 +883,9 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit)
|
|||
/* it's free, grab it */
|
||||
fh->resources |= bit;
|
||||
btv->resources |= bit;
|
||||
mutex_unlock(&btv->lock);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -940,7 +937,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
|
|||
/* trying to free ressources not allocated by us ... */
|
||||
printk("bttv: BUG! (btres)\n");
|
||||
}
|
||||
mutex_lock(&btv->lock);
|
||||
fh->resources &= ~bits;
|
||||
btv->resources &= ~bits;
|
||||
|
||||
|
@ -951,8 +947,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits)
|
|||
|
||||
if (0 == (bits & VBI_RESOURCES))
|
||||
disclaim_vbi_lines(btv);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
@ -1713,28 +1707,20 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
|
|||
|
||||
/* Make sure tvnorm and vbi_end remain consistent
|
||||
until we're done. */
|
||||
mutex_lock(&btv->lock);
|
||||
|
||||
norm = btv->tvnorm;
|
||||
|
||||
/* In this mode capturing always starts at defrect.top
|
||||
(default VDELAY), ignoring cropping parameters. */
|
||||
if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) {
|
||||
mutex_unlock(&btv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
c.rect = bttv_tvnorms[norm].cropcap.defrect;
|
||||
} else {
|
||||
mutex_lock(&btv->lock);
|
||||
|
||||
norm = btv->tvnorm;
|
||||
c = btv->crop[!!fh->do_crop];
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
if (width < c.min_scaled_width ||
|
||||
width > c.max_scaled_width ||
|
||||
height < c.min_scaled_height)
|
||||
|
@ -1858,7 +1844,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
|
|||
unsigned int i;
|
||||
int err;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
err = v4l2_prio_check(&btv->prio, fh->prio);
|
||||
if (err)
|
||||
goto err;
|
||||
|
@ -1874,7 +1859,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id)
|
|||
set_tvnorm(btv, i);
|
||||
|
||||
err:
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1898,7 +1882,6 @@ static int bttv_enum_input(struct file *file, void *priv,
|
|||
struct bttv *btv = fh->btv;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
if (i->index >= bttv_tvcards[btv->c.type].video_inputs) {
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
|
@ -1928,7 +1911,6 @@ static int bttv_enum_input(struct file *file, void *priv,
|
|||
i->std = BTTV_NORMS;
|
||||
|
||||
err:
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1938,9 +1920,7 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i)
|
|||
struct bttv_fh *fh = priv;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
*i = btv->input;
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1952,7 +1932,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
|
|||
|
||||
int err;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
err = v4l2_prio_check(&btv->prio, fh->prio);
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
@ -1965,7 +1944,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i)
|
|||
set_input(btv, i, btv->tvnorm);
|
||||
|
||||
err:
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1979,7 +1957,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
|
|||
if (unlikely(0 != t->index))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
if (unlikely(btv->tuner_type == TUNER_ABSENT)) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
|
@ -1995,7 +1972,6 @@ static int bttv_s_tuner(struct file *file, void *priv,
|
|||
btv->audio_mode_gpio(btv, t, 1);
|
||||
|
||||
err:
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2006,10 +1982,8 @@ static int bttv_g_frequency(struct file *file, void *priv,
|
|||
struct bttv_fh *fh = priv;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
|
||||
f->frequency = btv->freq;
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2024,7 +1998,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
|
|||
if (unlikely(f->tuner != 0))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
err = v4l2_prio_check(&btv->prio, fh->prio);
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
@ -2039,7 +2012,6 @@ static int bttv_s_frequency(struct file *file, void *priv,
|
|||
if (btv->has_matchbox && btv->radio_user)
|
||||
tea5757_set_freq(btv, btv->freq);
|
||||
err:
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2172,7 +2144,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
|
|||
|
||||
/* Make sure tvnorm, vbi_end and the current cropping parameters
|
||||
remain consistent until we're done. */
|
||||
mutex_lock(&btv->lock);
|
||||
|
||||
b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds;
|
||||
|
||||
|
@ -2250,7 +2221,6 @@ limit_scaled_size_lock (struct bttv_fh * fh,
|
|||
rc = 0; /* success */
|
||||
|
||||
fail:
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -2282,9 +2252,7 @@ verify_window_lock (struct bttv_fh * fh,
|
|||
if (V4L2_FIELD_ANY == field) {
|
||||
__s32 height2;
|
||||
|
||||
mutex_lock(&fh->btv->lock);
|
||||
height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1;
|
||||
mutex_unlock(&fh->btv->lock);
|
||||
field = (win->w.height > height2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_TOP;
|
||||
|
@ -2360,7 +2328,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
|
|||
}
|
||||
}
|
||||
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
/* clip against screen */
|
||||
if (NULL != btv->fbuf.base)
|
||||
n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
|
||||
|
@ -2391,13 +2358,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
|
|||
fh->ov.field = win->field;
|
||||
fh->ov.setup_ok = 1;
|
||||
|
||||
/*
|
||||
* FIXME: btv is protected by btv->lock mutex, while btv->init
|
||||
* is protected by fh->cap.vb_lock. This seems to open the
|
||||
* possibility for some race situations. Maybe the better would
|
||||
* be to unify those locks or to use another way to store the
|
||||
* init values that will be consumed by videobuf callbacks
|
||||
*/
|
||||
btv->init.ov.w.width = win->w.width;
|
||||
btv->init.ov.w.height = win->w.height;
|
||||
btv->init.ov.field = win->field;
|
||||
|
@ -2412,7 +2372,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv,
|
|||
bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
|
||||
retval = bttv_switch_overlay(btv,fh,new);
|
||||
}
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2526,9 +2485,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv,
|
|||
if (V4L2_FIELD_ANY == field) {
|
||||
__s32 height2;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
height2 = btv->crop[!!fh->do_crop].rect.height >> 1;
|
||||
mutex_unlock(&btv->lock);
|
||||
field = (f->fmt.pix.height > height2)
|
||||
? V4L2_FIELD_INTERLACED
|
||||
: V4L2_FIELD_BOTTOM;
|
||||
|
@ -2614,7 +2571,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
|
|||
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
|
||||
|
||||
/* update our state informations */
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
fh->fmt = fmt;
|
||||
fh->cap.field = f->fmt.pix.field;
|
||||
fh->cap.last = V4L2_FIELD_NONE;
|
||||
|
@ -2623,7 +2579,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv,
|
|||
btv->init.fmt = fmt;
|
||||
btv->init.width = f->fmt.pix.width;
|
||||
btv->init.height = f->fmt.pix.height;
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2649,11 +2604,9 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
|
|||
unsigned int i;
|
||||
struct bttv_fh *fh = priv;
|
||||
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize,
|
||||
V4L2_MEMORY_MMAP);
|
||||
if (retval < 0) {
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2665,7 +2618,6 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
|
|||
for (i = 0; i < gbuffers; i++)
|
||||
mbuf->offsets[i] = i * gbufsize;
|
||||
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2775,10 +2727,8 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
|
|||
int retval = 0;
|
||||
|
||||
if (on) {
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
/* verify args */
|
||||
if (unlikely(!btv->fbuf.base)) {
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(!fh->ov.setup_ok)) {
|
||||
|
@ -2787,13 +2737,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
|
|||
}
|
||||
if (retval)
|
||||
return retval;
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
}
|
||||
|
||||
if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY))
|
||||
return -EBUSY;
|
||||
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
if (on) {
|
||||
fh->ov.tvnorm = btv->tvnorm;
|
||||
new = videobuf_sg_alloc(sizeof(*new));
|
||||
|
@ -2805,7 +2753,6 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on)
|
|||
|
||||
/* switch over */
|
||||
retval = bttv_switch_overlay(btv, fh, new);
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2844,7 +2791,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
|
|||
}
|
||||
|
||||
/* ok, accept it */
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
btv->fbuf.base = fb->base;
|
||||
btv->fbuf.fmt.width = fb->fmt.width;
|
||||
btv->fbuf.fmt.height = fb->fmt.height;
|
||||
|
@ -2876,7 +2822,6 @@ static int bttv_s_fbuf(struct file *file, void *f,
|
|||
retval = bttv_switch_overlay(btv, fh, new);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -2955,7 +2900,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
|
|||
c->id >= V4L2_CID_PRIVATE_LASTP1))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME))
|
||||
*c = no_ctl;
|
||||
else {
|
||||
|
@ -2963,7 +2907,6 @@ static int bttv_queryctrl(struct file *file, void *priv,
|
|||
|
||||
*c = (NULL != ctrl) ? *ctrl : no_ctl;
|
||||
}
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2974,10 +2917,8 @@ static int bttv_g_parm(struct file *file, void *f,
|
|||
struct bttv_fh *fh = f;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
|
||||
&parm->parm.capture.timeperframe);
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2993,7 +2934,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
|
|||
if (0 != t->index)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
t->rxsubchans = V4L2_TUNER_SUB_MONO;
|
||||
bttv_call_all(btv, tuner, g_tuner, t);
|
||||
strcpy(t->name, "Television");
|
||||
|
@ -3005,7 +2945,6 @@ static int bttv_g_tuner(struct file *file, void *priv,
|
|||
if (btv->audio_mode_gpio)
|
||||
btv->audio_mode_gpio(btv, t, 0);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3014,9 +2953,7 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p)
|
|||
struct bttv_fh *fh = f;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
*p = v4l2_prio_max(&btv->prio);
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3028,9 +2965,7 @@ static int bttv_s_priority(struct file *file, void *f,
|
|||
struct bttv *btv = fh->btv;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
rc = v4l2_prio_change(&btv->prio, &fh->prio, prio);
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -3045,9 +2980,7 @@ static int bttv_cropcap(struct file *file, void *priv,
|
|||
cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
*cap = bttv_tvnorms[btv->tvnorm].cropcap;
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3065,9 +2998,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
|||
inconsistent with fh->width or fh->height and apps
|
||||
do not expect a change here. */
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
crop->c = btv->crop[!!fh->do_crop].rect;
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3091,17 +3022,14 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
|||
/* Make sure tvnorm, vbi_end and the current cropping
|
||||
parameters remain consistent until we're done. Note
|
||||
read() may change vbi_end in check_alloc_btres_lock(). */
|
||||
mutex_lock(&btv->lock);
|
||||
retval = v4l2_prio_check(&btv->prio, fh->prio);
|
||||
if (0 != retval) {
|
||||
mutex_unlock(&btv->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = -EBUSY;
|
||||
|
||||
if (locked_btres(fh->btv, VIDEO_RESOURCES)) {
|
||||
mutex_unlock(&btv->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3113,7 +3041,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
|||
|
||||
b_top = max(b->top, btv->vbi_end);
|
||||
if (b_top + 32 >= b_bottom) {
|
||||
mutex_unlock(&btv->lock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3136,12 +3063,8 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
|||
|
||||
btv->crop[1] = c;
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
fh->do_crop = 1;
|
||||
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
|
||||
if (fh->width < c.min_scaled_width) {
|
||||
fh->width = c.min_scaled_width;
|
||||
btv->init.width = c.min_scaled_width;
|
||||
|
@ -3158,8 +3081,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
|
|||
btv->init.height = c.max_scaled_height;
|
||||
}
|
||||
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3227,7 +3148,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
|
|||
return videobuf_poll_stream(file, &fh->vbi, wait);
|
||||
}
|
||||
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
if (check_btres(fh,RESOURCE_VIDEO_STREAM)) {
|
||||
/* streaming capture */
|
||||
if (list_empty(&fh->cap.stream))
|
||||
|
@ -3262,7 +3182,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait)
|
|||
else
|
||||
rc = 0;
|
||||
err:
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -3293,23 +3212,11 @@ static int bttv_open(struct file *file)
|
|||
return -ENOMEM;
|
||||
file->private_data = fh;
|
||||
|
||||
/*
|
||||
* btv is protected by btv->lock mutex, while btv->init and other
|
||||
* streaming vars are protected by fh->cap.vb_lock. We need to take
|
||||
* care of both locks to avoid troubles. However, vb_lock is used also
|
||||
* inside videobuf, without calling buf->lock. So, it is a very bad
|
||||
* idea to hold both locks at the same time.
|
||||
* Let's first copy btv->init at fh, holding cap.vb_lock, and then work
|
||||
* with the rest of init, holding btv->lock.
|
||||
*/
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
*fh = btv->init;
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
fh->type = type;
|
||||
fh->ov.setup_ok = 0;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
v4l2_prio_open(&btv->prio, &fh->prio);
|
||||
|
||||
videobuf_queue_sg_init(&fh->cap, &bttv_video_qops,
|
||||
|
@ -3317,13 +3224,13 @@ static int bttv_open(struct file *file)
|
|||
V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||
V4L2_FIELD_INTERLACED,
|
||||
sizeof(struct bttv_buffer),
|
||||
fh, NULL);
|
||||
fh, &btv->lock);
|
||||
videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops,
|
||||
&btv->c.pci->dev, &btv->s_lock,
|
||||
V4L2_BUF_TYPE_VBI_CAPTURE,
|
||||
V4L2_FIELD_SEQ_TB,
|
||||
sizeof(struct bttv_buffer),
|
||||
fh, NULL);
|
||||
fh, &btv->lock);
|
||||
set_tvnorm(btv,btv->tvnorm);
|
||||
set_input(btv, btv->input, btv->tvnorm);
|
||||
|
||||
|
@ -3346,7 +3253,6 @@ static int bttv_open(struct file *file)
|
|||
bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm);
|
||||
|
||||
bttv_field_count(btv);
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3355,7 +3261,6 @@ static int bttv_release(struct file *file)
|
|||
struct bttv_fh *fh = file->private_data;
|
||||
struct bttv *btv = fh->btv;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
/* turn off overlay */
|
||||
if (check_btres(fh, RESOURCE_OVERLAY))
|
||||
bttv_switch_overlay(btv,fh,NULL);
|
||||
|
@ -3381,14 +3286,8 @@ static int bttv_release(struct file *file)
|
|||
|
||||
/* free stuff */
|
||||
|
||||
/*
|
||||
* videobuf uses cap.vb_lock - we should avoid holding btv->lock,
|
||||
* otherwise we may have dead lock conditions
|
||||
*/
|
||||
mutex_unlock(&btv->lock);
|
||||
videobuf_mmap_free(&fh->cap);
|
||||
videobuf_mmap_free(&fh->vbi);
|
||||
mutex_lock(&btv->lock);
|
||||
v4l2_prio_close(&btv->prio, fh->prio);
|
||||
file->private_data = NULL;
|
||||
kfree(fh);
|
||||
|
@ -3398,7 +3297,6 @@ static int bttv_release(struct file *file)
|
|||
|
||||
if (!btv->users)
|
||||
audio_mute(btv, 1);
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3502,11 +3400,8 @@ static int radio_open(struct file *file)
|
|||
if (unlikely(!fh))
|
||||
return -ENOMEM;
|
||||
file->private_data = fh;
|
||||
mutex_lock(&fh->cap.vb_lock);
|
||||
*fh = btv->init;
|
||||
mutex_unlock(&fh->cap.vb_lock);
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
v4l2_prio_open(&btv->prio, &fh->prio);
|
||||
|
||||
btv->radio_user++;
|
||||
|
@ -3514,7 +3409,6 @@ static int radio_open(struct file *file)
|
|||
bttv_call_all(btv, tuner, s_radio);
|
||||
audio_input(btv,TVAUDIO_INPUT_RADIO);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3524,7 +3418,6 @@ static int radio_release(struct file *file)
|
|||
struct bttv *btv = fh->btv;
|
||||
struct rds_command cmd;
|
||||
|
||||
mutex_lock(&btv->lock);
|
||||
v4l2_prio_close(&btv->prio, fh->prio);
|
||||
file->private_data = NULL;
|
||||
kfree(fh);
|
||||
|
@ -3532,7 +3425,6 @@ static int radio_release(struct file *file)
|
|||
btv->radio_user--;
|
||||
|
||||
bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3561,7 +3453,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
|
|||
return -EINVAL;
|
||||
if (0 != t->index)
|
||||
return -EINVAL;
|
||||
mutex_lock(&btv->lock);
|
||||
strcpy(t->name, "Radio");
|
||||
t->type = V4L2_TUNER_RADIO;
|
||||
|
||||
|
@ -3570,8 +3461,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
|
|||
if (btv->audio_mode_gpio)
|
||||
btv->audio_mode_gpio(btv, t, 0);
|
||||
|
||||
mutex_unlock(&btv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3692,7 +3581,7 @@ static const struct v4l2_file_operations radio_fops =
|
|||
.open = radio_open,
|
||||
.read = radio_read,
|
||||
.release = radio_release,
|
||||
.ioctl = video_ioctl2,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.poll = radio_poll,
|
||||
};
|
||||
|
||||
|
|
|
@ -63,7 +63,10 @@ struct sd {
|
|||
#define QUALITY_DEF 80
|
||||
u8 jpegqual; /* webcam quality */
|
||||
|
||||
u8 reg01;
|
||||
u8 reg17;
|
||||
u8 reg18;
|
||||
u8 flags;
|
||||
|
||||
s8 ag_cnt;
|
||||
#define AG_CNT_START 13
|
||||
|
@ -96,6 +99,22 @@ enum sensors {
|
|||
SENSOR_SP80708,
|
||||
};
|
||||
|
||||
/* device flags */
|
||||
#define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */
|
||||
|
||||
/* sn9c1xx definitions */
|
||||
/* register 0x01 */
|
||||
#define S_PWR_DN 0x01 /* sensor power down */
|
||||
#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
|
||||
#define V_TX_EN 0x04 /* video transfer enable */
|
||||
#define LED 0x08 /* output to pin LED */
|
||||
#define SCL_SEL_OD 0x20 /* open-drain mode */
|
||||
#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
|
||||
/* register 0x17 */
|
||||
#define MCK_SIZE_MASK 0x1f /* sensor master clock */
|
||||
#define SEN_CLK_EN 0x20 /* enable sensor clock */
|
||||
#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
|
||||
|
||||
/* V4L2 controls supported by the driver */
|
||||
static void setbrightness(struct gspca_dev *gspca_dev);
|
||||
static void setcontrast(struct gspca_dev *gspca_dev);
|
||||
|
@ -1755,141 +1774,6 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void bridge_init(struct gspca_dev *gspca_dev,
|
||||
const u8 *sn9c1xx)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
u8 reg0102[2];
|
||||
const u8 *reg9a;
|
||||
static const u8 reg9a_def[] =
|
||||
{0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
|
||||
static const u8 reg9a_spec[] =
|
||||
{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
|
||||
static const u8 regd4[] = {0x60, 0x00, 0x00};
|
||||
|
||||
/* sensor clock already enabled in sd_init */
|
||||
/* reg_w1(gspca_dev, 0xf1, 0x00); */
|
||||
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
|
||||
|
||||
/* configure gpio */
|
||||
reg0102[0] = sn9c1xx[1];
|
||||
reg0102[1] = sn9c1xx[2];
|
||||
if (gspca_dev->audio)
|
||||
reg0102[1] |= 0x04; /* keep the audio connection */
|
||||
reg_w(gspca_dev, 0x01, reg0102, 2);
|
||||
reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
|
||||
reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_GC0307:
|
||||
case SENSOR_OV7660:
|
||||
case SENSOR_PO1030:
|
||||
case SENSOR_PO2030N:
|
||||
case SENSOR_SOI768:
|
||||
case SENSOR_SP80708:
|
||||
reg9a = reg9a_spec;
|
||||
break;
|
||||
default:
|
||||
reg9a = reg9a_def;
|
||||
break;
|
||||
}
|
||||
reg_w(gspca_dev, 0x9a, reg9a, 6);
|
||||
|
||||
reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
|
||||
|
||||
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_ADCM1700:
|
||||
reg_w1(gspca_dev, 0x01, 0x43);
|
||||
reg_w1(gspca_dev, 0x17, 0x62);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
break;
|
||||
case SENSOR_GC0307:
|
||||
msleep(50);
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0x22);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x40);
|
||||
msleep(50);
|
||||
break;
|
||||
case SENSOR_MI0360B:
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x40);
|
||||
break;
|
||||
case SENSOR_MT9V111:
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0x61);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x40);
|
||||
break;
|
||||
case SENSOR_OM6802:
|
||||
msleep(10);
|
||||
reg_w1(gspca_dev, 0x02, 0x73);
|
||||
reg_w1(gspca_dev, 0x17, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x22);
|
||||
msleep(100);
|
||||
reg_w1(gspca_dev, 0x01, 0x62);
|
||||
reg_w1(gspca_dev, 0x17, 0x64);
|
||||
reg_w1(gspca_dev, 0x17, 0x64);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
msleep(10);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
i2c_w8(gspca_dev, om6802_init0[0]);
|
||||
i2c_w8(gspca_dev, om6802_init0[1]);
|
||||
msleep(15);
|
||||
reg_w1(gspca_dev, 0x02, 0x71);
|
||||
msleep(150);
|
||||
break;
|
||||
case SENSOR_OV7630:
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0xe2);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x40);
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
reg_w1(gspca_dev, 0x01, 0x63);
|
||||
reg_w1(gspca_dev, 0x17, 0x20);
|
||||
reg_w1(gspca_dev, 0x01, 0x62);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
break;
|
||||
case SENSOR_PO1030:
|
||||
case SENSOR_SOI768:
|
||||
reg_w1(gspca_dev, 0x01, 0x61);
|
||||
reg_w1(gspca_dev, 0x17, 0x20);
|
||||
reg_w1(gspca_dev, 0x01, 0x60);
|
||||
reg_w1(gspca_dev, 0x01, 0x40);
|
||||
break;
|
||||
case SENSOR_PO2030N:
|
||||
case SENSOR_OV7660:
|
||||
reg_w1(gspca_dev, 0x01, 0x63);
|
||||
reg_w1(gspca_dev, 0x17, 0x20);
|
||||
reg_w1(gspca_dev, 0x01, 0x62);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
break;
|
||||
case SENSOR_SP80708:
|
||||
reg_w1(gspca_dev, 0x01, 0x63);
|
||||
reg_w1(gspca_dev, 0x17, 0x20);
|
||||
reg_w1(gspca_dev, 0x01, 0x62);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
msleep(100);
|
||||
reg_w1(gspca_dev, 0x02, 0x62);
|
||||
break;
|
||||
default:
|
||||
/* case SENSOR_HV7131R: */
|
||||
/* case SENSOR_MI0360: */
|
||||
/* case SENSOR_MO4000: */
|
||||
reg_w1(gspca_dev, 0x01, 0x43);
|
||||
reg_w1(gspca_dev, 0x17, 0x61);
|
||||
reg_w1(gspca_dev, 0x01, 0x42);
|
||||
if (sd->sensor == SENSOR_HV7131R)
|
||||
hv7131r_probe(gspca_dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function is called at probe time */
|
||||
static int sd_config(struct gspca_dev *gspca_dev,
|
||||
const struct usb_device_id *id)
|
||||
|
@ -1898,7 +1782,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
struct cam *cam;
|
||||
|
||||
sd->bridge = id->driver_info >> 16;
|
||||
sd->sensor = id->driver_info;
|
||||
sd->sensor = id->driver_info >> 8;
|
||||
sd->flags = id->driver_info;
|
||||
|
||||
cam = &gspca_dev->cam;
|
||||
if (sd->sensor == SENSOR_ADCM1700) {
|
||||
|
@ -1929,7 +1814,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
|||
/* setup a selector by bridge */
|
||||
reg_w1(gspca_dev, 0xf1, 0x01);
|
||||
reg_r(gspca_dev, 0x00, 1);
|
||||
reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
|
||||
reg_w1(gspca_dev, 0xf1, 0x00);
|
||||
reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
|
||||
regF1 = gspca_dev->usb_buf[0];
|
||||
if (gspca_dev->usb_err < 0)
|
||||
|
@ -2423,10 +2308,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i;
|
||||
u8 reg1, reg17;
|
||||
u8 reg01, reg17;
|
||||
u8 reg0102[2];
|
||||
const u8 *sn9c1xx;
|
||||
const u8 (*init)[8];
|
||||
const u8 *reg9a;
|
||||
int mode;
|
||||
static const u8 reg9a_def[] =
|
||||
{0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
|
||||
static const u8 reg9a_spec[] =
|
||||
{0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
|
||||
static const u8 regd4[] = {0x60, 0x00, 0x00};
|
||||
static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
|
||||
static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
|
||||
static const u8 CA_adcm1700[] =
|
||||
|
@ -2448,7 +2340,85 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
|
||||
/* initialize the bridge */
|
||||
sn9c1xx = sn_tb[sd->sensor];
|
||||
bridge_init(gspca_dev, sn9c1xx);
|
||||
|
||||
/* sensor clock already enabled in sd_init */
|
||||
/* reg_w1(gspca_dev, 0xf1, 0x00); */
|
||||
reg01 = sn9c1xx[1];
|
||||
if (sd->flags & PDN_INV)
|
||||
reg01 ^= S_PDN_INV; /* power down inverted */
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
|
||||
/* configure gpio */
|
||||
reg0102[0] = reg01;
|
||||
reg0102[1] = sn9c1xx[2];
|
||||
if (gspca_dev->audio)
|
||||
reg0102[1] |= 0x04; /* keep the audio connection */
|
||||
reg_w(gspca_dev, 0x01, reg0102, 2);
|
||||
reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
|
||||
reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_GC0307:
|
||||
case SENSOR_OV7660:
|
||||
case SENSOR_PO1030:
|
||||
case SENSOR_PO2030N:
|
||||
case SENSOR_SOI768:
|
||||
case SENSOR_SP80708:
|
||||
reg9a = reg9a_spec;
|
||||
break;
|
||||
default:
|
||||
reg9a = reg9a_def;
|
||||
break;
|
||||
}
|
||||
reg_w(gspca_dev, 0x9a, reg9a, 6);
|
||||
|
||||
reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
|
||||
|
||||
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
|
||||
|
||||
reg17 = sn9c1xx[0x17];
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_GC0307:
|
||||
msleep(50); /*fixme: is it useful? */
|
||||
break;
|
||||
case SENSOR_OM6802:
|
||||
msleep(10);
|
||||
reg_w1(gspca_dev, 0x02, 0x73);
|
||||
reg17 |= SEN_CLK_EN;
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg_w1(gspca_dev, 0x01, 0x22);
|
||||
msleep(100);
|
||||
reg01 = SCL_SEL_OD | S_PDN_INV;
|
||||
reg17 &= MCK_SIZE_MASK;
|
||||
reg17 |= 0x04; /* clock / 4 */
|
||||
break;
|
||||
}
|
||||
reg01 |= SYS_SEL_48M;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg17 |= SEN_CLK_EN;
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg01 &= ~S_PWR_DN; /* sensor power on */
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg01 &= ~SYS_SEL_48M;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_HV7131R:
|
||||
hv7131r_probe(gspca_dev); /*fixme: is it useful? */
|
||||
break;
|
||||
case SENSOR_OM6802:
|
||||
msleep(10);
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
i2c_w8(gspca_dev, om6802_init0[0]);
|
||||
i2c_w8(gspca_dev, om6802_init0[1]);
|
||||
msleep(15);
|
||||
reg_w1(gspca_dev, 0x02, 0x71);
|
||||
msleep(150);
|
||||
break;
|
||||
case SENSOR_SP80708:
|
||||
msleep(100);
|
||||
reg_w1(gspca_dev, 0x02, 0x62);
|
||||
break;
|
||||
}
|
||||
|
||||
/* initialize the sensor */
|
||||
i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
|
||||
|
@ -2476,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_GC0307:
|
||||
reg17 = 0xa2;
|
||||
break;
|
||||
case SENSOR_MT9V111:
|
||||
case SENSOR_MI0360B:
|
||||
reg17 = 0xe0;
|
||||
break;
|
||||
case SENSOR_ADCM1700:
|
||||
case SENSOR_OV7630:
|
||||
reg17 = 0xe2;
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
reg17 = 0x20;
|
||||
break;
|
||||
case SENSOR_OV7660:
|
||||
case SENSOR_SOI768:
|
||||
reg17 = 0xa0;
|
||||
break;
|
||||
case SENSOR_PO1030:
|
||||
case SENSOR_PO2030N:
|
||||
reg17 = 0xa0;
|
||||
case SENSOR_OM6802:
|
||||
/* case SENSOR_OV7648: * fixme: sometimes */
|
||||
break;
|
||||
default:
|
||||
reg17 = 0x60;
|
||||
reg17 |= DEF_EN;
|
||||
break;
|
||||
}
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
|
@ -2546,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
|
||||
init = NULL;
|
||||
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
|
||||
if (mode)
|
||||
reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
|
||||
else
|
||||
reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
|
||||
reg17 = 0x61; /* 0x:20: enable sensor clock */
|
||||
reg01 |= SYS_SEL_48M | V_TX_EN;
|
||||
reg17 &= ~MCK_SIZE_MASK;
|
||||
reg17 |= 0x02; /* clock / 2 */
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_ADCM1700:
|
||||
init = adcm1700_sensor_param1;
|
||||
reg1 = 0x46;
|
||||
reg17 = 0xe2;
|
||||
break;
|
||||
case SENSOR_GC0307:
|
||||
init = gc0307_sensor_param1;
|
||||
reg17 = 0xa2;
|
||||
reg1 = 0x44;
|
||||
break;
|
||||
case SENSOR_HV7131R:
|
||||
case SENSOR_MI0360:
|
||||
if (mode)
|
||||
reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */
|
||||
else
|
||||
reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
|
||||
reg17 &= ~MCK_SIZE_MASK;
|
||||
reg17 |= 0x01; /* clock / 1 */
|
||||
break;
|
||||
case SENSOR_MI0360B:
|
||||
init = mi0360b_sensor_param1;
|
||||
reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */
|
||||
reg17 = 0xe2;
|
||||
break;
|
||||
case SENSOR_MO4000:
|
||||
if (mode) {
|
||||
/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
|
||||
reg1 = 0x06; /* clk 24Mz */
|
||||
} else {
|
||||
reg17 = 0x22; /* 640 MCKSIZE */
|
||||
/* reg1 = 0x06; * 640 clk 24Mz (done) */
|
||||
if (mode) { /* if 320x240 */
|
||||
reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
|
||||
reg17 &= ~MCK_SIZE_MASK;
|
||||
reg17 |= 0x01; /* clock / 1 */
|
||||
}
|
||||
break;
|
||||
case SENSOR_MT9V111:
|
||||
init = mt9v111_sensor_param1;
|
||||
if (mode) {
|
||||
reg1 = 0x04; /* 320 clk 48Mhz */
|
||||
} else {
|
||||
/* reg1 = 0x06; * 640 clk 24Mz (done) */
|
||||
reg17 = 0xc2;
|
||||
}
|
||||
break;
|
||||
case SENSOR_OM6802:
|
||||
init = om6802_sensor_param1;
|
||||
reg17 = 0x64; /* 640 MCKSIZE */
|
||||
if (!mode) { /* if 640x480 */
|
||||
reg17 &= ~MCK_SIZE_MASK;
|
||||
reg17 |= 0x01; /* clock / 4 */
|
||||
}
|
||||
break;
|
||||
case SENSOR_OV7630:
|
||||
init = ov7630_sensor_param1;
|
||||
reg17 = 0xe2;
|
||||
reg1 = 0x44;
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
init = ov7648_sensor_param1;
|
||||
reg17 = 0x21;
|
||||
/* reg1 = 0x42; * 42 - 46? */
|
||||
reg17 &= ~MCK_SIZE_MASK;
|
||||
reg17 |= 0x01; /* clock / 1 */
|
||||
break;
|
||||
case SENSOR_OV7660:
|
||||
init = ov7660_sensor_param1;
|
||||
if (sd->bridge == BRIDGE_SN9C120) {
|
||||
if (mode) { /* 320x240 - 160x120 */
|
||||
reg17 = 0xa2;
|
||||
reg1 = 0x44; /* 48 Mhz, video trf eneble */
|
||||
}
|
||||
} else {
|
||||
reg17 = 0x22;
|
||||
reg1 = 0x06; /* 24 Mhz, video trf eneble
|
||||
* inverse power down */
|
||||
}
|
||||
break;
|
||||
case SENSOR_PO1030:
|
||||
init = po1030_sensor_param1;
|
||||
reg17 = 0xa2;
|
||||
reg1 = 0x44;
|
||||
break;
|
||||
case SENSOR_PO2030N:
|
||||
init = po2030n_sensor_param1;
|
||||
reg1 = 0x46;
|
||||
reg17 = 0xa2;
|
||||
break;
|
||||
case SENSOR_SOI768:
|
||||
init = soi768_sensor_param1;
|
||||
reg1 = 0x44;
|
||||
reg17 = 0xa2;
|
||||
break;
|
||||
case SENSOR_SP80708:
|
||||
init = sp80708_sensor_param1;
|
||||
if (mode) {
|
||||
/*?? reg1 = 0x04; * 320 clk 48Mhz */
|
||||
} else {
|
||||
reg1 = 0x46; /* 640 clk 48Mz */
|
||||
reg17 = 0xa2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2684,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||
setjpegqual(gspca_dev);
|
||||
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg_w1(gspca_dev, 0x01, reg1);
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
sd->reg01 = reg01;
|
||||
sd->reg17 = reg17;
|
||||
|
||||
sethvflip(gspca_dev);
|
||||
setbrightness(gspca_dev);
|
||||
|
@ -2706,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
|||
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
|
||||
static const u8 stopsoi768[] =
|
||||
{ 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
|
||||
u8 data;
|
||||
const u8 *sn9c1xx;
|
||||
u8 reg01;
|
||||
u8 reg17;
|
||||
|
||||
data = 0x0b;
|
||||
reg01 = sd->reg01;
|
||||
reg17 = sd->reg17 & ~SEN_CLK_EN;
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_ADCM1700:
|
||||
case SENSOR_GC0307:
|
||||
data = 0x29;
|
||||
case SENSOR_PO2030N:
|
||||
case SENSOR_SP80708:
|
||||
reg01 |= LED;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg01 &= ~(LED | V_TX_EN);
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
|
||||
break;
|
||||
case SENSOR_HV7131R:
|
||||
reg01 &= ~V_TX_EN;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
i2c_w8(gspca_dev, stophv7131);
|
||||
data = 0x2b;
|
||||
break;
|
||||
case SENSOR_MI0360:
|
||||
case SENSOR_MI0360B:
|
||||
reg01 &= ~V_TX_EN;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
|
||||
i2c_w8(gspca_dev, stopmi0360);
|
||||
data = 0x29;
|
||||
break;
|
||||
case SENSOR_OV7648:
|
||||
i2c_w8(gspca_dev, stopov7648);
|
||||
/* fall thru */
|
||||
case SENSOR_MT9V111:
|
||||
case SENSOR_OV7630:
|
||||
case SENSOR_OM6802:
|
||||
case SENSOR_PO1030:
|
||||
data = 0x29;
|
||||
reg01 &= ~V_TX_EN;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
break;
|
||||
case SENSOR_OV7630:
|
||||
case SENSOR_OV7648:
|
||||
reg01 &= ~V_TX_EN;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
i2c_w8(gspca_dev, stopov7648);
|
||||
break;
|
||||
case SENSOR_OV7660:
|
||||
reg01 &= ~V_TX_EN;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
break;
|
||||
case SENSOR_SOI768:
|
||||
i2c_w8(gspca_dev, stopsoi768);
|
||||
data = 0x29;
|
||||
break;
|
||||
}
|
||||
sn9c1xx = sn_tb[sd->sensor];
|
||||
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
|
||||
reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
|
||||
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
|
||||
reg_w1(gspca_dev, 0x01, data);
|
||||
|
||||
reg01 |= SCL_SEL_OD;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg01 |= S_PWR_DN; /* sensor power down */
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg_w1(gspca_dev, 0x17, reg17);
|
||||
reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
reg01 |= LED;
|
||||
reg_w1(gspca_dev, 0x01, reg01);
|
||||
/* Don't disable sensor clock as that disables the button on the cam */
|
||||
/* reg_w1(gspca_dev, 0xf1, 0x01); */
|
||||
}
|
||||
|
@ -2954,14 +2902,18 @@ static const struct sd_desc sd_desc = {
|
|||
/* -- module initialisation -- */
|
||||
#define BS(bridge, sensor) \
|
||||
.driver_info = (BRIDGE_ ## bridge << 16) \
|
||||
| SENSOR_ ## sensor
|
||||
| (SENSOR_ ## sensor << 8)
|
||||
#define BSF(bridge, sensor, flags) \
|
||||
.driver_info = (BRIDGE_ ## bridge << 16) \
|
||||
| (SENSOR_ ## sensor << 8) \
|
||||
| (flags)
|
||||
static const __devinitdata struct usb_device_id device_table[] = {
|
||||
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
|
||||
{USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
|
||||
{USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
|
||||
#endif
|
||||
{USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
|
||||
{USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
|
||||
{USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)},
|
||||
{USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)},
|
||||
{USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
|
||||
{USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
|
||||
{USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
|
||||
|
|
|
@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
|
|||
|
||||
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
|
||||
csicr1 |= CSICR1_REDGE;
|
||||
if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
|
||||
csicr1 |= CSICR1_INV_PCLK;
|
||||
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
|
||||
csicr1 |= CSICR1_SOF_POL;
|
||||
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
|
||||
|
|
|
@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv,
|
|||
INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
|
||||
fimc->vid_cap.active_buf_cnt = 0;
|
||||
fimc->vid_cap.frame_count = 0;
|
||||
fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
|
||||
|
||||
set_bit(ST_CAPT_PEND, &fimc->state);
|
||||
ret = videobuf_streamon(&fimc->vid_cap.vbq);
|
||||
|
@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int fimc_cap_cropcap(struct file *file, void *fh,
|
||||
struct v4l2_cropcap *cr)
|
||||
{
|
||||
struct fimc_frame *f;
|
||||
struct fimc_ctx *ctx = fh;
|
||||
struct fimc_dev *fimc = ctx->fimc_dev;
|
||||
|
||||
if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
f = &ctx->s_frame;
|
||||
cr->bounds.left = 0;
|
||||
cr->bounds.top = 0;
|
||||
cr->bounds.width = f->o_width;
|
||||
cr->bounds.height = f->o_height;
|
||||
cr->defrect = cr->bounds;
|
||||
|
||||
mutex_unlock(&fimc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
||||
{
|
||||
struct fimc_frame *f;
|
||||
struct fimc_ctx *ctx = file->private_data;
|
||||
struct fimc_dev *fimc = ctx->fimc_dev;
|
||||
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
f = &ctx->s_frame;
|
||||
cr->c.left = f->offs_h;
|
||||
cr->c.top = f->offs_v;
|
||||
cr->c.width = f->width;
|
||||
cr->c.height = f->height;
|
||||
|
||||
mutex_unlock(&fimc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fimc_cap_s_crop(struct file *file, void *fh,
|
||||
struct v4l2_crop *cr)
|
||||
{
|
||||
|
@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
|
|||
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
|
||||
.vidioc_s_ctrl = fimc_cap_s_ctrl,
|
||||
|
||||
.vidioc_g_crop = fimc_vidioc_g_crop,
|
||||
.vidioc_g_crop = fimc_cap_g_crop,
|
||||
.vidioc_s_crop = fimc_cap_s_crop,
|
||||
.vidioc_cropcap = fimc_vidioc_cropcap,
|
||||
.vidioc_cropcap = fimc_cap_cropcap,
|
||||
|
||||
.vidioc_enum_input = fimc_cap_enum_input,
|
||||
.vidioc_s_input = fimc_cap_s_input,
|
||||
|
@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
|
|||
videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
|
||||
vid_cap->v4l2_dev.dev, &fimc->irqlock,
|
||||
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
|
||||
sizeof(struct fimc_vid_buffer), (void *)ctx);
|
||||
sizeof(struct fimc_vid_buffer), (void *)ctx, NULL);
|
||||
|
||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
|
||||
if (ret) {
|
||||
|
|
|
@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = {
|
|||
.planes_cnt = 1,
|
||||
.flags = FMT_FLAGS_M2M,
|
||||
}, {
|
||||
.name = "XRGB-8-8-8-8, 24 bpp",
|
||||
.fourcc = V4L2_PIX_FMT_RGB24,
|
||||
.name = "XRGB-8-8-8-8, 32 bpp",
|
||||
.fourcc = V4L2_PIX_FMT_RGB32,
|
||||
.depth = 32,
|
||||
.color = S5P_FIMC_RGB888,
|
||||
.buff_cnt = 1,
|
||||
|
@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
|
|||
{
|
||||
struct fimc_ctx *ctx = priv;
|
||||
struct v4l2_queryctrl *c;
|
||||
int ret = -EINVAL;
|
||||
|
||||
c = get_ctrl(qc->id);
|
||||
if (c) {
|
||||
|
@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->state & FIMC_CTX_CAP)
|
||||
return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
|
||||
if (ctx->state & FIMC_CTX_CAP) {
|
||||
if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
|
||||
return -ERESTARTSYS;
|
||||
ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
|
||||
core, queryctrl, qc);
|
||||
return -EINVAL;
|
||||
mutex_unlock(&ctx->fimc_dev->lock);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
|
||||
|
@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fimc_vidioc_cropcap(struct file *file, void *fh,
|
||||
static int fimc_m2m_cropcap(struct file *file, void *fh,
|
||||
struct v4l2_cropcap *cr)
|
||||
{
|
||||
struct fimc_frame *frame;
|
||||
|
@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
||||
static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
||||
{
|
||||
struct fimc_frame *frame;
|
||||
struct fimc_ctx *ctx = file->private_data;
|
||||
|
@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
|
|||
struct fimc_frame *f;
|
||||
u32 min_size, halign;
|
||||
|
||||
f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
|
||||
&ctx->s_frame : &ctx->d_frame;
|
||||
|
||||
if (cr->c.top < 0 || cr->c.left < 0) {
|
||||
v4l2_err(&fimc->m2m.v4l2_dev,
|
||||
"doesn't support negative values for top & left\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
f = ctx_get_frame(ctx, cr->type);
|
||||
if (IS_ERR(f))
|
||||
return PTR_ERR(f);
|
||||
if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame;
|
||||
else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
|
||||
ctx->state & FIMC_CTX_M2M)
|
||||
f = &ctx->s_frame;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
|
||||
? fimc->variant->min_inp_pixsize
|
||||
: fimc->variant->min_out_pixsize;
|
||||
min_size = (f == &ctx->s_frame) ?
|
||||
fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
|
||||
|
||||
if (ctx->state & FIMC_CTX_M2M) {
|
||||
if (fimc->id == 1 && fimc->variant->pix_hoff)
|
||||
|
@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
|||
f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
|
||||
&ctx->s_frame : &ctx->d_frame;
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
spin_lock_irqsave(&ctx->slock, flags);
|
||||
if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) {
|
||||
/* Check to see if scaling ratio is within supported range */
|
||||
|
@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
|||
else
|
||||
ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame);
|
||||
if (ret) {
|
||||
spin_unlock_irqrestore(&ctx->slock, flags);
|
||||
v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range");
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto scr_unlock;
|
||||
}
|
||||
}
|
||||
ctx->state |= FIMC_PARAMS;
|
||||
|
@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
|
|||
f->width = cr->c.width;
|
||||
f->height = cr->c.height;
|
||||
|
||||
scr_unlock:
|
||||
spin_unlock_irqrestore(&ctx->slock, flags);
|
||||
mutex_unlock(&fimc->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
|
|||
.vidioc_g_ctrl = fimc_vidioc_g_ctrl,
|
||||
.vidioc_s_ctrl = fimc_m2m_s_ctrl,
|
||||
|
||||
.vidioc_g_crop = fimc_vidioc_g_crop,
|
||||
.vidioc_g_crop = fimc_m2m_g_crop,
|
||||
.vidioc_s_crop = fimc_m2m_s_crop,
|
||||
.vidioc_cropcap = fimc_vidioc_cropcap
|
||||
.vidioc_cropcap = fimc_m2m_cropcap
|
||||
|
||||
};
|
||||
|
||||
|
@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = {
|
|||
.open = fimc_m2m_open,
|
||||
.release = fimc_m2m_release,
|
||||
.poll = fimc_m2m_poll,
|
||||
.ioctl = video_ioctl2,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.mmap = fimc_m2m_mmap,
|
||||
};
|
||||
|
||||
|
@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
|
|||
.pix_hoff = 1,
|
||||
.has_inp_rot = 1,
|
||||
.has_out_rot = 1,
|
||||
.has_cistatus2 = 1,
|
||||
.min_inp_pixsize = 16,
|
||||
.min_out_pixsize = 16,
|
||||
.hor_offs_align = 1,
|
||||
|
@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
|
|||
|
||||
static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
|
||||
.pix_hoff = 1,
|
||||
.has_cistatus2 = 1,
|
||||
.min_inp_pixsize = 16,
|
||||
.min_out_pixsize = 16,
|
||||
.hor_offs_align = 1,
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/videobuf-core.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-mem2mem.h>
|
||||
#include <media/v4l2-mediabus.h>
|
||||
#include <media/s3c_fimc.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#include "regs-fimc.h"
|
||||
|
||||
#define err(fmt, args...) \
|
||||
|
@ -369,6 +371,7 @@ struct fimc_pix_limit {
|
|||
* @pix_hoff: indicate whether horizontal offset is in pixels or in bytes
|
||||
* @has_inp_rot: set if has input rotator
|
||||
* @has_out_rot: set if has output rotator
|
||||
* @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
|
||||
* @pix_limit: pixel size constraints for the scaler
|
||||
* @min_inp_pixsize: minimum input pixel size
|
||||
* @min_out_pixsize: minimum output pixel size
|
||||
|
@ -379,6 +382,7 @@ struct samsung_fimc_variant {
|
|||
unsigned int pix_hoff:1;
|
||||
unsigned int has_inp_rot:1;
|
||||
unsigned int has_out_rot:1;
|
||||
unsigned int has_cistatus2:1;
|
||||
struct fimc_pix_limit *pix_limit;
|
||||
u16 min_inp_pixsize;
|
||||
u16 min_out_pixsize;
|
||||
|
@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
|
|||
return frame;
|
||||
}
|
||||
|
||||
/* Return an index to the buffer actually being written. */
|
||||
static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev)
|
||||
{
|
||||
u32 reg = readl(dev->regs + S5P_CISTATUS);
|
||||
return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
|
||||
S5P_CISTATUS_FRAMECNT_SHIFT;
|
||||
u32 reg;
|
||||
|
||||
if (dev->variant->has_cistatus2) {
|
||||
reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F;
|
||||
return reg > 0 ? --reg : reg;
|
||||
} else {
|
||||
reg = readl(dev->regs + S5P_CISTATUS);
|
||||
return (reg & S5P_CISTATUS_FRAMECNT_MASK) >>
|
||||
S5P_CISTATUS_FRAMECNT_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------*/
|
||||
|
@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv,
|
|||
struct v4l2_format *f);
|
||||
int fimc_vidioc_try_fmt(struct file *file, void *priv,
|
||||
struct v4l2_format *f);
|
||||
int fimc_vidioc_g_crop(struct file *file, void *fh,
|
||||
struct v4l2_crop *cr);
|
||||
int fimc_vidioc_cropcap(struct file *file, void *fh,
|
||||
struct v4l2_cropcap *cr);
|
||||
int fimc_vidioc_queryctrl(struct file *file, void *priv,
|
||||
struct v4l2_queryctrl *qc);
|
||||
int fimc_vidioc_g_ctrl(struct file *file, void *priv,
|
||||
|
|
|
@ -165,6 +165,9 @@
|
|||
#define S5P_CISTATUS_VVALID_A (1 << 15)
|
||||
#define S5P_CISTATUS_VVALID_B (1 << 14)
|
||||
|
||||
/* Indexes to the last and the currently processed buffer. */
|
||||
#define S5P_CISTATUS2 0x68
|
||||
|
||||
/* Image capture control */
|
||||
#define S5P_CIIMGCPT 0xc0
|
||||
#define S5P_CIIMGCPT_IMGCPTEN (1 << 31)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче