mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 09:34:12 +08:00
ASoC: More updates for v3.8
Nothing terribly exciting here, just small localised changes. As well as fixes there are a couple of Cirrus changes and one devm_ change which were in prior to the merge window but got missed from the original pull to Takashi. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJQzJCAAAoJELSic+t+oim976sQAI8OMV9oRV2qjhjWz+WRQlR7 dPMLRh1UzBKaYxs4izF21Kp4tfH6fQfopZb5m13JZJXEgjp1cV+3FyZaxQHrdJz4 n6+vrzc2yp8PRdgv0FDuqbnKVlgxEJQEqX/okWjGFYg4AGn6St0UsDgH1eHt+QsF LTsbDnEwgsfni7ybUeukv6RyPpskfw+KfBpKyHfb1lf/5x+W9sel96Hsf/ihFLIT Ij1wPjYarK5LYfwNqQO4g1FaBAe4TmKEUOt0sjMCx7B3icDp4tgp+rbEOEdA1bLJ w9cJu5HPkvyXcin6cguk6Hu4QmPPSyi2Q56dnwTqdP+2Dq4rQzUd6e9BFdvkQqpR Pn2L8RQRv3RMD+mgPVnMJK5LnKF5iBKzEZINa32CeacTTjThMbRUr0odo+Wc4Xql kfoNmSU2rMwM93pweWD/OGl6Am0WrmNWy8jDnkvhhEd5+ZEAQkox6fiSZTe0YLCs CZ0TIW/7UzqaUv5MqRKg3W5+9rdsxcaMgIbjB7LE+MKBaLApHIPgBqRpqRtfwTh1 DPr1lCUqjJoJomMPHVhIPq7ktR1oHuVULEtGPyxygaxLSmbAA8ib2r7e8fsA0GTS joJsLrRU6+X9fIK272NmC15dbflnv6cgvaba2RDkenM8+DHqpNrufRqe0MflzoEU 0p9h7mTLk5+No+DzxWfs =3VlW -----END PGP SIGNATURE----- Merge tag 'asoc-3.8p1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-next ASoC: More updates for v3.8 Nothing terribly exciting here, just small localised changes. As well as fixes there are a couple of Cirrus changes and one devm_ change which were in prior to the merge window but got missed from the original pull to Takashi.
This commit is contained in:
commit
6be7f5344b
8
Makefile
8
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 7
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc7
|
||||
EXTRAVERSION =
|
||||
NAME = Terrified Chipmunk
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -1321,10 +1321,12 @@ kernelversion:
|
||||
|
||||
# Clear a bunch of variables before executing the submake
|
||||
tools/: FORCE
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/
|
||||
$(Q)mkdir -p $(objtree)/tools
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/
|
||||
|
||||
tools/%: FORCE
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS= -C $(src)/tools/ $*
|
||||
$(Q)mkdir -p $(objtree)/tools
|
||||
$(Q)$(MAKE) LDFLAGS= MAKEFLAGS= O=$(objtree) subdir=tools -C $(src)/tools/ $*
|
||||
|
||||
# Single targets
|
||||
# ---------------------------------------------------------------------------
|
||||
|
@ -547,6 +547,7 @@ config ARCH_KIRKWOOD
|
||||
select CPU_FEROCEON
|
||||
select GENERIC_CLOCKEVENTS
|
||||
select PCI
|
||||
select PCI_QUIRKS
|
||||
select PLAT_ORION_LEGACY
|
||||
help
|
||||
Support for the following Marvell Kirkwood series SoCs:
|
||||
|
@ -652,6 +652,15 @@ __setup_mmu: sub r3, r4, #16384 @ Page directory size
|
||||
mov pc, lr
|
||||
ENDPROC(__setup_mmu)
|
||||
|
||||
@ Enable unaligned access on v6, to allow better code generation
|
||||
@ for the decompressor C code:
|
||||
__armv6_mmu_cache_on:
|
||||
mrc p15, 0, r0, c1, c0, 0 @ read SCTLR
|
||||
bic r0, r0, #2 @ A (no unaligned access fault)
|
||||
orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
|
||||
mcr p15, 0, r0, c1, c0, 0 @ write SCTLR
|
||||
b __armv4_mmu_cache_on
|
||||
|
||||
__arm926ejs_mmu_cache_on:
|
||||
#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
|
||||
mov r0, #4 @ put dcache in WT mode
|
||||
@ -694,6 +703,9 @@ __armv7_mmu_cache_on:
|
||||
bic r0, r0, #1 << 28 @ clear SCTLR.TRE
|
||||
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
|
||||
orr r0, r0, #0x003c @ write buffer
|
||||
bic r0, r0, #2 @ A (no unaligned access fault)
|
||||
orr r0, r0, #1 << 22 @ U (v6 unaligned access model)
|
||||
@ (needed for ARM1176)
|
||||
#ifdef CONFIG_MMU
|
||||
#ifdef CONFIG_CPU_ENDIAN_BE8
|
||||
orr r0, r0, #1 << 25 @ big-endian page tables
|
||||
@ -914,7 +926,7 @@ proc_types:
|
||||
|
||||
.word 0x0007b000 @ ARMv6
|
||||
.word 0x000ff000
|
||||
W(b) __armv4_mmu_cache_on
|
||||
W(b) __armv6_mmu_cache_on
|
||||
W(b) __armv4_mmu_cache_off
|
||||
W(b) __armv6_mmu_cache_flush
|
||||
|
||||
|
@ -217,7 +217,7 @@
|
||||
compatible = "atmel,at91rm9200-ssc";
|
||||
reg = <0xfffbc000 0x4000>;
|
||||
interrupts = <14 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
adc0: adc@fffe0000 {
|
||||
|
@ -179,14 +179,14 @@
|
||||
compatible = "atmel,at91rm9200-ssc";
|
||||
reg = <0xfff98000 0x4000>;
|
||||
interrupts = <16 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssc1: ssc@fff9c000 {
|
||||
compatible = "atmel,at91rm9200-ssc";
|
||||
reg = <0xfff9c000 0x4000>;
|
||||
interrupts = <17 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
macb0: ethernet@fffbc000 {
|
||||
|
@ -232,14 +232,14 @@
|
||||
compatible = "atmel,at91sam9g45-ssc";
|
||||
reg = <0xfff9c000 0x4000>;
|
||||
interrupts = <16 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssc1: ssc@fffa0000 {
|
||||
compatible = "atmel,at91sam9g45-ssc";
|
||||
reg = <0xfffa0000 0x4000>;
|
||||
interrupts = <17 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
adc0: adc@fffb0000 {
|
||||
|
@ -92,7 +92,7 @@
|
||||
compatible = "atmel,at91sam9g45-ssc";
|
||||
reg = <0xf0010000 0x4000>;
|
||||
interrupts = <28 4 5>;
|
||||
status = "disable";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tcb0: timer@f8008000 {
|
||||
|
@ -162,7 +162,6 @@ static struct clock_event_device sp804_clockevent = {
|
||||
.set_mode = sp804_set_mode,
|
||||
.set_next_event = sp804_set_next_event,
|
||||
.rating = 300,
|
||||
.cpumask = cpu_all_mask,
|
||||
};
|
||||
|
||||
static struct irqaction sp804_timer_irq = {
|
||||
@ -185,6 +184,7 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
|
||||
clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
|
||||
evt->name = name;
|
||||
evt->irq = irq;
|
||||
evt->cpumask = cpu_possible_mask;
|
||||
|
||||
setup_irq(irq, &sp804_timer_irq);
|
||||
clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
|
||||
|
@ -63,7 +63,7 @@ static inline int pmu_to_irq(int pin)
|
||||
|
||||
static inline int irq_to_pmu(int irq)
|
||||
{
|
||||
if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
|
||||
if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
|
||||
return irq - IRQ_DOVE_PMU_START;
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -46,8 +46,20 @@ static void pmu_irq_ack(struct irq_data *d)
|
||||
int pin = irq_to_pmu(d->irq);
|
||||
u32 u;
|
||||
|
||||
/*
|
||||
* The PMU mask register is not RW0C: it is RW. This means that
|
||||
* the bits take whatever value is written to them; if you write
|
||||
* a '1', you will set the interrupt.
|
||||
*
|
||||
* Unfortunately this means there is NO race free way to clear
|
||||
* these interrupts.
|
||||
*
|
||||
* So, let's structure the code so that the window is as small as
|
||||
* possible.
|
||||
*/
|
||||
u = ~(1 << (pin & 31));
|
||||
writel(u, PMU_INTERRUPT_CAUSE);
|
||||
u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
|
||||
writel_relaxed(u, PMU_INTERRUPT_CAUSE);
|
||||
}
|
||||
|
||||
static struct irq_chip pmu_irq_chip = {
|
||||
|
@ -410,6 +410,7 @@ void __init ixp4xx_pci_preinit(void)
|
||||
* Enable the IO window to be way up high, at 0xfffffc00
|
||||
*/
|
||||
local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
|
||||
local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
|
||||
} else {
|
||||
printk("PCI: IXP4xx is target - No bus scan performed\n");
|
||||
}
|
||||
|
@ -67,15 +67,12 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
|
||||
.pfn = __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
|
||||
.length = IXP4XX_PCI_CFG_REGION_SIZE,
|
||||
.type = MT_DEVICE
|
||||
},
|
||||
#ifdef CONFIG_DEBUG_LL
|
||||
{ /* Debug UART mapping */
|
||||
.virtual = (unsigned long)IXP4XX_DEBUG_UART_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(IXP4XX_DEBUG_UART_BASE_PHYS),
|
||||
.length = IXP4XX_DEBUG_UART_REGION_SIZE,
|
||||
}, { /* Queue Manager */
|
||||
.virtual = (unsigned long)IXP4XX_QMGR_BASE_VIRT,
|
||||
.pfn = __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
|
||||
.length = IXP4XX_QMGR_REGION_SIZE,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
void __init ixp4xx_map_io(void)
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/pci.h>
|
||||
#include <asm/system_info.h>
|
||||
|
||||
#define SLOT_ETHA 0x0B /* IDSEL = AD21 */
|
||||
#define SLOT_ETHB 0x0C /* IDSEL = AD20 */
|
||||
@ -329,7 +330,7 @@ static struct platform_device device_hss_tab[] = {
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device *device_tab[6] __initdata = {
|
||||
static struct platform_device *device_tab[7] __initdata = {
|
||||
&device_flash, /* index 0 */
|
||||
};
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
#else
|
||||
mov \rp, #0
|
||||
#endif
|
||||
orr \rv, \rp, #0xff000000 @ virtual
|
||||
orr \rv, \rv, #0x00b00000
|
||||
orr \rv, \rp, #0xfe000000 @ virtual
|
||||
orr \rv, \rv, #0x00f00000
|
||||
orr \rp, \rp, #0xc8000000 @ physical
|
||||
.endm
|
||||
|
||||
|
@ -30,51 +30,43 @@
|
||||
*
|
||||
* 0x50000000 0x10000000 ioremap'd EXP BUS
|
||||
*
|
||||
* 0x6000000 0x00004000 ioremap'd QMgr
|
||||
* 0xC8000000 0x00013000 0xFEF00000 On-Chip Peripherals
|
||||
*
|
||||
* 0xC0000000 0x00001000 0xffbff000 PCI CFG
|
||||
* 0xC0000000 0x00001000 0xFEF13000 PCI CFG
|
||||
*
|
||||
* 0xC4000000 0x00001000 0xffbfe000 EXP CFG
|
||||
* 0xC4000000 0x00001000 0xFEF14000 EXP CFG
|
||||
*
|
||||
* 0xC8000000 0x00013000 0xffbeb000 On-Chip Peripherals
|
||||
* 0x60000000 0x00004000 0xFEF15000 QMgr
|
||||
*/
|
||||
|
||||
/*
|
||||
* Queue Manager
|
||||
*/
|
||||
#define IXP4XX_QMGR_BASE_PHYS (0x60000000)
|
||||
#define IXP4XX_QMGR_REGION_SIZE (0x00004000)
|
||||
#define IXP4XX_QMGR_BASE_PHYS 0x60000000
|
||||
#define IXP4XX_QMGR_BASE_VIRT IOMEM(0xFEF15000)
|
||||
#define IXP4XX_QMGR_REGION_SIZE 0x00004000
|
||||
|
||||
/*
|
||||
* Expansion BUS Configuration registers
|
||||
* Peripheral space, including debug UART. Must be section-aligned so that
|
||||
* it can be used with the low-level debug code.
|
||||
*/
|
||||
#define IXP4XX_EXP_CFG_BASE_PHYS (0xC4000000)
|
||||
#define IXP4XX_EXP_CFG_BASE_VIRT IOMEM(0xFFBFE000)
|
||||
#define IXP4XX_EXP_CFG_REGION_SIZE (0x00001000)
|
||||
#define IXP4XX_PERIPHERAL_BASE_PHYS 0xC8000000
|
||||
#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFEF00000)
|
||||
#define IXP4XX_PERIPHERAL_REGION_SIZE 0x00013000
|
||||
|
||||
/*
|
||||
* PCI Config registers
|
||||
*/
|
||||
#define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
|
||||
#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFFBFF000)
|
||||
#define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
|
||||
#define IXP4XX_PCI_CFG_BASE_PHYS 0xC0000000
|
||||
#define IXP4XX_PCI_CFG_BASE_VIRT IOMEM(0xFEF13000)
|
||||
#define IXP4XX_PCI_CFG_REGION_SIZE 0x00001000
|
||||
|
||||
/*
|
||||
* Peripheral space
|
||||
* Expansion BUS Configuration registers
|
||||
*/
|
||||
#define IXP4XX_PERIPHERAL_BASE_PHYS (0xC8000000)
|
||||
#define IXP4XX_PERIPHERAL_BASE_VIRT IOMEM(0xFFBEB000)
|
||||
#define IXP4XX_PERIPHERAL_REGION_SIZE (0x00013000)
|
||||
|
||||
/*
|
||||
* Debug UART
|
||||
*
|
||||
* This is basically a remap of UART1 into a region that is section
|
||||
* aligned so that it * can be used with the low-level debug code.
|
||||
*/
|
||||
#define IXP4XX_DEBUG_UART_BASE_PHYS (0xC8000000)
|
||||
#define IXP4XX_DEBUG_UART_BASE_VIRT IOMEM(0xffb00000)
|
||||
#define IXP4XX_DEBUG_UART_REGION_SIZE (0x00001000)
|
||||
#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000
|
||||
#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000
|
||||
#define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000
|
||||
|
||||
#define IXP4XX_EXP_CS0_OFFSET 0x00
|
||||
#define IXP4XX_EXP_CS1_OFFSET 0x04
|
||||
|
@ -86,7 +86,7 @@ void qmgr_release_queue(unsigned int queue);
|
||||
|
||||
static inline void qmgr_put_entry(unsigned int queue, u32 val)
|
||||
{
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
#if DEBUG_QMGR
|
||||
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
|
||||
|
||||
@ -99,7 +99,7 @@ static inline void qmgr_put_entry(unsigned int queue, u32 val)
|
||||
static inline u32 qmgr_get_entry(unsigned int queue)
|
||||
{
|
||||
u32 val;
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
val = __raw_readl(&qmgr_regs->acc[queue][0]);
|
||||
#if DEBUG_QMGR
|
||||
BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
|
||||
@ -112,14 +112,14 @@ static inline u32 qmgr_get_entry(unsigned int queue)
|
||||
|
||||
static inline int __qmgr_get_stat1(unsigned int queue)
|
||||
{
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
|
||||
>> ((queue & 7) << 2)) & 0xF;
|
||||
}
|
||||
|
||||
static inline int __qmgr_get_stat2(unsigned int queue)
|
||||
{
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
BUG_ON(queue >= HALF_QUEUES);
|
||||
return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
|
||||
>> ((queue & 0xF) << 1)) & 0x3;
|
||||
@ -145,7 +145,7 @@ static inline int qmgr_stat_empty(unsigned int queue)
|
||||
*/
|
||||
static inline int qmgr_stat_below_low_watermark(unsigned int queue)
|
||||
{
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
if (queue >= HALF_QUEUES)
|
||||
return (__raw_readl(&qmgr_regs->statne_h) >>
|
||||
(queue - HALF_QUEUES)) & 0x01;
|
||||
@ -172,7 +172,7 @@ static inline int qmgr_stat_above_high_watermark(unsigned int queue)
|
||||
*/
|
||||
static inline int qmgr_stat_full(unsigned int queue)
|
||||
{
|
||||
extern struct qmgr_regs __iomem *qmgr_regs;
|
||||
const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
if (queue >= HALF_QUEUES)
|
||||
return (__raw_readl(&qmgr_regs->statf_h) >>
|
||||
(queue - HALF_QUEUES)) & 0x01;
|
||||
|
@ -116,7 +116,11 @@
|
||||
/* NPE mailbox_status value for reset */
|
||||
#define RESET_MBOX_STAT 0x0000F0F0
|
||||
|
||||
const char *npe_names[] = { "NPE-A", "NPE-B", "NPE-C" };
|
||||
#define NPE_A_FIRMWARE "NPE-A"
|
||||
#define NPE_B_FIRMWARE "NPE-B"
|
||||
#define NPE_C_FIRMWARE "NPE-C"
|
||||
|
||||
const char *npe_names[] = { NPE_A_FIRMWARE, NPE_B_FIRMWARE, NPE_C_FIRMWARE };
|
||||
|
||||
#define print_npe(pri, npe, fmt, ...) \
|
||||
printk(pri "%s: " fmt, npe_name(npe), ## __VA_ARGS__)
|
||||
@ -724,6 +728,9 @@ module_exit(npe_cleanup_module);
|
||||
|
||||
MODULE_AUTHOR("Krzysztof Halasa");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_FIRMWARE(NPE_A_FIRMWARE);
|
||||
MODULE_FIRMWARE(NPE_B_FIRMWARE);
|
||||
MODULE_FIRMWARE(NPE_C_FIRMWARE);
|
||||
|
||||
EXPORT_SYMBOL(npe_names);
|
||||
EXPORT_SYMBOL(npe_running);
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <mach/qmgr.h>
|
||||
|
||||
struct qmgr_regs __iomem *qmgr_regs;
|
||||
static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
|
||||
static struct resource *mem_res;
|
||||
static spinlock_t qmgr_lock;
|
||||
static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
|
||||
@ -293,12 +293,6 @@ static int qmgr_init(void)
|
||||
if (mem_res == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
qmgr_regs = ioremap(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
|
||||
if (qmgr_regs == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto error_map;
|
||||
}
|
||||
|
||||
/* reset qmgr registers */
|
||||
for (i = 0; i < 4; i++) {
|
||||
__raw_writel(0x33333333, &qmgr_regs->stat1[i]);
|
||||
@ -347,8 +341,6 @@ static int qmgr_init(void)
|
||||
error_irq2:
|
||||
free_irq(IRQ_IXP4XX_QM1, NULL);
|
||||
error_irq:
|
||||
iounmap(qmgr_regs);
|
||||
error_map:
|
||||
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
|
||||
return err;
|
||||
}
|
||||
@ -359,7 +351,6 @@ static void qmgr_remove(void)
|
||||
free_irq(IRQ_IXP4XX_QM2, NULL);
|
||||
synchronize_irq(IRQ_IXP4XX_QM1);
|
||||
synchronize_irq(IRQ_IXP4XX_QM2);
|
||||
iounmap(qmgr_regs);
|
||||
release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
|
||||
}
|
||||
|
||||
@ -369,7 +360,6 @@ module_exit(qmgr_remove);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Krzysztof Halasa");
|
||||
|
||||
EXPORT_SYMBOL(qmgr_regs);
|
||||
EXPORT_SYMBOL(qmgr_set_irq);
|
||||
EXPORT_SYMBOL(qmgr_enable_irq);
|
||||
EXPORT_SYMBOL(qmgr_disable_irq);
|
||||
|
@ -207,14 +207,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
|
||||
* is operating as a root complex this needs to be switched to
|
||||
* PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
|
||||
* the device. Decoding setup is handled by the orion code.
|
||||
*/
|
||||
static void __devinit rc_pci_fixup(struct pci_dev *dev)
|
||||
{
|
||||
/*
|
||||
* Prevent enumeration of root complex.
|
||||
*/
|
||||
if (dev->bus->parent == NULL && dev->devfn == 0) {
|
||||
int i;
|
||||
|
||||
dev->class &= 0xff;
|
||||
dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
dev->resource[i].start = 0;
|
||||
dev->resource[i].end = 0;
|
||||
|
@ -89,7 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area)
|
||||
mov pc, lr
|
||||
|
||||
/*
|
||||
* cpu_arm926_switch_mm(pgd_phys, tsk)
|
||||
* cpu_v6_switch_mm(pgd_phys, tsk)
|
||||
*
|
||||
* Set the translation table base pointer to be pgd_phys
|
||||
*
|
||||
|
@ -473,12 +473,13 @@ int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
|
||||
pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
|
||||
chan->number, __func__, buf);
|
||||
|
||||
if (chan->end == NULL)
|
||||
if (chan->end == NULL) {
|
||||
pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
|
||||
chan->number, __func__, chan);
|
||||
|
||||
chan->end->next = buf;
|
||||
chan->end = buf;
|
||||
} else {
|
||||
chan->end->next = buf;
|
||||
chan->end = buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* if necessary, update the next buffer field */
|
||||
|
@ -392,7 +392,7 @@ __SYSCALL(367, sys_fanotify_init)
|
||||
__SYSCALL(368, compat_sys_fanotify_mark_wrapper)
|
||||
__SYSCALL(369, sys_prlimit64)
|
||||
__SYSCALL(370, sys_name_to_handle_at)
|
||||
__SYSCALL(371, sys_open_by_handle_at)
|
||||
__SYSCALL(371, compat_sys_open_by_handle_at)
|
||||
__SYSCALL(372, sys_clock_adjtime)
|
||||
__SYSCALL(373, sys_syncfs)
|
||||
|
||||
|
33
arch/c6x/include/asm/setup.h
Normal file
33
arch/c6x/include/asm/setup.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_C6X_SETUP_H
|
||||
#define _ASM_C6X_SETUP_H
|
||||
|
||||
#include <uapi/asm/setup.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern char c6x_command_line[COMMAND_LINE_SIZE];
|
||||
|
||||
extern int c6x_add_memory(phys_addr_t start, unsigned long size);
|
||||
|
||||
extern unsigned long ram_start;
|
||||
extern unsigned long ram_end;
|
||||
|
||||
extern int c6x_num_cores;
|
||||
extern unsigned int c6x_silicon_rev;
|
||||
extern unsigned int c6x_devstat;
|
||||
extern unsigned char c6x_fuse_mac[6];
|
||||
|
||||
extern void machine_init(unsigned long dt_ptr);
|
||||
extern void time_init(void);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* _ASM_C6X_SETUP_H */
|
@ -1,6 +1,8 @@
|
||||
# UAPI Header export list
|
||||
include include/uapi/asm-generic/Kbuild.asm
|
||||
|
||||
generic-y += kvm_para.h
|
||||
|
||||
header-y += byteorder.h
|
||||
header-y += kvm_para.h
|
||||
header-y += ptrace.h
|
||||
|
@ -1 +0,0 @@
|
||||
#include <asm-generic/kvm_para.h>
|
@ -1,33 +1,6 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_C6X_SETUP_H
|
||||
#define _ASM_C6X_SETUP_H
|
||||
#ifndef _UAPI_ASM_C6X_SETUP_H
|
||||
#define _UAPI_ASM_C6X_SETUP_H
|
||||
|
||||
#define COMMAND_LINE_SIZE 1024
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern char c6x_command_line[COMMAND_LINE_SIZE];
|
||||
|
||||
extern int c6x_add_memory(phys_addr_t start, unsigned long size);
|
||||
|
||||
extern unsigned long ram_start;
|
||||
extern unsigned long ram_end;
|
||||
|
||||
extern int c6x_num_cores;
|
||||
extern unsigned int c6x_silicon_rev;
|
||||
extern unsigned int c6x_devstat;
|
||||
extern unsigned char c6x_fuse_mac[6];
|
||||
|
||||
extern void machine_init(unsigned long dt_ptr);
|
||||
extern void time_init(void);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* _ASM_C6X_SETUP_H */
|
||||
#endif /* _UAPI_ASM_C6X_SETUP_H */
|
||||
|
@ -277,6 +277,8 @@ work_rescheduled:
|
||||
[A1] BNOP .S1 work_resched,5
|
||||
|
||||
work_notifysig:
|
||||
;; enable interrupts for do_notify_resume()
|
||||
UNMASK_INT B2
|
||||
B .S2 do_notify_resume
|
||||
LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag
|
||||
ADDKPC .S2 resume_userspace,B3,1
|
||||
@ -427,8 +429,7 @@ ENTRY(ret_from_kernel_execve)
|
||||
ENDPROC(ret_from_kernel_execve)
|
||||
|
||||
;;
|
||||
;; These are the interrupt handlers, responsible for calling __do_IRQ()
|
||||
;; int6 is used for syscalls (see _system_call entry)
|
||||
;; These are the interrupt handlers, responsible for calling c6x_do_IRQ()
|
||||
;;
|
||||
.macro SAVE_ALL_INT
|
||||
SAVE_ALL IRP,ITSR
|
||||
|
@ -111,7 +111,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
||||
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1))
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return rval;
|
||||
|
@ -95,7 +95,17 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
pte_t *ptep, pte_t pte,
|
||||
int dirty)
|
||||
{
|
||||
return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
|
||||
int changed = !pte_same(*ptep, pte);
|
||||
|
||||
if (changed) {
|
||||
set_pte_at(vma->vm_mm, addr, ptep, pte);
|
||||
/*
|
||||
* There could be some standard sized pages in there,
|
||||
* get them all.
|
||||
*/
|
||||
flush_tlb_range(vma, addr, addr + HPAGE_SIZE);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
|
@ -510,7 +510,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
|
||||
c->cputype = CPU_R3000A;
|
||||
__cpu_name[cpu] = "R3000A";
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
c->cputype = CPU_R3000;
|
||||
__cpu_name[cpu] = "R3000";
|
||||
|
@ -36,6 +36,11 @@ FEXPORT(ret_from_exception)
|
||||
FEXPORT(ret_from_irq)
|
||||
LONG_S s0, TI_REGS($28)
|
||||
FEXPORT(__ret_from_irq)
|
||||
/*
|
||||
* We can be coming here from a syscall done in the kernel space,
|
||||
* e.g. a failed kernel_execve().
|
||||
*/
|
||||
resume_userspace_check:
|
||||
LONG_L t0, PT_STATUS(sp) # returning to kernel mode?
|
||||
andi t0, t0, KU_USER
|
||||
beqz t0, resume_kernel
|
||||
@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and
|
||||
move a0, sp
|
||||
li a1, 0
|
||||
jal do_notify_resume # a2 already loaded
|
||||
j resume_userspace
|
||||
j resume_userspace_check
|
||||
|
||||
FEXPORT(syscall_exit_partial)
|
||||
local_irq_disable # make sure need_resched doesn't
|
||||
|
@ -397,14 +397,14 @@ EXPORT(sysn32_call_table)
|
||||
PTR sys_timerfd_create
|
||||
PTR compat_sys_timerfd_gettime /* 6285 */
|
||||
PTR compat_sys_timerfd_settime
|
||||
PTR sys_signalfd4
|
||||
PTR compat_sys_signalfd4
|
||||
PTR sys_eventfd2
|
||||
PTR sys_epoll_create1
|
||||
PTR sys_dup3 /* 6290 */
|
||||
PTR sys_pipe2
|
||||
PTR sys_inotify_init1
|
||||
PTR sys_preadv
|
||||
PTR sys_pwritev
|
||||
PTR compat_sys_preadv
|
||||
PTR compat_sys_pwritev
|
||||
PTR compat_sys_rt_tgsigqueueinfo /* 6295 */
|
||||
PTR sys_perf_event_open
|
||||
PTR sys_accept4
|
||||
|
@ -120,18 +120,11 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||
|
||||
if (cpu_context(cpu, mm) != 0) {
|
||||
unsigned long size, flags;
|
||||
int huge = is_vm_hugetlb_page(vma);
|
||||
|
||||
ENTER_CRITICAL(flags);
|
||||
if (huge) {
|
||||
start = round_down(start, HPAGE_SIZE);
|
||||
end = round_up(end, HPAGE_SIZE);
|
||||
size = (end - start) >> HPAGE_SHIFT;
|
||||
} else {
|
||||
start = round_down(start, PAGE_SIZE << 1);
|
||||
end = round_up(end, PAGE_SIZE << 1);
|
||||
size = (end - start) >> (PAGE_SHIFT + 1);
|
||||
}
|
||||
start = round_down(start, PAGE_SIZE << 1);
|
||||
end = round_up(end, PAGE_SIZE << 1);
|
||||
size = (end - start) >> (PAGE_SHIFT + 1);
|
||||
if (size <= current_cpu_data.tlbsize/2) {
|
||||
int oldpid = read_c0_entryhi();
|
||||
int newpid = cpu_asid(cpu, mm);
|
||||
@ -140,10 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
|
||||
int idx;
|
||||
|
||||
write_c0_entryhi(start | newpid);
|
||||
if (huge)
|
||||
start += HPAGE_SIZE;
|
||||
else
|
||||
start += (PAGE_SIZE << 1);
|
||||
start += (PAGE_SIZE << 1);
|
||||
mtc0_tlbw_hazard();
|
||||
tlb_probe();
|
||||
tlb_probe_hazard();
|
||||
|
@ -84,7 +84,6 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp;
|
||||
sigset_t set;
|
||||
stack_t st;
|
||||
|
||||
/*
|
||||
* Since we stacked the signal on a dword boundary,
|
||||
@ -104,11 +103,10 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
goto badframe;
|
||||
|
||||
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
|
||||
goto badframe;
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
do_sigaltstack(&st, NULL, regs->sp);
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return regs->gpr[11];
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
ENTRY_SAME(fork_wrapper)
|
||||
ENTRY_SAME(read)
|
||||
ENTRY_SAME(write)
|
||||
ENTRY_SAME(open) /* 5 */
|
||||
ENTRY_COMP(open) /* 5 */
|
||||
ENTRY_SAME(close)
|
||||
ENTRY_SAME(waitpid)
|
||||
ENTRY_SAME(creat)
|
||||
|
@ -28,7 +28,7 @@ ENTRY(sys32_open_wrapper)
|
||||
llgtr %r2,%r2 # const char *
|
||||
lgfr %r3,%r3 # int
|
||||
lgfr %r4,%r4 # int
|
||||
jg sys_open # branch to system call
|
||||
jg compat_sys_open # branch to system call
|
||||
|
||||
ENTRY(sys32_close_wrapper)
|
||||
llgfr %r2,%r2 # unsigned int
|
||||
|
@ -148,7 +148,6 @@ score_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
sigset_t set;
|
||||
stack_t st;
|
||||
int sig;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
@ -168,12 +167,10 @@ score_rt_sigreturn(struct pt_regs *regs)
|
||||
else if (sig)
|
||||
force_sig(sig, current);
|
||||
|
||||
if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
|
||||
goto badframe;
|
||||
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
|
||||
if (do_sigaltstack(&frame->rs_uc.uc_stack, NULL, regs->regs[0]) == -EFAULT)
|
||||
goto badframe;
|
||||
regs->is_syscall = 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
|
@ -347,7 +347,6 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
|
||||
{
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
|
||||
sigset_t set;
|
||||
stack_t __user st;
|
||||
long long ret;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
@ -365,11 +364,10 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
|
||||
goto badframe;
|
||||
regs->pc -= 4;
|
||||
|
||||
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
|
||||
goto badframe;
|
||||
/* It is more difficult to avoid calling this function than to
|
||||
call it and ignore errors. */
|
||||
do_sigaltstack(&st, NULL, REF_REG_SP);
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, REF_REG_SP) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return (int) ret;
|
||||
|
||||
|
@ -81,18 +81,18 @@ static void usage(void)
|
||||
|
||||
static int start_line(const char *line)
|
||||
{
|
||||
if (strcmp(line + 8, " T _start\n") == 0)
|
||||
if (strcmp(line + 10, " _start\n") == 0)
|
||||
return 1;
|
||||
else if (strcmp(line + 16, " T _start\n") == 0)
|
||||
else if (strcmp(line + 18, " _start\n") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int end_line(const char *line)
|
||||
{
|
||||
if (strcmp(line + 8, " A _end\n") == 0)
|
||||
if (strcmp(line + 10, " _end\n") == 0)
|
||||
return 1;
|
||||
else if (strcmp (line + 16, " A _end\n") == 0)
|
||||
else if (strcmp (line + 18, " _end\n") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -100,8 +100,8 @@ static int end_line(const char *line)
|
||||
/*
|
||||
* Find address for start and end in System.map.
|
||||
* The file looks like this:
|
||||
* f0004000 T _start
|
||||
* f0379f79 A _end
|
||||
* f0004000 ... _start
|
||||
* f0379f79 ... _end
|
||||
* 1234567890123456
|
||||
* ^coloumn 1
|
||||
* There is support for 64 bit addresses too.
|
||||
|
@ -47,7 +47,7 @@ STUB: sra REG1, 0, REG1; \
|
||||
sra REG4, 0, REG4
|
||||
|
||||
SIGN1(sys32_exit, sparc_exit, %o0)
|
||||
SIGN1(sys32_exit_group, sys_exit_group, %o0)
|
||||
SIGN1(sys32_exit_group, sparc_exit_group, %o0)
|
||||
SIGN1(sys32_wait4, compat_sys_wait4, %o2)
|
||||
SIGN1(sys32_creat, sys_creat, %o1)
|
||||
SIGN1(sys32_mknod, sys_mknod, %o1)
|
||||
|
@ -118,10 +118,20 @@ ret_from_syscall:
|
||||
ba,pt %xcc, ret_sys_call
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I0], %o0
|
||||
|
||||
.globl sparc_exit_group
|
||||
.type sparc_exit_group,#function
|
||||
sparc_exit_group:
|
||||
sethi %hi(sys_exit_group), %g7
|
||||
ba,pt %xcc, 1f
|
||||
or %g7, %lo(sys_exit_group), %g7
|
||||
.size sparc_exit_group,.-sparc_exit_group
|
||||
|
||||
.globl sparc_exit
|
||||
.type sparc_exit,#function
|
||||
sparc_exit:
|
||||
rdpr %pstate, %g2
|
||||
sethi %hi(sys_exit), %g7
|
||||
or %g7, %lo(sys_exit), %g7
|
||||
1: rdpr %pstate, %g2
|
||||
wrpr %g2, PSTATE_IE, %pstate
|
||||
rdpr %otherwin, %g1
|
||||
rdpr %cansave, %g3
|
||||
@ -129,7 +139,7 @@ sparc_exit:
|
||||
wrpr %g3, 0x0, %cansave
|
||||
wrpr %g0, 0x0, %otherwin
|
||||
wrpr %g2, 0x0, %pstate
|
||||
ba,pt %xcc, sys_exit
|
||||
jmpl %g7, %g0
|
||||
stb %g0, [%g6 + TI_WSAVED]
|
||||
.size sparc_exit,.-sparc_exit
|
||||
|
||||
|
@ -133,7 +133,7 @@ sys_call_table:
|
||||
/*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents
|
||||
.word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr
|
||||
/*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall
|
||||
.word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname
|
||||
.word sys_setpgid, sys_fremovexattr, sys_tkill, sparc_exit_group, sys_newuname
|
||||
/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl
|
||||
.word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask
|
||||
/*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
|
||||
|
@ -32,13 +32,14 @@ void flush_thread(void)
|
||||
"err = %d\n", ret);
|
||||
force_sig(SIGKILL, current);
|
||||
}
|
||||
get_safe_registers(current_pt_regs()->regs.gp,
|
||||
current_pt_regs()->regs.fp);
|
||||
|
||||
__switch_mm(¤t->mm->context.id);
|
||||
}
|
||||
|
||||
void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
|
||||
{
|
||||
get_safe_registers(regs->regs.gp, regs->regs.fp);
|
||||
PT_REGS_IP(regs) = eip;
|
||||
PT_REGS_SP(regs) = esp;
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
|
@ -12,6 +12,7 @@ header-y += mce.h
|
||||
header-y += msr-index.h
|
||||
header-y += msr.h
|
||||
header-y += mtrr.h
|
||||
header-y += perf_regs.h
|
||||
header-y += posix_types_32.h
|
||||
header-y += posix_types_64.h
|
||||
header-y += posix_types_x32.h
|
||||
@ -19,8 +20,10 @@ header-y += prctl.h
|
||||
header-y += processor-flags.h
|
||||
header-y += ptrace-abi.h
|
||||
header-y += sigcontext32.h
|
||||
header-y += svm.h
|
||||
header-y += ucontext.h
|
||||
header-y += vm86.h
|
||||
header-y += vmx.h
|
||||
header-y += vsyscall.h
|
||||
|
||||
genhdr-y += unistd_32.h
|
||||
|
@ -399,14 +399,17 @@ static inline void drop_init_fpu(struct task_struct *tsk)
|
||||
typedef struct { int preload; } fpu_switch_t;
|
||||
|
||||
/*
|
||||
* FIXME! We could do a totally lazy restore, but we need to
|
||||
* add a per-cpu "this was the task that last touched the FPU
|
||||
* on this CPU" variable, and the task needs to have a "I last
|
||||
* touched the FPU on this CPU" and check them.
|
||||
* Must be run with preemption disabled: this clears the fpu_owner_task,
|
||||
* on this CPU.
|
||||
*
|
||||
* We don't do that yet, so "fpu_lazy_restore()" always returns
|
||||
* false, but some day..
|
||||
* This will disable any lazy FPU state restore of the current FPU state,
|
||||
* but if the current thread owns the FPU, it will still be saved by.
|
||||
*/
|
||||
static inline void __cpu_disable_lazy_restore(unsigned int cpu)
|
||||
{
|
||||
per_cpu(fpu_owner_task, cpu) = NULL;
|
||||
}
|
||||
|
||||
static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
|
||||
{
|
||||
return new == this_cpu_read_stable(fpu_owner_task) &&
|
||||
|
@ -292,8 +292,8 @@ default_entry:
|
||||
* be using the global pages.
|
||||
*
|
||||
* NOTE! If we are on a 486 we may have no cr4 at all!
|
||||
* Specifically, cr4 exists if and only if CPUID exists,
|
||||
* which in turn exists if and only if EFLAGS.ID exists.
|
||||
* Specifically, cr4 exists if and only if CPUID exists
|
||||
* and has flags other than the FPU flag set.
|
||||
*/
|
||||
movl $X86_EFLAGS_ID,%ecx
|
||||
pushl %ecx
|
||||
@ -308,6 +308,11 @@ default_entry:
|
||||
testl %ecx,%eax
|
||||
jz 6f # No ID flag = no CPUID = no CR4
|
||||
|
||||
movl $1,%eax
|
||||
cpuid
|
||||
andl $~1,%edx # Ignore CPUID.FPU
|
||||
jz 6f # No flags or only CPUID.FPU = no CR4
|
||||
|
||||
movl pa(mmu_cr4_features),%eax
|
||||
movl %eax,%cr4
|
||||
|
||||
|
@ -1541,6 +1541,13 @@ void syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
bool step;
|
||||
|
||||
/*
|
||||
* We may come here right after calling schedule_user()
|
||||
* or do_notify_resume(), in which case we can be in RCU
|
||||
* user mode.
|
||||
*/
|
||||
rcu_user_exit();
|
||||
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
|
||||
|
@ -68,6 +68,8 @@
|
||||
#include <asm/mwait.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/fpu-internal.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/uv/uv.h>
|
||||
#include <linux/mc146818rtc.h>
|
||||
@ -818,6 +820,9 @@ int __cpuinit native_cpu_up(unsigned int cpu, struct task_struct *tidle)
|
||||
|
||||
per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
|
||||
|
||||
/* the FPU context is blank, nobody can own it */
|
||||
__cpu_disable_lazy_restore(cpu);
|
||||
|
||||
err = do_boot_cpu(apicid, cpu, tidle);
|
||||
if (err) {
|
||||
pr_debug("do_boot_cpu failed %d\n", err);
|
||||
|
@ -426,8 +426,7 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt)
|
||||
_ASM_EXTABLE(1b, 3b) \
|
||||
: "=m" ((ctxt)->eflags), "=&r" (_tmp), \
|
||||
"+a" (*rax), "+d" (*rdx), "+qm"(_ex) \
|
||||
: "i" (EFLAGS_MASK), "m" ((ctxt)->src.val), \
|
||||
"a" (*rax), "d" (*rdx)); \
|
||||
: "i" (EFLAGS_MASK), "m" ((ctxt)->src.val)); \
|
||||
} while (0)
|
||||
|
||||
/* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
|
||||
|
@ -1961,6 +1961,7 @@ static int __devinit ucode_init (loader_block * lb, amb_dev * dev) {
|
||||
res = loader_verify(lb, dev, rec);
|
||||
if (res)
|
||||
break;
|
||||
rec = ihex_next_binrec(rec);
|
||||
}
|
||||
release_firmware(fw);
|
||||
if (!res)
|
||||
|
@ -127,12 +127,12 @@ config HW_RANDOM_VIA
|
||||
If unsure, say Y.
|
||||
|
||||
config HW_RANDOM_IXP4XX
|
||||
tristate "Intel IXP4xx NPU HW Random Number Generator support"
|
||||
tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
|
||||
depends on HW_RANDOM && ARCH_IXP4XX
|
||||
default HW_RANDOM
|
||||
---help---
|
||||
This driver provides kernel-side support for the Random
|
||||
Number Generator hardware found on the Intel IXP4xx NPU.
|
||||
This driver provides kernel-side support for the Pseudo-Random
|
||||
Number Generator hardware found on the Intel IXP45x/46x NPU.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ixp4xx-rng.
|
||||
|
@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void)
|
||||
void __iomem * rng_base;
|
||||
int err;
|
||||
|
||||
if (!cpu_is_ixp46x()) /* includes IXP455 */
|
||||
return -ENOSYS;
|
||||
|
||||
rng_base = ioremap(0x70002100, 4);
|
||||
if (!rng_base)
|
||||
return -ENOMEM;
|
||||
@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init);
|
||||
module_exit(ixp4xx_rng_exit);
|
||||
|
||||
MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
|
||||
MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx");
|
||||
MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -285,7 +285,7 @@ static long raw_ctl_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
|
||||
static const struct file_operations raw_fops = {
|
||||
.read = do_sync_read,
|
||||
.aio_read = blkdev_aio_read,
|
||||
.aio_read = generic_file_aio_read,
|
||||
.write = do_sync_write,
|
||||
.aio_write = blkdev_aio_write,
|
||||
.fsync = blkdev_fsync,
|
||||
|
@ -224,7 +224,7 @@ config CRYPTO_DEV_TALITOS
|
||||
|
||||
config CRYPTO_DEV_IXP4XX
|
||||
tristate "Driver for IXP4xx crypto hardware acceleration"
|
||||
depends on ARCH_IXP4XX
|
||||
depends on ARCH_IXP4XX && IXP4XX_QMGR && IXP4XX_NPE
|
||||
select CRYPTO_DES
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_AUTHENC
|
||||
|
@ -750,12 +750,12 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
|
||||
}
|
||||
if (cipher_cfg & MOD_AES) {
|
||||
switch (key_len) {
|
||||
case 16: keylen_cfg = MOD_AES128 | KEYLEN_128; break;
|
||||
case 24: keylen_cfg = MOD_AES192 | KEYLEN_192; break;
|
||||
case 32: keylen_cfg = MOD_AES256 | KEYLEN_256; break;
|
||||
default:
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
case 16: keylen_cfg = MOD_AES128; break;
|
||||
case 24: keylen_cfg = MOD_AES192; break;
|
||||
case 32: keylen_cfg = MOD_AES256; break;
|
||||
default:
|
||||
*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
cipher_cfg |= keylen_cfg;
|
||||
} else if (cipher_cfg & MOD_3DES) {
|
||||
|
@ -416,10 +416,18 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
|
||||
dimm->cschannel = chn;
|
||||
|
||||
/* Increment csrow location */
|
||||
row++;
|
||||
if (row == tot_csrows) {
|
||||
row = 0;
|
||||
if (layers[0].is_virt_csrow) {
|
||||
chn++;
|
||||
if (chn == tot_channels) {
|
||||
chn = 0;
|
||||
row++;
|
||||
}
|
||||
} else {
|
||||
row++;
|
||||
if (row == tot_csrows) {
|
||||
row = 0;
|
||||
chn++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increment dimm location */
|
||||
|
@ -197,8 +197,8 @@ static const char *ferr_fat_fbd_name[] = {
|
||||
[0] = "Memory Write error on non-redundant retry or "
|
||||
"FBD configuration Write error on retry",
|
||||
};
|
||||
#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28))
|
||||
#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
|
||||
#define GET_FBD_FAT_IDX(fbderr) (((fbderr) >> 28) & 3)
|
||||
#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 22))
|
||||
|
||||
#define FERR_NF_FBD 0xa0
|
||||
static const char *ferr_nf_fbd_name[] = {
|
||||
@ -225,7 +225,7 @@ static const char *ferr_nf_fbd_name[] = {
|
||||
[1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
|
||||
[0] = "Uncorrectable Data ECC on Replay",
|
||||
};
|
||||
#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
|
||||
#define GET_FBD_NF_IDX(fbderr) (((fbderr) >> 28) & 3)
|
||||
#define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
|
||||
(1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
|
||||
(1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
|
||||
@ -464,7 +464,7 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
|
||||
errnum = find_first_bit(&errors,
|
||||
ARRAY_SIZE(ferr_nf_fbd_name));
|
||||
specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
|
||||
branch = (GET_FBD_FAT_IDX(error_reg) == 2) ? 1 : 0;
|
||||
branch = (GET_FBD_NF_IDX(error_reg) == 2) ? 1 : 0;
|
||||
|
||||
pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
|
||||
REDMEMA, &syndrome);
|
||||
|
@ -816,7 +816,7 @@ static ssize_t i7core_inject_store_##param( \
|
||||
struct device_attribute *mattr, \
|
||||
const char *data, size_t count) \
|
||||
{ \
|
||||
struct mem_ctl_info *mci = to_mci(dev); \
|
||||
struct mem_ctl_info *mci = dev_get_drvdata(dev); \
|
||||
struct i7core_pvt *pvt; \
|
||||
long value; \
|
||||
int rc; \
|
||||
@ -845,7 +845,7 @@ static ssize_t i7core_inject_show_##param( \
|
||||
struct device_attribute *mattr, \
|
||||
char *data) \
|
||||
{ \
|
||||
struct mem_ctl_info *mci = to_mci(dev); \
|
||||
struct mem_ctl_info *mci = dev_get_drvdata(dev); \
|
||||
struct i7core_pvt *pvt; \
|
||||
\
|
||||
pvt = mci->pvt_info; \
|
||||
@ -1052,7 +1052,7 @@ static ssize_t i7core_show_counter_##param( \
|
||||
struct device_attribute *mattr, \
|
||||
char *data) \
|
||||
{ \
|
||||
struct mem_ctl_info *mci = to_mci(dev); \
|
||||
struct mem_ctl_info *mci = dev_get_drvdata(dev); \
|
||||
struct i7core_pvt *pvt = mci->pvt_info; \
|
||||
\
|
||||
edac_dbg(1, "\n"); \
|
||||
|
@ -370,10 +370,6 @@ static enum dev_type i82975x_dram_type(void __iomem *mch_window, int rank)
|
||||
static void i82975x_init_csrows(struct mem_ctl_info *mci,
|
||||
struct pci_dev *pdev, void __iomem *mch_window)
|
||||
{
|
||||
static const char *labels[4] = {
|
||||
"DIMM A1", "DIMM A2",
|
||||
"DIMM B1", "DIMM B2"
|
||||
};
|
||||
struct csrow_info *csrow;
|
||||
unsigned long last_cumul_size;
|
||||
u8 value;
|
||||
@ -423,9 +419,10 @@ static void i82975x_init_csrows(struct mem_ctl_info *mci,
|
||||
dimm = mci->csrows[index]->channels[chan]->dimm;
|
||||
|
||||
dimm->nr_pages = nr_pages / csrow->nr_channels;
|
||||
strncpy(csrow->channels[chan]->dimm->label,
|
||||
labels[(index >> 1) + (chan * 2)],
|
||||
EDAC_MC_LABEL_LEN);
|
||||
|
||||
snprintf(csrow->channels[chan]->dimm->label, EDAC_MC_LABEL_LEN, "DIMM %c%d",
|
||||
(chan == 0) ? 'A' : 'B',
|
||||
index);
|
||||
dimm->grain = 1 << 7; /* 128Byte cache-line resolution */
|
||||
dimm->dtype = i82975x_dram_type(mch_window, index);
|
||||
dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */
|
||||
|
@ -226,6 +226,12 @@ static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
|
||||
* already updated or not by exynos_drm_encoder_dpms function.
|
||||
*/
|
||||
exynos_encoder->updated = true;
|
||||
|
||||
/*
|
||||
* In case of setcrtc, there is no way to update encoder's dpms
|
||||
* so update it here.
|
||||
*/
|
||||
exynos_encoder->dpms = DRM_MODE_DPMS_ON;
|
||||
}
|
||||
|
||||
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
|
||||
@ -507,6 +513,6 @@ void exynos_drm_encoder_plane_disable(struct drm_encoder *encoder, void *data)
|
||||
* because the setting for disabling the overlay will be updated
|
||||
* at vsync.
|
||||
*/
|
||||
if (overlay_ops->wait_for_vblank)
|
||||
if (overlay_ops && overlay_ops->wait_for_vblank)
|
||||
overlay_ops->wait_for_vblank(manager->dev);
|
||||
}
|
||||
|
@ -87,7 +87,8 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
|
||||
|
||||
dev->mode_config.fb_base = (resource_size_t)buffer->dma_addr;
|
||||
fbi->screen_base = buffer->kvaddr + offset;
|
||||
fbi->fix.smem_start = (unsigned long)(buffer->dma_addr + offset);
|
||||
fbi->fix.smem_start = (unsigned long)(page_to_phys(buffer->pages[0]) +
|
||||
offset);
|
||||
fbi->screen_size = size;
|
||||
fbi->fix.smem_len = size;
|
||||
|
||||
|
@ -61,11 +61,11 @@ struct fimd_driver_data {
|
||||
unsigned int timing_base;
|
||||
};
|
||||
|
||||
struct fimd_driver_data exynos4_fimd_driver_data = {
|
||||
static struct fimd_driver_data exynos4_fimd_driver_data = {
|
||||
.timing_base = 0x0,
|
||||
};
|
||||
|
||||
struct fimd_driver_data exynos5_fimd_driver_data = {
|
||||
static struct fimd_driver_data exynos5_fimd_driver_data = {
|
||||
.timing_base = 0x20000,
|
||||
};
|
||||
|
||||
|
@ -204,7 +204,6 @@ exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
return ret;
|
||||
|
||||
plane->crtc = crtc;
|
||||
plane->fb = crtc->fb;
|
||||
|
||||
exynos_plane_commit(plane);
|
||||
exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
|
||||
|
@ -1796,7 +1796,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
|
||||
*/
|
||||
mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
|
||||
gfp = mapping_gfp_mask(mapping);
|
||||
gfp |= __GFP_NORETRY | __GFP_NOWARN;
|
||||
gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
|
||||
gfp &= ~(__GFP_IO | __GFP_WAIT);
|
||||
for_each_sg(st->sgl, sg, page_count, i) {
|
||||
page = shmem_read_mapping_page_gfp(mapping, i, gfp);
|
||||
@ -1809,7 +1809,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
|
||||
* our own buffer, now let the real VM do its job and
|
||||
* go down in flames if truly OOM.
|
||||
*/
|
||||
gfp &= ~(__GFP_NORETRY | __GFP_NOWARN);
|
||||
gfp &= ~(__GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD);
|
||||
gfp |= __GFP_IO | __GFP_WAIT;
|
||||
|
||||
i915_gem_shrink_all(dev_priv);
|
||||
@ -1817,7 +1817,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
|
||||
if (IS_ERR(page))
|
||||
goto err_pages;
|
||||
|
||||
gfp |= __GFP_NORETRY | __GFP_NOWARN;
|
||||
gfp |= __GFP_NORETRY | __GFP_NOWARN | __GFP_NO_KSWAPD;
|
||||
gfp &= ~(__GFP_IO | __GFP_WAIT);
|
||||
}
|
||||
|
||||
|
@ -499,12 +499,8 @@ parse_edp(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
|
||||
|
||||
edp = find_section(bdb, BDB_EDP);
|
||||
if (!edp) {
|
||||
if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support) {
|
||||
DRM_DEBUG_KMS("No eDP BDB found but eDP panel "
|
||||
"supported, assume %dbpp panel color "
|
||||
"depth.\n",
|
||||
dev_priv->edp.bpp);
|
||||
}
|
||||
if (SUPPORTS_EDP(dev_priv->dev) && dev_priv->edp.support)
|
||||
DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -657,9 +653,6 @@ init_vbt_defaults(struct drm_i915_private *dev_priv)
|
||||
dev_priv->lvds_use_ssc = 1;
|
||||
dev_priv->lvds_ssc_freq = intel_bios_ssc_frequency(dev, 1);
|
||||
DRM_DEBUG_KMS("Set default to SSC at %dMHz\n", dev_priv->lvds_ssc_freq);
|
||||
|
||||
/* eDP data */
|
||||
dev_priv->edp.bpp = 18;
|
||||
}
|
||||
|
||||
static int __init intel_no_opregion_vbt_callback(const struct dmi_system_id *id)
|
||||
|
@ -3845,7 +3845,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc,
|
||||
/* Use VBT settings if we have an eDP panel */
|
||||
unsigned int edp_bpc = dev_priv->edp.bpp / 3;
|
||||
|
||||
if (edp_bpc < display_bpc) {
|
||||
if (edp_bpc && edp_bpc < display_bpc) {
|
||||
DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc);
|
||||
display_bpc = edp_bpc;
|
||||
}
|
||||
|
@ -2373,15 +2373,9 @@ int intel_enable_rc6(const struct drm_device *dev)
|
||||
if (i915_enable_rc6 >= 0)
|
||||
return i915_enable_rc6;
|
||||
|
||||
if (INTEL_INFO(dev)->gen == 5) {
|
||||
#ifdef CONFIG_INTEL_IOMMU
|
||||
/* Disable rc6 on ilk if VT-d is on. */
|
||||
if (intel_iommu_gfx_mapped)
|
||||
return false;
|
||||
#endif
|
||||
DRM_DEBUG_DRIVER("Ironlake: only RC6 available\n");
|
||||
return INTEL_RC6_ENABLE;
|
||||
}
|
||||
/* Disable RC6 on Ironlake */
|
||||
if (INTEL_INFO(dev)->gen == 5)
|
||||
return 0;
|
||||
|
||||
if (IS_HASWELL(dev)) {
|
||||
DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
|
||||
|
@ -2201,7 +2201,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
intel_sdvo->is_hdmi = true;
|
||||
}
|
||||
intel_sdvo->base.cloneable = true;
|
||||
|
||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
||||
if (intel_sdvo->is_hdmi)
|
||||
@ -2232,7 +2231,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type)
|
||||
|
||||
intel_sdvo->is_tv = true;
|
||||
intel_sdvo->base.needs_tv_clock = true;
|
||||
intel_sdvo->base.cloneable = false;
|
||||
|
||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
||||
|
||||
@ -2275,8 +2273,6 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1;
|
||||
}
|
||||
|
||||
intel_sdvo->base.cloneable = true;
|
||||
|
||||
intel_sdvo_connector_init(intel_sdvo_connector,
|
||||
intel_sdvo);
|
||||
return true;
|
||||
@ -2307,9 +2303,6 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
|
||||
}
|
||||
|
||||
/* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
|
||||
intel_sdvo->base.cloneable = false;
|
||||
|
||||
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
|
||||
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
|
||||
goto err;
|
||||
@ -2721,6 +2714,16 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
||||
goto err_output;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cloning SDVO with anything is often impossible, since the SDVO
|
||||
* encoder can request a special input timing mode. And even if that's
|
||||
* not the case we have evidence that cloning a plain unscaled mode with
|
||||
* VGA doesn't really work. Furthermore the cloning flags are way too
|
||||
* simplistic anyway to express such constraints, so just give up on
|
||||
* cloning for SDVO encoders.
|
||||
*/
|
||||
intel_sdvo->base.cloneable = false;
|
||||
|
||||
/* Only enable the hotplug irq if we need it, to work around noisy
|
||||
* hotplug lines.
|
||||
*/
|
||||
|
@ -1696,42 +1696,22 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
||||
return ATOM_PPLL2;
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else if (ASIC_IS_AVIVO(rdev)) {
|
||||
/* in DP mode, the DP ref clock can come from either PPLL
|
||||
* depending on the asic:
|
||||
* DCE3: PPLL1 or PPLL2
|
||||
*/
|
||||
if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
|
||||
/* use the same PPLL for all DP monitors */
|
||||
pll = radeon_get_shared_dp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
} else {
|
||||
/* use the same PPLL for all monitors with the same clock */
|
||||
pll = radeon_get_shared_nondp_ppll(crtc);
|
||||
if (pll != ATOM_PPLL_INVALID)
|
||||
return pll;
|
||||
}
|
||||
/* all other cases */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
/* the order shouldn't matter here, but we probably
|
||||
* need this until we have atomic modeset
|
||||
*/
|
||||
if (rdev->flags & RADEON_IS_IGP) {
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
} else {
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL1)))
|
||||
return ATOM_PPLL1;
|
||||
}
|
||||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else {
|
||||
/* on pre-R5xx asics, the crtc to pll mapping is hardcoded */
|
||||
/* some atombios (observed in some DCE2/DCE3) code have a bug,
|
||||
* the matching btw pll and crtc is done through
|
||||
* PCLK_CRTC[1|2]_CNTL (0x480/0x484) but atombios code use the
|
||||
* pll (1 or 2) to select which register to write. ie if using
|
||||
* pll1 it will use PCLK_CRTC1_CNTL (0x480) and if using pll2
|
||||
* it will use PCLK_CRTC2_CNTL (0x484), it then use crtc id to
|
||||
* choose which value to write. Which is reverse order from
|
||||
* register logic. So only case that works is when pllid is
|
||||
* same as crtcid or when both pll and crtc are enabled and
|
||||
* both use same clock.
|
||||
*
|
||||
* So just return crtc id as if crtc and pll were hard linked
|
||||
* together even if they aren't
|
||||
*/
|
||||
return radeon_crtc->crtc_id;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
|
||||
static bool matrix_keypad_map_key(struct input_dev *input_dev,
|
||||
@ -161,3 +162,5 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(matrix_keypad_build_keymap);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -963,7 +963,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||
struct r1conf *conf = mddev->private;
|
||||
struct bio *bio;
|
||||
|
||||
if (from_schedule) {
|
||||
if (from_schedule || current->bio_list) {
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
bio_list_merge(&conf->pending_bio_list, &plug->pending);
|
||||
conf->pending_count += plug->pending_cnt;
|
||||
|
@ -1069,7 +1069,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||
struct r10conf *conf = mddev->private;
|
||||
struct bio *bio;
|
||||
|
||||
if (from_schedule) {
|
||||
if (from_schedule || current->bio_list) {
|
||||
spin_lock_irq(&conf->device_lock);
|
||||
bio_list_merge(&conf->pending_bio_list, &plug->pending);
|
||||
conf->pending_count += plug->pending_cnt;
|
||||
|
@ -300,15 +300,15 @@ static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32
|
||||
{
|
||||
u32 m_div, clk_sel;
|
||||
|
||||
dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
|
||||
intp->quartz);
|
||||
|
||||
if (intp == NULL)
|
||||
return STV0900_INVALID_HANDLE;
|
||||
|
||||
if (intp->errs)
|
||||
return STV0900_I2C_ERROR;
|
||||
|
||||
dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
|
||||
intp->quartz);
|
||||
|
||||
clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
|
||||
m_div = ((clk_sel * mclk) / intp->quartz) - 1;
|
||||
stv0900_write_bits(intp, F0900_M_DIV, m_div);
|
||||
|
@ -53,8 +53,7 @@ MODULE_LICENSE("GPL");
|
||||
/* ADV7604 system clock frequency */
|
||||
#define ADV7604_fsc (28636360)
|
||||
|
||||
#define DIGITAL_INPUT ((state->prim_mode == ADV7604_PRIM_MODE_HDMI_COMP) || \
|
||||
(state->prim_mode == ADV7604_PRIM_MODE_HDMI_GR))
|
||||
#define DIGITAL_INPUT (state->mode == ADV7604_MODE_HDMI)
|
||||
|
||||
/*
|
||||
**********************************************************************
|
||||
@ -68,7 +67,7 @@ struct adv7604_state {
|
||||
struct v4l2_subdev sd;
|
||||
struct media_pad pad;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
enum adv7604_prim_mode prim_mode;
|
||||
enum adv7604_mode mode;
|
||||
struct v4l2_dv_timings timings;
|
||||
u8 edid[256];
|
||||
unsigned edid_blocks;
|
||||
@ -77,6 +76,7 @@ struct adv7604_state {
|
||||
struct workqueue_struct *work_queues;
|
||||
struct delayed_work delayed_work_enable_hotplug;
|
||||
bool connector_hdmi;
|
||||
bool restart_stdi_once;
|
||||
|
||||
/* i2c clients */
|
||||
struct i2c_client *i2c_avlink;
|
||||
@ -106,7 +106,6 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
|
||||
V4L2_DV_BT_CEA_720X576P50,
|
||||
V4L2_DV_BT_CEA_1280X720P24,
|
||||
V4L2_DV_BT_CEA_1280X720P25,
|
||||
V4L2_DV_BT_CEA_1280X720P30,
|
||||
V4L2_DV_BT_CEA_1280X720P50,
|
||||
V4L2_DV_BT_CEA_1280X720P60,
|
||||
V4L2_DV_BT_CEA_1920X1080P24,
|
||||
@ -115,6 +114,7 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
|
||||
V4L2_DV_BT_CEA_1920X1080P50,
|
||||
V4L2_DV_BT_CEA_1920X1080P60,
|
||||
|
||||
/* sorted by DMT ID */
|
||||
V4L2_DV_BT_DMT_640X350P85,
|
||||
V4L2_DV_BT_DMT_640X400P85,
|
||||
V4L2_DV_BT_DMT_720X400P85,
|
||||
@ -164,6 +164,89 @@ static const struct v4l2_dv_timings adv7604_timings[] = {
|
||||
{ },
|
||||
};
|
||||
|
||||
struct adv7604_video_standards {
|
||||
struct v4l2_dv_timings timings;
|
||||
u8 vid_std;
|
||||
u8 v_freq;
|
||||
};
|
||||
|
||||
/* sorted by number of lines */
|
||||
static const struct adv7604_video_standards adv7604_prim_mode_comp[] = {
|
||||
/* { V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 }, TODO flickering */
|
||||
{ V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
|
||||
{ V4L2_DV_BT_CEA_1280X720P50, 0x19, 0x01 },
|
||||
{ V4L2_DV_BT_CEA_1280X720P60, 0x19, 0x00 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
|
||||
/* TODO add 1920x1080P60_RB (CVT timing) */
|
||||
{ },
|
||||
};
|
||||
|
||||
/* sorted by number of lines */
|
||||
static const struct adv7604_video_standards adv7604_prim_mode_gr[] = {
|
||||
{ V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1360X768P60, 0x12, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1366X768P60, 0x13, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1400X1050P60, 0x14, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1400X1050P75, 0x15, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1600X1200P60, 0x16, 0x00 }, /* TODO not tested */
|
||||
/* TODO add 1600X1200P60_RB (not a DMT timing) */
|
||||
{ V4L2_DV_BT_DMT_1680X1050P60, 0x18, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1920X1200P60_RB, 0x19, 0x00 }, /* TODO not tested */
|
||||
{ },
|
||||
};
|
||||
|
||||
/* sorted by number of lines */
|
||||
static const struct adv7604_video_standards adv7604_prim_mode_hdmi_comp[] = {
|
||||
{ V4L2_DV_BT_CEA_720X480P59_94, 0x0a, 0x00 },
|
||||
{ V4L2_DV_BT_CEA_720X576P50, 0x0b, 0x00 },
|
||||
{ V4L2_DV_BT_CEA_1280X720P50, 0x13, 0x01 },
|
||||
{ V4L2_DV_BT_CEA_1280X720P60, 0x13, 0x00 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P24, 0x1e, 0x04 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P25, 0x1e, 0x03 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P30, 0x1e, 0x02 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P50, 0x1e, 0x01 },
|
||||
{ V4L2_DV_BT_CEA_1920X1080P60, 0x1e, 0x00 },
|
||||
{ },
|
||||
};
|
||||
|
||||
/* sorted by number of lines */
|
||||
static const struct adv7604_video_standards adv7604_prim_mode_hdmi_gr[] = {
|
||||
{ V4L2_DV_BT_DMT_640X480P60, 0x08, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P72, 0x09, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P75, 0x0a, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_640X480P85, 0x0b, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P56, 0x00, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P60, 0x01, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P72, 0x02, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P75, 0x03, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_800X600P85, 0x04, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P60, 0x0c, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P70, 0x0d, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P75, 0x0e, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1024X768P85, 0x0f, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1280X1024P60, 0x05, 0x00 },
|
||||
{ V4L2_DV_BT_DMT_1280X1024P75, 0x06, 0x00 },
|
||||
{ },
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static inline struct adv7604_state *to_state(struct v4l2_subdev *sd)
|
||||
@ -672,64 +755,144 @@ static int adv7604_s_detect_tx_5v_ctrl(struct v4l2_subdev *sd)
|
||||
((io_read(sd, 0x6f) & 0x10) >> 4));
|
||||
}
|
||||
|
||||
static void configure_free_run(struct v4l2_subdev *sd, const struct v4l2_bt_timings *timings)
|
||||
static int find_and_set_predefined_video_timings(struct v4l2_subdev *sd,
|
||||
u8 prim_mode,
|
||||
const struct adv7604_video_standards *predef_vid_timings,
|
||||
const struct v4l2_dv_timings *timings)
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
int i;
|
||||
|
||||
for (i = 0; predef_vid_timings[i].timings.bt.width; i++) {
|
||||
if (!v4l_match_dv_timings(timings, &predef_vid_timings[i].timings,
|
||||
DIGITAL_INPUT ? 250000 : 1000000))
|
||||
continue;
|
||||
io_write(sd, 0x00, predef_vid_timings[i].vid_std); /* video std */
|
||||
io_write(sd, 0x01, (predef_vid_timings[i].v_freq << 4) +
|
||||
prim_mode); /* v_freq and prim mode */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int configure_predefined_video_timings(struct v4l2_subdev *sd,
|
||||
struct v4l2_dv_timings *timings)
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
int err;
|
||||
|
||||
v4l2_dbg(1, debug, sd, "%s", __func__);
|
||||
|
||||
/* reset to default values */
|
||||
io_write(sd, 0x16, 0x43);
|
||||
io_write(sd, 0x17, 0x5a);
|
||||
/* disable embedded syncs for auto graphics mode */
|
||||
cp_write_and_or(sd, 0x81, 0xef, 0x00);
|
||||
cp_write(sd, 0x8f, 0x00);
|
||||
cp_write(sd, 0x90, 0x00);
|
||||
cp_write(sd, 0xa2, 0x00);
|
||||
cp_write(sd, 0xa3, 0x00);
|
||||
cp_write(sd, 0xa4, 0x00);
|
||||
cp_write(sd, 0xa5, 0x00);
|
||||
cp_write(sd, 0xa6, 0x00);
|
||||
cp_write(sd, 0xa7, 0x00);
|
||||
cp_write(sd, 0xab, 0x00);
|
||||
cp_write(sd, 0xac, 0x00);
|
||||
|
||||
switch (state->mode) {
|
||||
case ADV7604_MODE_COMP:
|
||||
case ADV7604_MODE_GR:
|
||||
err = find_and_set_predefined_video_timings(sd,
|
||||
0x01, adv7604_prim_mode_comp, timings);
|
||||
if (err)
|
||||
err = find_and_set_predefined_video_timings(sd,
|
||||
0x02, adv7604_prim_mode_gr, timings);
|
||||
break;
|
||||
case ADV7604_MODE_HDMI:
|
||||
err = find_and_set_predefined_video_timings(sd,
|
||||
0x05, adv7604_prim_mode_hdmi_comp, timings);
|
||||
if (err)
|
||||
err = find_and_set_predefined_video_timings(sd,
|
||||
0x06, adv7604_prim_mode_hdmi_gr, timings);
|
||||
break;
|
||||
default:
|
||||
v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
|
||||
__func__, state->mode);
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void configure_custom_video_timings(struct v4l2_subdev *sd,
|
||||
const struct v4l2_bt_timings *bt)
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
u32 width = htotal(timings);
|
||||
u32 height = vtotal(timings);
|
||||
u16 ch1_fr_ll = (((u32)timings->pixelclock / 100) > 0) ?
|
||||
((width * (ADV7604_fsc / 100)) / ((u32)timings->pixelclock / 100)) : 0;
|
||||
u32 width = htotal(bt);
|
||||
u32 height = vtotal(bt);
|
||||
u16 cp_start_sav = bt->hsync + bt->hbackporch - 4;
|
||||
u16 cp_start_eav = width - bt->hfrontporch;
|
||||
u16 cp_start_vbi = height - bt->vfrontporch;
|
||||
u16 cp_end_vbi = bt->vsync + bt->vbackporch;
|
||||
u16 ch1_fr_ll = (((u32)bt->pixelclock / 100) > 0) ?
|
||||
((width * (ADV7604_fsc / 100)) / ((u32)bt->pixelclock / 100)) : 0;
|
||||
const u8 pll[2] = {
|
||||
0xc0 | ((width >> 8) & 0x1f),
|
||||
width & 0xff
|
||||
};
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s\n", __func__);
|
||||
|
||||
cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7); /* CH1_FR_LL */
|
||||
cp_write(sd, 0x90, ch1_fr_ll & 0xff); /* CH1_FR_LL */
|
||||
cp_write(sd, 0xab, (height >> 4) & 0xff); /* CP_LCOUNT_MAX */
|
||||
cp_write(sd, 0xac, (height & 0x0f) << 4); /* CP_LCOUNT_MAX */
|
||||
/* TODO support interlaced */
|
||||
cp_write(sd, 0x91, 0x10); /* INTERLACED */
|
||||
|
||||
/* Should only be set in auto-graphics mode [REF_02 p. 91-92] */
|
||||
if ((io_read(sd, 0x00) == 0x07) && (io_read(sd, 0x01) == 0x02)) {
|
||||
u16 cp_start_sav, cp_start_eav, cp_start_vbi, cp_end_vbi;
|
||||
const u8 pll[2] = {
|
||||
(0xc0 | ((width >> 8) & 0x1f)),
|
||||
(width & 0xff)
|
||||
};
|
||||
switch (state->mode) {
|
||||
case ADV7604_MODE_COMP:
|
||||
case ADV7604_MODE_GR:
|
||||
/* auto graphics */
|
||||
io_write(sd, 0x00, 0x07); /* video std */
|
||||
io_write(sd, 0x01, 0x02); /* prim mode */
|
||||
/* enable embedded syncs for auto graphics mode */
|
||||
cp_write_and_or(sd, 0x81, 0xef, 0x10);
|
||||
|
||||
/* Should only be set in auto-graphics mode [REF_02, p. 91-92] */
|
||||
/* setup PLL_DIV_MAN_EN and PLL_DIV_RATIO */
|
||||
/* IO-map reg. 0x16 and 0x17 should be written in sequence */
|
||||
if (adv_smbus_write_i2c_block_data(client, 0x16, 2, pll)) {
|
||||
v4l2_err(sd, "writing to reg 0x16 and 0x17 failed\n");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/* active video - horizontal timing */
|
||||
cp_start_sav = timings->hsync + timings->hbackporch - 4;
|
||||
cp_start_eav = width - timings->hfrontporch;
|
||||
cp_write(sd, 0xa2, (cp_start_sav >> 4) & 0xff);
|
||||
cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) | ((cp_start_eav >> 8) & 0x0f));
|
||||
cp_write(sd, 0xa3, ((cp_start_sav & 0x0f) << 4) |
|
||||
((cp_start_eav >> 8) & 0x0f));
|
||||
cp_write(sd, 0xa4, cp_start_eav & 0xff);
|
||||
|
||||
/* active video - vertical timing */
|
||||
cp_start_vbi = height - timings->vfrontporch;
|
||||
cp_end_vbi = timings->vsync + timings->vbackporch;
|
||||
cp_write(sd, 0xa5, (cp_start_vbi >> 4) & 0xff);
|
||||
cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) | ((cp_end_vbi >> 8) & 0xf));
|
||||
cp_write(sd, 0xa6, ((cp_start_vbi & 0xf) << 4) |
|
||||
((cp_end_vbi >> 8) & 0xf));
|
||||
cp_write(sd, 0xa7, cp_end_vbi & 0xff);
|
||||
} else {
|
||||
/* reset to default values */
|
||||
io_write(sd, 0x16, 0x43);
|
||||
io_write(sd, 0x17, 0x5a);
|
||||
cp_write(sd, 0xa2, 0x00);
|
||||
cp_write(sd, 0xa3, 0x00);
|
||||
cp_write(sd, 0xa4, 0x00);
|
||||
cp_write(sd, 0xa5, 0x00);
|
||||
cp_write(sd, 0xa6, 0x00);
|
||||
cp_write(sd, 0xa7, 0x00);
|
||||
break;
|
||||
case ADV7604_MODE_HDMI:
|
||||
/* set default prim_mode/vid_std for HDMI
|
||||
accoring to [REF_03, c. 4.2] */
|
||||
io_write(sd, 0x00, 0x02); /* video std */
|
||||
io_write(sd, 0x01, 0x06); /* prim mode */
|
||||
break;
|
||||
default:
|
||||
v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
|
||||
__func__, state->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cp_write(sd, 0x8f, (ch1_fr_ll >> 8) & 0x7);
|
||||
cp_write(sd, 0x90, ch1_fr_ll & 0xff);
|
||||
cp_write(sd, 0xab, (height >> 4) & 0xff);
|
||||
cp_write(sd, 0xac, (height & 0x0f) << 4);
|
||||
}
|
||||
|
||||
static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
{
|
||||
@ -738,12 +901,7 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
switch (state->rgb_quantization_range) {
|
||||
case V4L2_DV_RGB_RANGE_AUTO:
|
||||
/* automatic */
|
||||
if ((hdmi_read(sd, 0x05) & 0x80) ||
|
||||
(state->prim_mode == ADV7604_PRIM_MODE_COMP) ||
|
||||
(state->prim_mode == ADV7604_PRIM_MODE_RGB)) {
|
||||
/* receiving HDMI or analog signal */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0xf0);
|
||||
} else {
|
||||
if (DIGITAL_INPUT && !(hdmi_read(sd, 0x05) & 0x80)) {
|
||||
/* receiving DVI-D signal */
|
||||
|
||||
/* ADV7604 selects RGB limited range regardless of
|
||||
@ -756,6 +914,9 @@ static void set_rgb_quantization_range(struct v4l2_subdev *sd)
|
||||
/* RGB full range (0-255) */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0x10);
|
||||
}
|
||||
} else {
|
||||
/* receiving HDMI or analog signal, set automode */
|
||||
io_write_and_or(sd, 0x02, 0x0f, 0xf0);
|
||||
}
|
||||
break;
|
||||
case V4L2_DV_RGB_RANGE_LIMITED:
|
||||
@ -967,8 +1128,10 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
|
||||
state->aspect_ratio, timings))
|
||||
return 0;
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: No format candidate found for lcf=%d, bl = %d\n",
|
||||
__func__, stdi->lcf, stdi->bl);
|
||||
v4l2_dbg(2, debug, sd,
|
||||
"%s: No format candidate found for lcvs = %d, lcf=%d, bl = %d, %chsync, %cvsync\n",
|
||||
__func__, stdi->lcvs, stdi->lcf, stdi->bl,
|
||||
stdi->hs_pol, stdi->vs_pol);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1123,7 +1286,7 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
|
||||
adv7604_fill_optional_dv_timings_fields(sd, timings);
|
||||
} else {
|
||||
/* find format
|
||||
* Since LCVS values are inaccurate (REF_03, page 275-276),
|
||||
* Since LCVS values are inaccurate [REF_03, p. 275-276],
|
||||
* stdi2dv_timings() is called with lcvs +-1 if the first attempt fails.
|
||||
*/
|
||||
if (!stdi2dv_timings(sd, &stdi, timings))
|
||||
@ -1135,9 +1298,31 @@ static int adv7604_query_dv_timings(struct v4l2_subdev *sd,
|
||||
stdi.lcvs -= 2;
|
||||
v4l2_dbg(1, debug, sd, "%s: lcvs - 1 = %d\n", __func__, stdi.lcvs);
|
||||
if (stdi2dv_timings(sd, &stdi, timings)) {
|
||||
/*
|
||||
* The STDI block may measure wrong values, especially
|
||||
* for lcvs and lcf. If the driver can not find any
|
||||
* valid timing, the STDI block is restarted to measure
|
||||
* the video timings again. The function will return an
|
||||
* error, but the restart of STDI will generate a new
|
||||
* STDI interrupt and the format detection process will
|
||||
* restart.
|
||||
*/
|
||||
if (state->restart_stdi_once) {
|
||||
v4l2_dbg(1, debug, sd, "%s: restart STDI\n", __func__);
|
||||
/* TODO restart STDI for Sync Channel 2 */
|
||||
/* enter one-shot mode */
|
||||
cp_write_and_or(sd, 0x86, 0xf9, 0x00);
|
||||
/* trigger STDI restart */
|
||||
cp_write_and_or(sd, 0x86, 0xf9, 0x04);
|
||||
/* reset to continuous mode */
|
||||
cp_write_and_or(sd, 0x86, 0xf9, 0x02);
|
||||
state->restart_stdi_once = false;
|
||||
return -ENOLINK;
|
||||
}
|
||||
v4l2_dbg(1, debug, sd, "%s: format not supported\n", __func__);
|
||||
return -ERANGE;
|
||||
}
|
||||
state->restart_stdi_once = true;
|
||||
}
|
||||
found:
|
||||
|
||||
@ -1166,6 +1351,7 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
|
||||
{
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
struct v4l2_bt_timings *bt;
|
||||
int err;
|
||||
|
||||
if (!timings)
|
||||
return -EINVAL;
|
||||
@ -1178,12 +1364,20 @@ static int adv7604_s_dv_timings(struct v4l2_subdev *sd,
|
||||
__func__, (u32)bt->pixelclock);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
adv7604_fill_optional_dv_timings_fields(sd, timings);
|
||||
|
||||
state->timings = *timings;
|
||||
|
||||
/* freerun */
|
||||
configure_free_run(sd, bt);
|
||||
cp_write(sd, 0x91, bt->interlaced ? 0x50 : 0x10);
|
||||
|
||||
/* Use prim_mode and vid_std when available */
|
||||
err = configure_predefined_video_timings(sd, timings);
|
||||
if (err) {
|
||||
/* custom settings when the video format
|
||||
does not have prim_mode/vid_std */
|
||||
configure_custom_video_timings(sd, bt);
|
||||
}
|
||||
|
||||
set_rgb_quantization_range(sd);
|
||||
|
||||
@ -1203,24 +1397,25 @@ static int adv7604_g_dv_timings(struct v4l2_subdev *sd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void enable_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
|
||||
static void enable_input(struct v4l2_subdev *sd)
|
||||
{
|
||||
switch (prim_mode) {
|
||||
case ADV7604_PRIM_MODE_COMP:
|
||||
case ADV7604_PRIM_MODE_RGB:
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
|
||||
switch (state->mode) {
|
||||
case ADV7604_MODE_COMP:
|
||||
case ADV7604_MODE_GR:
|
||||
/* enable */
|
||||
io_write(sd, 0x15, 0xb0); /* Disable Tristate of Pins (no audio) */
|
||||
break;
|
||||
case ADV7604_PRIM_MODE_HDMI_COMP:
|
||||
case ADV7604_PRIM_MODE_HDMI_GR:
|
||||
case ADV7604_MODE_HDMI:
|
||||
/* enable */
|
||||
hdmi_write(sd, 0x1a, 0x0a); /* Unmute audio */
|
||||
hdmi_write(sd, 0x01, 0x00); /* Enable HDMI clock terminators */
|
||||
io_write(sd, 0x15, 0xa0); /* Disable Tristate of Pins */
|
||||
break;
|
||||
default:
|
||||
v4l2_err(sd, "%s: reserved primary mode 0x%0x\n",
|
||||
__func__, prim_mode);
|
||||
v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
|
||||
__func__, state->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1233,17 +1428,13 @@ static void disable_input(struct v4l2_subdev *sd)
|
||||
hdmi_write(sd, 0x01, 0x78); /* Disable HDMI clock terminators */
|
||||
}
|
||||
|
||||
static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mode)
|
||||
static void select_input(struct v4l2_subdev *sd)
|
||||
{
|
||||
switch (prim_mode) {
|
||||
case ADV7604_PRIM_MODE_COMP:
|
||||
case ADV7604_PRIM_MODE_RGB:
|
||||
/* set mode and select free run resolution */
|
||||
io_write(sd, 0x00, 0x07); /* video std */
|
||||
io_write(sd, 0x01, 0x02); /* prim mode */
|
||||
/* enable embedded syncs for auto graphics mode */
|
||||
cp_write_and_or(sd, 0x81, 0xef, 0x10);
|
||||
struct adv7604_state *state = to_state(sd);
|
||||
|
||||
switch (state->mode) {
|
||||
case ADV7604_MODE_COMP:
|
||||
case ADV7604_MODE_GR:
|
||||
/* reset ADI recommended settings for HDMI: */
|
||||
/* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
|
||||
hdmi_write(sd, 0x0d, 0x04); /* HDMI filter optimization */
|
||||
@ -1271,16 +1462,7 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
|
||||
cp_write(sd, 0x40, 0x5c); /* CP core pre-gain control. Graphics mode */
|
||||
break;
|
||||
|
||||
case ADV7604_PRIM_MODE_HDMI_COMP:
|
||||
case ADV7604_PRIM_MODE_HDMI_GR:
|
||||
/* set mode and select free run resolution */
|
||||
/* video std */
|
||||
io_write(sd, 0x00,
|
||||
(prim_mode == ADV7604_PRIM_MODE_HDMI_GR) ? 0x02 : 0x1e);
|
||||
io_write(sd, 0x01, prim_mode); /* prim mode */
|
||||
/* disable embedded syncs for auto graphics mode */
|
||||
cp_write_and_or(sd, 0x81, 0xef, 0x00);
|
||||
|
||||
case ADV7604_MODE_HDMI:
|
||||
/* set ADI recommended settings for HDMI: */
|
||||
/* "ADV7604 Register Settings Recommendations (rev. 2.5, June 2010)" p. 4. */
|
||||
hdmi_write(sd, 0x0d, 0x84); /* HDMI filter optimization */
|
||||
@ -1309,7 +1491,8 @@ static void select_input(struct v4l2_subdev *sd, enum adv7604_prim_mode prim_mod
|
||||
|
||||
break;
|
||||
default:
|
||||
v4l2_err(sd, "%s: reserved primary mode 0x%0x\n", __func__, prim_mode);
|
||||
v4l2_dbg(2, debug, sd, "%s: Unknown mode %d\n",
|
||||
__func__, state->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1321,26 +1504,13 @@ static int adv7604_s_routing(struct v4l2_subdev *sd,
|
||||
|
||||
v4l2_dbg(2, debug, sd, "%s: input %d", __func__, input);
|
||||
|
||||
switch (input) {
|
||||
case 0:
|
||||
/* TODO select HDMI_COMP or HDMI_GR */
|
||||
state->prim_mode = ADV7604_PRIM_MODE_HDMI_COMP;
|
||||
break;
|
||||
case 1:
|
||||
state->prim_mode = ADV7604_PRIM_MODE_RGB;
|
||||
break;
|
||||
case 2:
|
||||
state->prim_mode = ADV7604_PRIM_MODE_COMP;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
state->mode = input;
|
||||
|
||||
disable_input(sd);
|
||||
|
||||
select_input(sd, state->prim_mode);
|
||||
select_input(sd);
|
||||
|
||||
enable_input(sd, state->prim_mode);
|
||||
enable_input(sd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1549,8 +1719,9 @@ static int adv7604_log_status(struct v4l2_subdev *sd)
|
||||
v4l2_info(sd, "CP locked: %s\n", no_lock_cp(sd) ? "false" : "true");
|
||||
v4l2_info(sd, "CP free run: %s\n",
|
||||
(!!(cp_read(sd, 0xff) & 0x10) ? "on" : "off"));
|
||||
v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x\n",
|
||||
io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f);
|
||||
v4l2_info(sd, "Prim-mode = 0x%x, video std = 0x%x, v_freq = 0x%x\n",
|
||||
io_read(sd, 0x01) & 0x0f, io_read(sd, 0x00) & 0x3f,
|
||||
(io_read(sd, 0x01) & 0x70) >> 4);
|
||||
|
||||
v4l2_info(sd, "-----Video Timings-----\n");
|
||||
if (read_stdi(sd, &stdi))
|
||||
@ -1712,9 +1883,9 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
|
||||
cp_write(sd, 0xba, (pdata->hdmi_free_run_mode << 1) | 0x01); /* HDMI free run */
|
||||
cp_write(sd, 0xf3, 0xdc); /* Low threshold to enter/exit free run mode */
|
||||
cp_write(sd, 0xf9, 0x23); /* STDI ch. 1 - LCVS change threshold -
|
||||
ADI recommended setting [REF_01 c. 2.3.3] */
|
||||
ADI recommended setting [REF_01, c. 2.3.3] */
|
||||
cp_write(sd, 0x45, 0x23); /* STDI ch. 2 - LCVS change threshold -
|
||||
ADI recommended setting [REF_01 c. 2.3.3] */
|
||||
ADI recommended setting [REF_01, c. 2.3.3] */
|
||||
cp_write(sd, 0xc9, 0x2d); /* use prim_mode and vid_std as free run resolution
|
||||
for digital formats */
|
||||
|
||||
@ -1724,11 +1895,6 @@ static int adv7604_core_init(struct v4l2_subdev *sd)
|
||||
afe_write(sd, 0x02, pdata->ain_sel); /* Select analog input muxing mode */
|
||||
io_write_and_or(sd, 0x30, ~(1 << 4), pdata->output_bus_lsb_to_msb << 4);
|
||||
|
||||
state->prim_mode = pdata->prim_mode;
|
||||
select_input(sd, pdata->prim_mode);
|
||||
|
||||
enable_input(sd, pdata->prim_mode);
|
||||
|
||||
/* interrupts */
|
||||
io_write(sd, 0x40, 0xc2); /* Configure INT1 */
|
||||
io_write(sd, 0x41, 0xd7); /* STDI irq for any change, disable INT2 */
|
||||
@ -1883,6 +2049,7 @@ static int adv7604_probe(struct i2c_client *client,
|
||||
v4l2_err(sd, "failed to create all i2c clients\n");
|
||||
goto err_i2c;
|
||||
}
|
||||
state->restart_stdi_once = true;
|
||||
|
||||
/* work queues */
|
||||
state->work_queues = create_singlethread_workqueue(client->name);
|
||||
|
@ -263,9 +263,14 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a)
|
||||
if (ret & 1) /* Autoexposure */
|
||||
ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
|
||||
rect.height + mt9v022->y_skip_top + 43);
|
||||
else
|
||||
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
|
||||
rect.height + mt9v022->y_skip_top + 43);
|
||||
/*
|
||||
* If autoexposure is off, there is no need to set
|
||||
* MT9V022_TOTAL_SHUTTER_WIDTH here. Autoexposure can be off
|
||||
* only if the user has set exposure manually, using the
|
||||
* V4L2_CID_EXPOSURE_AUTO with the value V4L2_EXPOSURE_MANUAL.
|
||||
* In this case the register MT9V022_TOTAL_SHUTTER_WIDTH
|
||||
* already contains the correct value.
|
||||
*/
|
||||
}
|
||||
/* Setup frame format: defaults apart from width and height */
|
||||
if (!ret)
|
||||
|
@ -965,8 +965,10 @@ static struct platform_device_id gsc_driver_ids[] = {
|
||||
MODULE_DEVICE_TABLE(platform, gsc_driver_ids);
|
||||
|
||||
static const struct of_device_id exynos_gsc_match[] = {
|
||||
{ .compatible = "samsung,exynos5250-gsc",
|
||||
.data = &gsc_v_100_drvdata, },
|
||||
{
|
||||
.compatible = "samsung,exynos5-gsc",
|
||||
.data = &gsc_v_100_drvdata,
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, exynos_gsc_match);
|
||||
|
@ -657,8 +657,7 @@ static int gsc_m2m_release(struct file *file)
|
||||
pr_debug("pid: %d, state: 0x%lx, refcnt= %d",
|
||||
task_pid_nr(current), gsc->state, gsc->m2m.refcnt);
|
||||
|
||||
if (mutex_lock_interruptible(&gsc->lock))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&gsc->lock);
|
||||
|
||||
v4l2_m2m_ctx_release(ctx->m2m_ctx);
|
||||
gsc_ctrls_delete(ctx);
|
||||
@ -732,6 +731,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc)
|
||||
gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops;
|
||||
gsc->vdev.release = video_device_release_empty;
|
||||
gsc->vdev.lock = &gsc->lock;
|
||||
gsc->vdev.vfl_dir = VFL_DIR_M2M;
|
||||
snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m",
|
||||
GSC_MODULE_NAME, gsc->id);
|
||||
|
||||
|
@ -40,10 +40,10 @@
|
||||
#define GSC_IN_ROT_YFLIP (2 << 16)
|
||||
#define GSC_IN_ROT_XFLIP (1 << 16)
|
||||
#define GSC_IN_RGB_TYPE_MASK (3 << 14)
|
||||
#define GSC_IN_RGB_HD_WIDE (3 << 14)
|
||||
#define GSC_IN_RGB_HD_NARROW (2 << 14)
|
||||
#define GSC_IN_RGB_SD_WIDE (1 << 14)
|
||||
#define GSC_IN_RGB_SD_NARROW (0 << 14)
|
||||
#define GSC_IN_RGB_HD_NARROW (3 << 14)
|
||||
#define GSC_IN_RGB_HD_WIDE (2 << 14)
|
||||
#define GSC_IN_RGB_SD_NARROW (1 << 14)
|
||||
#define GSC_IN_RGB_SD_WIDE (0 << 14)
|
||||
#define GSC_IN_YUV422_1P_ORDER_MASK (1 << 13)
|
||||
#define GSC_IN_YUV422_1P_ORDER_LSB_Y (0 << 13)
|
||||
#define GSC_IN_YUV422_1P_OEDER_LSB_C (1 << 13)
|
||||
@ -85,10 +85,10 @@
|
||||
#define GSC_OUT_GLOBAL_ALPHA_MASK (0xff << 24)
|
||||
#define GSC_OUT_GLOBAL_ALPHA(x) ((x) << 24)
|
||||
#define GSC_OUT_RGB_TYPE_MASK (3 << 10)
|
||||
#define GSC_OUT_RGB_HD_NARROW (3 << 10)
|
||||
#define GSC_OUT_RGB_HD_WIDE (2 << 10)
|
||||
#define GSC_OUT_RGB_SD_NARROW (1 << 10)
|
||||
#define GSC_OUT_RGB_SD_WIDE (0 << 10)
|
||||
#define GSC_OUT_RGB_HD_WIDE (3 << 10)
|
||||
#define GSC_OUT_RGB_HD_NARROW (2 << 10)
|
||||
#define GSC_OUT_RGB_SD_WIDE (1 << 10)
|
||||
#define GSC_OUT_RGB_SD_NARROW (0 << 10)
|
||||
#define GSC_OUT_YUV422_1P_ORDER_MASK (1 << 9)
|
||||
#define GSC_OUT_YUV422_1P_ORDER_LSB_Y (0 << 9)
|
||||
#define GSC_OUT_YUV422_1P_OEDER_LSB_C (1 << 9)
|
||||
|
@ -1706,7 +1706,7 @@ static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
|
||||
}
|
||||
|
||||
static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
struct v4l2_event_subscription *sub)
|
||||
{
|
||||
if (sub->type != V4L2_EVENT_FRAME_SYNC)
|
||||
return -EINVAL;
|
||||
@ -1719,7 +1719,7 @@ static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
}
|
||||
|
||||
static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
struct v4l2_event_subscription *sub)
|
||||
{
|
||||
return v4l2_event_unsubscribe(fh, sub);
|
||||
}
|
||||
|
@ -1025,7 +1025,7 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
|
||||
|
||||
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
|
||||
struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
struct v4l2_event_subscription *sub)
|
||||
{
|
||||
struct ispstat *stat = v4l2_get_subdevdata(subdev);
|
||||
|
||||
@ -1037,7 +1037,7 @@ int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
|
||||
|
||||
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
|
||||
struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub)
|
||||
struct v4l2_event_subscription *sub)
|
||||
{
|
||||
return v4l2_event_unsubscribe(fh, sub);
|
||||
}
|
||||
|
@ -147,10 +147,10 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name,
|
||||
void omap3isp_stat_cleanup(struct ispstat *stat);
|
||||
int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
|
||||
struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub);
|
||||
struct v4l2_event_subscription *sub);
|
||||
int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
|
||||
struct v4l2_fh *fh,
|
||||
const struct v4l2_event_subscription *sub);
|
||||
struct v4l2_event_subscription *sub);
|
||||
int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
|
||||
|
||||
int omap3isp_stat_busy(struct ispstat *stat);
|
||||
|
@ -792,7 +792,7 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
|
||||
}
|
||||
|
||||
static int
|
||||
isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
|
||||
isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
|
||||
{
|
||||
struct isp_video *video = video_drvdata(file);
|
||||
struct v4l2_subdev *subdev;
|
||||
|
@ -24,6 +24,7 @@ config VIDEO_S5P_FIMC
|
||||
config VIDEO_S5P_MIPI_CSIS
|
||||
tristate "S5P/EXYNOS MIPI-CSI2 receiver (MIPI-CSIS) driver"
|
||||
depends on REGULATOR
|
||||
select S5P_SETUP_MIPIPHY
|
||||
help
|
||||
This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC MIPI-CSI2
|
||||
receiver (MIPI-CSIS) devices.
|
||||
|
@ -556,8 +556,7 @@ static int fimc_capture_close(struct file *file)
|
||||
|
||||
dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&fimc->lock);
|
||||
|
||||
if (--fimc->vid_cap.refcnt == 0) {
|
||||
clear_bit(ST_CAPT_BUSY, &fimc->state);
|
||||
@ -1736,7 +1735,9 @@ static int fimc_register_capture_device(struct fimc_dev *fimc,
|
||||
q->mem_ops = &vb2_dma_contig_memops;
|
||||
q->buf_struct_size = sizeof(struct fimc_vid_buffer);
|
||||
|
||||
vb2_queue_init(q);
|
||||
ret = vb2_queue_init(q);
|
||||
if (ret)
|
||||
goto err_ent;
|
||||
|
||||
vid_cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
|
||||
ret = media_entity_init(&vfd->entity, 1, &vid_cap->vd_pad, 0);
|
||||
@ -1772,9 +1773,13 @@ static int fimc_capture_subdev_registered(struct v4l2_subdev *sd)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
|
||||
|
||||
ret = fimc_register_capture_device(fimc, sd->v4l2_dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
fimc_unregister_m2m_device(fimc);
|
||||
fimc->pipeline_ops = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1791,6 +1796,7 @@ static void fimc_capture_subdev_unregistered(struct v4l2_subdev *sd)
|
||||
if (video_is_registered(&fimc->vid_cap.vfd)) {
|
||||
video_unregister_device(&fimc->vid_cap.vfd);
|
||||
media_entity_cleanup(&fimc->vid_cap.vfd.entity);
|
||||
fimc->pipeline_ops = NULL;
|
||||
}
|
||||
kfree(fimc->vid_cap.ctx);
|
||||
fimc->vid_cap.ctx = NULL;
|
||||
|
@ -491,8 +491,7 @@ static int fimc_lite_close(struct file *file)
|
||||
struct fimc_lite *fimc = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&fimc->lock);
|
||||
|
||||
if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) {
|
||||
clear_bit(ST_FLITE_IN_USE, &fimc->state);
|
||||
@ -1253,7 +1252,9 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
|
||||
q->buf_struct_size = sizeof(struct flite_buffer);
|
||||
q->drv_priv = fimc;
|
||||
|
||||
vb2_queue_init(q);
|
||||
ret = vb2_queue_init(q);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
fimc->vd_pad.flags = MEDIA_PAD_FL_SINK;
|
||||
ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0);
|
||||
@ -1261,10 +1262,12 @@ static int fimc_lite_subdev_registered(struct v4l2_subdev *sd)
|
||||
return ret;
|
||||
|
||||
video_set_drvdata(vfd, fimc);
|
||||
fimc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
|
||||
|
||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
|
||||
if (ret < 0) {
|
||||
media_entity_cleanup(&vfd->entity);
|
||||
fimc->pipeline_ops = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1283,6 +1286,7 @@ static void fimc_lite_subdev_unregistered(struct v4l2_subdev *sd)
|
||||
if (video_is_registered(&fimc->vfd)) {
|
||||
video_unregister_device(&fimc->vfd);
|
||||
media_entity_cleanup(&fimc->vfd.entity);
|
||||
fimc->pipeline_ops = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,8 +718,7 @@ static int fimc_m2m_release(struct file *file)
|
||||
dbg("pid: %d, state: 0x%lx, refcnt= %d",
|
||||
task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
|
||||
|
||||
if (mutex_lock_interruptible(&fimc->lock))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&fimc->lock);
|
||||
|
||||
v4l2_m2m_ctx_release(ctx->m2m_ctx);
|
||||
fimc_ctrls_delete(ctx);
|
||||
|
@ -343,53 +343,50 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd)
|
||||
static int fimc_register_callback(struct device *dev, void *p)
|
||||
{
|
||||
struct fimc_dev *fimc = dev_get_drvdata(dev);
|
||||
struct v4l2_subdev *sd = &fimc->vid_cap.subdev;
|
||||
struct v4l2_subdev *sd;
|
||||
struct fimc_md *fmd = p;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (!fimc || !fimc->pdev)
|
||||
if (fimc == NULL || fimc->id >= FIMC_MAX_DEVS)
|
||||
return 0;
|
||||
|
||||
if (fimc->pdev->id < 0 || fimc->pdev->id >= FIMC_MAX_DEVS)
|
||||
return 0;
|
||||
|
||||
fimc->pipeline_ops = &fimc_pipeline_ops;
|
||||
fmd->fimc[fimc->pdev->id] = fimc;
|
||||
sd = &fimc->vid_cap.subdev;
|
||||
sd->grp_id = FIMC_GROUP_ID;
|
||||
v4l2_set_subdev_hostdata(sd, (void *)&fimc_pipeline_ops);
|
||||
|
||||
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
|
||||
if (ret) {
|
||||
v4l2_err(&fmd->v4l2_dev, "Failed to register FIMC.%d (%d)\n",
|
||||
fimc->id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
fmd->fimc[fimc->id] = fimc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fimc_lite_register_callback(struct device *dev, void *p)
|
||||
{
|
||||
struct fimc_lite *fimc = dev_get_drvdata(dev);
|
||||
struct v4l2_subdev *sd = &fimc->subdev;
|
||||
struct fimc_md *fmd = p;
|
||||
int ret;
|
||||
|
||||
if (fimc == NULL)
|
||||
if (fimc == NULL || fimc->index >= FIMC_LITE_MAX_DEVS)
|
||||
return 0;
|
||||
|
||||
if (fimc->index >= FIMC_LITE_MAX_DEVS)
|
||||
return 0;
|
||||
fimc->subdev.grp_id = FLITE_GROUP_ID;
|
||||
v4l2_set_subdev_hostdata(&fimc->subdev, (void *)&fimc_pipeline_ops);
|
||||
|
||||
fimc->pipeline_ops = &fimc_pipeline_ops;
|
||||
fmd->fimc_lite[fimc->index] = fimc;
|
||||
sd->grp_id = FLITE_GROUP_ID;
|
||||
|
||||
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
|
||||
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, &fimc->subdev);
|
||||
if (ret) {
|
||||
v4l2_err(&fmd->v4l2_dev,
|
||||
"Failed to register FIMC-LITE.%d (%d)\n",
|
||||
fimc->index, ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
|
||||
fmd->fimc_lite[fimc->index] = fimc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int csis_register_callback(struct device *dev, void *p)
|
||||
@ -407,10 +404,12 @@ static int csis_register_callback(struct device *dev, void *p)
|
||||
v4l2_info(sd, "csis%d sd: %s\n", pdev->id, sd->name);
|
||||
|
||||
id = pdev->id < 0 ? 0 : pdev->id;
|
||||
fmd->csis[id].sd = sd;
|
||||
sd->grp_id = CSIS_GROUP_ID;
|
||||
|
||||
ret = v4l2_device_register_subdev(&fmd->v4l2_dev, sd);
|
||||
if (ret)
|
||||
if (!ret)
|
||||
fmd->csis[id].sd = sd;
|
||||
else
|
||||
v4l2_err(&fmd->v4l2_dev,
|
||||
"Failed to register CSIS subdevice: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -381,11 +381,8 @@ static void s5p_mfc_handle_frame(struct s5p_mfc_ctx *ctx,
|
||||
ctx->consumed_stream += s5p_mfc_hw_call(dev->mfc_ops,
|
||||
get_consumed_stream, dev);
|
||||
if (ctx->codec_mode != S5P_MFC_CODEC_H264_DEC &&
|
||||
s5p_mfc_hw_call(dev->mfc_ops,
|
||||
get_dec_frame_type, dev) ==
|
||||
S5P_FIMV_DECODE_FRAME_P_FRAME
|
||||
&& ctx->consumed_stream + STUFF_BYTE <
|
||||
src_buf->b->v4l2_planes[0].bytesused) {
|
||||
ctx->consumed_stream + STUFF_BYTE <
|
||||
src_buf->b->v4l2_planes[0].bytesused) {
|
||||
/* Run MFC again on the same buffer */
|
||||
mfc_debug(2, "Running again the same buffer\n");
|
||||
ctx->after_packed_pb = 1;
|
||||
|
@ -1762,7 +1762,7 @@ int s5p_mfc_get_dspl_y_adr_v6(struct s5p_mfc_dev *dev)
|
||||
|
||||
int s5p_mfc_get_dec_y_adr_v6(struct s5p_mfc_dev *dev)
|
||||
{
|
||||
return mfc_read(dev, S5P_FIMV_D_DISPLAY_LUMA_ADDR_V6);
|
||||
return mfc_read(dev, S5P_FIMV_D_DECODED_LUMA_ADDR_V6);
|
||||
}
|
||||
|
||||
int s5p_mfc_get_dspl_status_v6(struct s5p_mfc_dev *dev)
|
||||
|
@ -935,9 +935,10 @@ static int sh_vou_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
|
||||
/* Assume a dull encoder, do all the work ourselves. */
|
||||
static int sh_vou_s_crop(struct file *file, void *fh, const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_crop a_writable = *a;
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct sh_vou_device *vou_dev = video_get_drvdata(vdev);
|
||||
struct v4l2_rect *rect = &a->c;
|
||||
struct v4l2_rect *rect = &a_writable.c;
|
||||
struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT};
|
||||
struct v4l2_pix_format *pix = &vou_dev->pix;
|
||||
struct sh_vou_geometry geo;
|
||||
|
@ -470,14 +470,6 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
|
||||
pcdev->icd = NULL;
|
||||
}
|
||||
|
||||
static int mx1_camera_set_crop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
|
||||
return v4l2_subdev_call(sd, video, s_crop, a);
|
||||
}
|
||||
|
||||
static int mx1_camera_set_bus_param(struct soc_camera_device *icd)
|
||||
{
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
@ -689,7 +681,6 @@ static struct soc_camera_host_ops mx1_soc_camera_host_ops = {
|
||||
.add = mx1_camera_add_device,
|
||||
.remove = mx1_camera_remove_device,
|
||||
.set_bus_param = mx1_camera_set_bus_param,
|
||||
.set_crop = mx1_camera_set_crop,
|
||||
.set_fmt = mx1_camera_set_fmt,
|
||||
.try_fmt = mx1_camera_try_fmt,
|
||||
.init_videobuf = mx1_camera_init_videobuf,
|
||||
|
@ -864,8 +864,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
|
||||
bytesperline = soc_mbus_bytes_per_line(icd->user_width,
|
||||
icd->current_fmt->host_fmt);
|
||||
if (bytesperline < 0)
|
||||
if (bytesperline < 0) {
|
||||
spin_unlock_irqrestore(&pcdev->lock, flags);
|
||||
return bytesperline;
|
||||
}
|
||||
|
||||
/*
|
||||
* I didn't manage to properly enable/disable the prp
|
||||
@ -878,8 +880,10 @@ static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
|
||||
pcdev->discard_buffer = dma_alloc_coherent(ici->v4l2_dev.dev,
|
||||
pcdev->discard_size, &pcdev->discard_buffer_dma,
|
||||
GFP_KERNEL);
|
||||
if (!pcdev->discard_buffer)
|
||||
if (!pcdev->discard_buffer) {
|
||||
spin_unlock_irqrestore(&pcdev->lock, flags);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pcdev->buf_discard[0].discard = true;
|
||||
list_add_tail(&pcdev->buf_discard[0].queue,
|
||||
@ -1099,9 +1103,10 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd)
|
||||
}
|
||||
|
||||
static int mx2_camera_set_crop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *a)
|
||||
const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_rect *rect = &a->c;
|
||||
struct v4l2_crop a_writable = *a;
|
||||
struct v4l2_rect *rect = &a_writable.c;
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
struct v4l2_mbus_framefmt mf;
|
||||
int ret;
|
||||
|
@ -799,9 +799,10 @@ static inline void stride_align(__u32 *width)
|
||||
* default g_crop and cropcap from soc_camera.c
|
||||
*/
|
||||
static int mx3_camera_set_crop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *a)
|
||||
const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_rect *rect = &a->c;
|
||||
struct v4l2_crop a_writable = *a;
|
||||
struct v4l2_rect *rect = &a_writable.c;
|
||||
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
|
||||
struct mx3_camera_dev *mx3_cam = ici->priv;
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
|
@ -1215,9 +1215,9 @@ static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
|
||||
}
|
||||
|
||||
static int omap1_cam_set_crop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *crop)
|
||||
const struct v4l2_crop *crop)
|
||||
{
|
||||
struct v4l2_rect *rect = &crop->c;
|
||||
const struct v4l2_rect *rect = &crop->c;
|
||||
const struct soc_camera_format_xlate *xlate = icd->current_fmt;
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
struct device *dev = icd->parent;
|
||||
|
@ -1337,9 +1337,9 @@ static int pxa_camera_check_frame(u32 width, u32 height)
|
||||
}
|
||||
|
||||
static int pxa_camera_set_crop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *a)
|
||||
const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_rect *rect = &a->c;
|
||||
const struct v4l2_rect *rect = &a->c;
|
||||
struct device *dev = icd->parent;
|
||||
struct soc_camera_host *ici = to_soc_camera_host(dev);
|
||||
struct pxa_camera_dev *pcdev = ici->priv;
|
||||
|
@ -1182,13 +1182,13 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
|
||||
}
|
||||
|
||||
/* Check if any dimension of r1 is smaller than respective one of r2 */
|
||||
static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
|
||||
static bool is_smaller(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
|
||||
{
|
||||
return r1->width < r2->width || r1->height < r2->height;
|
||||
}
|
||||
|
||||
/* Check if r1 fails to cover r2 */
|
||||
static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
|
||||
static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2)
|
||||
{
|
||||
return r1->left > r2->left || r1->top > r2->top ||
|
||||
r1->left + r1->width < r2->left + r2->width ||
|
||||
@ -1263,7 +1263,7 @@ static void update_subrect(struct sh_mobile_ceu_cam *cam)
|
||||
* 3. if (2) failed, try to request the maximum image
|
||||
*/
|
||||
static int client_s_crop(struct soc_camera_device *icd, struct v4l2_crop *crop,
|
||||
const struct v4l2_crop *cam_crop)
|
||||
struct v4l2_crop *cam_crop)
|
||||
{
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
|
||||
@ -1519,7 +1519,8 @@ static int client_scale(struct soc_camera_device *icd,
|
||||
static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
|
||||
const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_rect *rect = &a->c;
|
||||
struct v4l2_crop a_writable = *a;
|
||||
const struct v4l2_rect *rect = &a_writable.c;
|
||||
struct device *dev = icd->parent;
|
||||
struct soc_camera_host *ici = to_soc_camera_host(dev);
|
||||
struct sh_mobile_ceu_dev *pcdev = ici->priv;
|
||||
@ -1545,7 +1546,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
|
||||
* 1. - 2. Apply iterative camera S_CROP for new input window, read back
|
||||
* actual camera rectangle.
|
||||
*/
|
||||
ret = client_s_crop(icd, a, &cam_crop);
|
||||
ret = client_s_crop(icd, &a_writable, &cam_crop);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -1946,7 +1947,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
|
||||
}
|
||||
|
||||
static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
|
||||
struct v4l2_crop *a)
|
||||
const struct v4l2_crop *a)
|
||||
{
|
||||
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
|
||||
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
|
||||
|
@ -283,14 +283,13 @@ static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
|
||||
|
||||
/* activate the pid on the device pid filter */
|
||||
if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
|
||||
adap->pid_filtering &&
|
||||
adap->props->pid_filter)
|
||||
adap->pid_filtering && adap->props->pid_filter) {
|
||||
ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
|
||||
dvbdmxfeed->pid, (count == 1) ? 1 : 0);
|
||||
if (ret < 0)
|
||||
dev_err(&d->udev->dev, "%s: pid_filter() " \
|
||||
"failed=%d\n", KBUILD_MODNAME,
|
||||
ret);
|
||||
if (ret < 0)
|
||||
dev_err(&d->udev->dev, "%s: pid_filter() failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
}
|
||||
|
||||
/* start feeding if it is first pid */
|
||||
if (adap->feed_count == 1 && count == 1) {
|
||||
|
@ -32,9 +32,7 @@ int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = mutex_lock_interruptible(&d->usb_mutex);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mutex_lock(&d->usb_mutex);
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
|
||||
|
||||
|
@ -1346,6 +1346,10 @@ static const struct usb_device_id rtl28xxu_id_table[] = {
|
||||
&rtl2832u_props, "DigitalNow Quad DVB-T Receiver", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d3,
|
||||
&rtl2832u_props, "TerraTec Cinergy T Stick RC (Rev. 3)", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_DEXATEK, 0x1102,
|
||||
&rtl2832u_props, "Dexatek DK mini DVB-T Dongle", NULL) },
|
||||
{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00d7,
|
||||
&rtl2832u_props, "TerraTec Cinergy T Stick+", NULL) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
|
||||
|
@ -96,11 +96,11 @@ static irqreturn_t arizona_underclocked(int irq, void *data)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
|
||||
dev_err(arizona->dev, "AIF3 underclocked\n");
|
||||
if (val & ARIZONA_AIF3_UNDERCLOCKED_STS)
|
||||
dev_err(arizona->dev, "AIF3 underclocked\n");
|
||||
if (val & ARIZONA_AIF2_UNDERCLOCKED_STS)
|
||||
dev_err(arizona->dev, "AIF2 underclocked\n");
|
||||
if (val & ARIZONA_AIF1_UNDERCLOCKED_STS)
|
||||
dev_err(arizona->dev, "AIF1 underclocked\n");
|
||||
if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS)
|
||||
dev_err(arizona->dev, "ISRC2 underclocked\n");
|
||||
@ -417,11 +417,19 @@ int __devinit arizona_dev_init(struct arizona *arizona)
|
||||
|
||||
/* If we have a /RESET GPIO we'll already be reset */
|
||||
if (!arizona->pdata.reset) {
|
||||
regcache_mark_dirty(arizona->regmap);
|
||||
|
||||
ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "Failed to reset device: %d\n", ret);
|
||||
goto err_reset;
|
||||
}
|
||||
|
||||
ret = regcache_sync(arizona->regmap);
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "Failed to sync device: %d\n", ret);
|
||||
goto err_reset;
|
||||
}
|
||||
}
|
||||
|
||||
ret = arizona_wait_for_boot(arizona);
|
||||
@ -522,7 +530,7 @@ int __devinit arizona_dev_init(struct arizona *arizona)
|
||||
break;
|
||||
case WM5110:
|
||||
ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
|
||||
ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
|
||||
ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user