Re: Linux 2.6.39.4
From: Greg KH
Date: Wed Aug 03 2011 - 16:29:50 EST
diff --git a/Makefile b/Makefile
index 2abc88e..1b2a736 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 39
-EXTRAVERSION = .3
+EXTRAVERSION = .4
NAME = Flesh-Eating Bats with Fangs
# *DOCUMENTATION*
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 376f221..326f0a2 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -409,7 +409,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
return -EFAULT;
len = namelen;
- if (namelen > 32)
+ if (len > 32)
len = 32;
down_read(&uts_sem);
@@ -594,7 +594,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
down_read(&uts_sem);
res = sysinfo_table[offset];
len = strlen(res)+1;
- if (len > count)
+ if ((unsigned long)len > (unsigned long)count)
len = count;
if (copy_to_user(buf, res, len))
err = -EFAULT;
@@ -649,7 +649,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
return 1;
case GSI_GET_HWRPB:
- if (nbytes < sizeof(*hwrpb))
+ if (nbytes > sizeof(*hwrpb))
return -EINVAL;
if (copy_to_user(buffer, hwrpb, nbytes) != 0)
return -EFAULT;
@@ -1008,6 +1008,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
{
struct rusage r;
long ret, err;
+ unsigned int status = 0;
mm_segment_t old_fs;
if (!ur)
@@ -1016,13 +1017,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options,
old_fs = get_fs();
set_fs (KERNEL_DS);
- ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
+ ret = sys_wait4(pid, (unsigned int __user *) &status, options,
+ (struct rusage __user *) &r);
set_fs (old_fs);
if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
return -EFAULT;
err = 0;
+ err |= put_user(status, ustatus);
err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 139e3c8..d284a30 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -588,7 +588,7 @@ static int armpmu_event_init(struct perf_event *event)
static void armpmu_enable(struct pmu *pmu)
{
/* Enable all of the perf events on hardware. */
- int idx;
+ int idx, enabled = 0;
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
if (!armpmu)
@@ -601,9 +601,11 @@ static void armpmu_enable(struct pmu *pmu)
continue;
armpmu->enable(&event->hw, idx);
+ enabled = 1;
}
- armpmu->start();
+ if (enabled)
+ armpmu->start();
}
static void armpmu_disable(struct pmu *pmu)
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index c67f684..09a87e6 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -520,7 +520,7 @@ fail:
*/
if (have_imager()) {
label = "HD imager";
- mux |= 1;
+ mux |= 2;
/* externally mux MMC1/ENET/AIC33 to imager */
mux |= BIT(6) | BIT(5) | BIT(3);
@@ -540,7 +540,7 @@ fail:
resets &= ~BIT(1);
if (have_tvp7002()) {
- mux |= 2;
+ mux |= 1;
resets &= ~BIT(2);
label = "tvp7002 HD";
} else {
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 72b4e76..ab9f999 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -79,7 +79,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0);
static APBC_CLK(ssp5, PXA168_SSP5, 4, 0);
static APBC_CLK(keypad, PXA168_KPC, 0, 32000);
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
static APMU_CLK(lcd, LCD, 0x7f, 312000000);
/* device and clock bindings */
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 8f92ccd..1464607 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -110,7 +110,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
-static APMU_CLK(nand, NAND, 0x01db, 208000000);
+static APMU_CLK(nand, NAND, 0x19b, 156000000);
static APMU_CLK(u2o, USB, 0x1b, 480000000);
/* device and clock bindings */
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
index 1d1419b..dfff1de 100644
--- a/arch/arm/mach-pxa/mfp-pxa2xx.c
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -347,9 +347,9 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) &&
(GPDR(i) & GPIO_bit(i))) {
if (GPLR(i) & GPIO_bit(i))
- PGSR(i) |= GPIO_bit(i);
+ PGSR(gpio_to_bank(i)) |= GPIO_bit(i);
else
- PGSR(i) &= ~GPIO_bit(i);
+ PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i);
}
}
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 08c44b0..1def278 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -411,6 +411,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
},
},
+ { /* Handle problems with rebooting on the Latitude E5420. */
+ .callback = set_pci_reboot,
+ .ident = "Dell Latitude E5420",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
+ },
+ },
{ }
};
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index dad9fd6..17b74f4 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2802,10 +2802,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
/*
- * Some controllers can't be frozen very well and may set
- * spuruious error conditions during reset. Clear accumulated
- * error information. As reset is the final recovery action,
- * nothing is lost by doing this.
+ * Some controllers can't be frozen very well and may set spurious
+ * error conditions during reset. Clear accumulated error
+ * information and re-thaw the port if frozen. As reset is the
+ * final recovery action and we cross check link onlineness against
+ * device classification later, no hotplug event is lost by this.
*/
spin_lock_irqsave(link->ap->lock, flags);
memset(&link->eh_info, 0, sizeof(link->eh_info));
@@ -2814,6 +2815,9 @@ int ata_eh_reset(struct ata_link *link, int classify,
ap->pflags &= ~ATA_PFLAG_EH_PENDING;
spin_unlock_irqrestore(link->ap->lock, flags);
+ if (ap->pflags & ATA_PFLAG_FROZEN)
+ ata_eh_thaw_port(ap);
+
/*
* Make sure onlineness and classification result correspond.
* Hotplug could have happened during reset and some
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 23d1468..578d139 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
#define PCI_DEVICE_ID_AGERE_FW643 0x5901
#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd
#define QUIRK_CYCLE_TIMER 1
#define QUIRK_RESET_PACKET 2
@@ -3170,6 +3171,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
int i, err;
size_t size;
+ if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
+ dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
+ return -ENOSYS;
+ }
+
ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
if (ohci == NULL) {
err = -ENOMEM;
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 296e6ec..10e4e34 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -960,17 +960,19 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
{
save->vga_control[0] = RREG32(D1VGA_CONTROL);
save->vga_control[1] = RREG32(D2VGA_CONTROL);
- save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
- save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
- save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
- save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
+ save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
+ save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ }
+ if (rdev->num_crtc >= 6) {
+ save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
+ save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
}
@@ -979,35 +981,45 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
WREG32(VGA_RENDER_CONTROL, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
}
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
WREG32(D1VGA_CONTROL, 0);
WREG32(D2VGA_CONTROL, 0);
- WREG32(EVERGREEN_D3VGA_CONTROL, 0);
- WREG32(EVERGREEN_D4VGA_CONTROL, 0);
- WREG32(EVERGREEN_D5VGA_CONTROL, 0);
- WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+ if (rdev->num_crtc >= 4) {
+ WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+ WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+ }
+ if (rdev->num_crtc >= 6) {
+ WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+ WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+ }
}
void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1030,7 +1042,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
(u32)rdev->mc.vram_start);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
upper_32_bits(rdev->mc.vram_start));
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
@@ -1048,7 +1060,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
(u32)rdev->mc.vram_start);
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
(u32)rdev->mc.vram_start);
-
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
upper_32_bits(rdev->mc.vram_start));
WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
@@ -1076,31 +1089,41 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
/* Restore video state */
WREG32(D1VGA_CONTROL, save->vga_control[0]);
WREG32(D2VGA_CONTROL, save->vga_control[1]);
- WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
- WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
- WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
- WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+ if (rdev->num_crtc >= 4) {
+ WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
+ WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
+ }
+ if (rdev->num_crtc >= 6) {
+ WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]);
+ WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]);
+ }
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
}
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]);
WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]);
}
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
@@ -1900,7 +1923,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
gb_backend_map = 0x66442200;
break;
case CHIP_JUNIPER:
- gb_backend_map = 0x00006420;
+ gb_backend_map = 0x00002200;
break;
default:
gb_backend_map =
@@ -2327,18 +2350,22 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev)
WREG32(GRBM_INT_CNTL, 0);
WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
}
@@ -2457,19 +2484,25 @@ int evergreen_irq_set(struct radeon_device *rdev)
WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
- if (!(rdev->flags & RADEON_IS_IGP)) {
+ if (rdev->num_crtc >= 4) {
WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
+ }
+ if (rdev->num_crtc >= 6) {
WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
}
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
- WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+ if (rdev->num_crtc >= 4) {
+ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
+ }
+ if (rdev->num_crtc >= 6) {
+ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+ WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+ }
WREG32(DC_HPD1_INT_CONTROL, hpd1);
WREG32(DC_HPD2_INT_CONTROL, hpd2);
@@ -2493,53 +2526,57 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev)
rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
- rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
- rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
- rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
- rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+ if (rdev->num_crtc >= 4) {
+ rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ }
+ if (rdev->num_crtc >= 6) {
+ rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+ rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+ }
if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
- if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
- if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
- if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
- if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
- WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-
if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
-
if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)
WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
- if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
- WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
- if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
- WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
-
- if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
- WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
- if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
- WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
-
- if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
- WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
- if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
- WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
-
- if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
- WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
- if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
- WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+ if (rdev->num_crtc >= 4) {
+ if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
+ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
+ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+ WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+ WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
+ WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
+ WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
+ }
+
+ if (rdev->num_crtc >= 6) {
+ if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
+ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
+ WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+ WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+ WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
+ WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
+ if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
+ WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+ }
if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
tmp = RREG32(DC_HPD1_INT_CONTROL);
@@ -3150,6 +3187,7 @@ void evergreen_fini(struct radeon_device *rdev)
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
evergreen_pcie_gart_fini(rdev);
radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index f37e91e..273e7e9 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -460,7 +460,7 @@
#define IH_RB_WPTR_ADDR_LO 0x3e14
#define IH_CNTL 0x3e18
# define ENABLE_INTR (1 << 0)
-# define IH_MC_SWAP(x) ((x) << 2)
+# define IH_MC_SWAP(x) ((x) << 1)
# define IH_MC_SWAP_NONE 0
# define IH_MC_SWAP_16BIT 1
# define IH_MC_SWAP_32BIT 2
@@ -541,7 +541,7 @@
# define LB_D5_VBLANK_INTERRUPT (1 << 3)
# define DC_HPD5_INTERRUPT (1 << 17)
# define DC_HPD5_RX_INTERRUPT (1 << 18)
-#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6050
+#define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150
# define LB_D6_VLINE_INTERRUPT (1 << 2)
# define LB_D6_VBLANK_INTERRUPT (1 << 3)
# define DC_HPD6_INTERRUPT (1 << 17)
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index b205ba1..58f5070 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1584,6 +1584,7 @@ void cayman_fini(struct radeon_device *rdev)
cayman_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
cayman_pcie_gart_fini(rdev);
radeon_gem_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 6f27593..068cc85 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2613,6 +2613,7 @@ void r600_fini(struct radeon_device *rdev)
r600_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
r600_pcie_gart_fini(rdev);
radeon_agp_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index b2b944b..e5eaef9 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -536,7 +536,7 @@
#define IH_RB_WPTR_ADDR_LO 0x3e14
#define IH_CNTL 0x3e18
# define ENABLE_INTR (1 << 0)
-# define IH_MC_SWAP(x) ((x) << 2)
+# define IH_MC_SWAP(x) ((x) << 1)
# define IH_MC_SWAP_NONE 0
# define IH_MC_SWAP_16BIT 1
# define IH_MC_SWAP_32BIT 2
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index bdbab5c..2802c56 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -264,6 +264,8 @@ static void radeon_unpin_work_func(struct work_struct *__work)
radeon_bo_unreserve(work->old_rbo);
} else
DRM_ERROR("failed to reserve buffer after flip\n");
+
+ drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
kfree(work);
}
@@ -371,6 +373,8 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
new_radeon_fb = to_radeon_framebuffer(fb);
/* schedule unpin of the old buffer */
obj = old_radeon_fb->obj;
+ /* take a reference to the old object */
+ drm_gem_object_reference(obj);
rbo = gem_to_radeon_bo(obj);
work->old_rbo = rbo;
INIT_WORK(&work->work, radeon_unpin_work_func);
@@ -378,12 +382,9 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
/* We borrow the event spin lock for protecting unpin_work */
spin_lock_irqsave(&dev->event_lock, flags);
if (radeon_crtc->unpin_work) {
- spin_unlock_irqrestore(&dev->event_lock, flags);
- kfree(work);
- radeon_fence_unref(&fence);
-
DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
- return -EBUSY;
+ r = -EBUSY;
+ goto unlock_free;
}
radeon_crtc->unpin_work = work;
radeon_crtc->deferred_flip_completion = 0;
@@ -497,6 +498,8 @@ pflip_cleanup1:
pflip_cleanup:
spin_lock_irqsave(&dev->event_lock, flags);
radeon_crtc->unpin_work = NULL;
+unlock_free:
+ drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
spin_unlock_irqrestore(&dev->event_lock, flags);
radeon_fence_unref(&fence);
kfree(work);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 05aa674..33b856b 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1365,6 +1365,7 @@ void rv770_fini(struct radeon_device *rdev)
r700_cp_fini(rdev);
r600_irq_fini(rdev);
radeon_wb_fini(rdev);
+ radeon_ib_pool_fini(rdev);
radeon_irq_kms_fini(rdev);
rv770_pcie_gart_fini(rdev);
rv770_vram_scratch_fini(rdev);
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index b5e8920..3462242 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -673,6 +673,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val)
else
err = -EIO;
+ ACPI_FREE(ret);
return err;
}
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 316b648..a8d2359 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1535,7 +1535,7 @@ static struct attribute *it87_attributes_label[] = {
};
static const struct attribute_group it87_group_label = {
- .attrs = it87_attributes_vid,
+ .attrs = it87_attributes_label,
};
/* SuperIO detection - will change isa_address if a chip is found */
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 1a6dfb6..d3b464b 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -98,11 +98,16 @@ struct lm95241_data {
};
/* Conversions */
-static int TempFromReg(u8 val_h, u8 val_l)
+static int temp_from_reg_signed(u8 val_h, u8 val_l)
{
- if (val_h & 0x80)
- return val_h - 0x100;
- return val_h * 1000 + val_l * 1000 / 256;
+ s16 val_hl = (val_h << 8) | val_l;
+ return val_hl * 1000 / 256;
+}
+
+static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
+{
+ u16 val_hl = (val_h << 8) | val_l;
+ return val_hl * 1000 / 256;
}
static struct lm95241_data *lm95241_update_device(struct device *dev)
@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct lm95241_data *data = lm95241_update_device(dev);
+ int index = to_sensor_dev_attr(attr)->index;
return snprintf(buf, PAGE_SIZE - 1, "%d\n",
- TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
- data->temp[to_sensor_dev_attr(attr)->index + 1]));
+ index == 0 || (data->config & (1 << (index / 2))) ?
+ temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
+ temp_from_reg_unsigned(data->temp[index],
+ data->temp[index + 1]));
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr,
@@ -339,7 +347,7 @@ static int lm95241_detect(struct i2c_client *new_client,
if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
== MANUFACTURER_ID)
&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
- >= DEFAULT_REVISION)) {
+ == DEFAULT_REVISION)) {
name = DEVNAME;
} else {
dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index 12a54aa..14335bb 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -40,6 +40,8 @@ struct max1111_data {
struct spi_transfer xfer[2];
uint8_t *tx_buf;
uint8_t *rx_buf;
+ struct mutex drvdata_lock;
+ /* protect msg, xfer and buffers from multiple access */
};
static int max1111_read(struct device *dev, int channel)
@@ -48,6 +50,9 @@ static int max1111_read(struct device *dev, int channel)
uint8_t v1, v2;
int err;
+ /* writing to drvdata struct is not thread safe, wait on mutex */
+ mutex_lock(&data->drvdata_lock);
+
data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
@@ -55,12 +60,15 @@ static int max1111_read(struct device *dev, int channel)
err = spi_sync(data->spi, &data->msg);
if (err < 0) {
dev_err(dev, "spi_sync failed with %d\n", err);
+ mutex_unlock(&data->drvdata_lock);
return err;
}
v1 = data->rx_buf[0];
v2 = data->rx_buf[1];
+ mutex_unlock(&data->drvdata_lock);
+
if ((v1 & 0xc0) || (v2 & 0x3f))
return -EINVAL;
@@ -176,6 +184,8 @@ static int __devinit max1111_probe(struct spi_device *spi)
if (err)
goto err_free_data;
+ mutex_init(&data->drvdata_lock);
+
data->spi = spi;
spi_set_drvdata(spi, data);
@@ -213,6 +223,7 @@ static int __devexit max1111_remove(struct spi_device *spi)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
+ mutex_destroy(&data->drvdata_lock);
kfree(data->rx_buf);
kfree(data->tx_buf);
kfree(data);
diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c
index 98e2e28..9b1f0c3 100644
--- a/drivers/hwmon/pmbus.c
+++ b/drivers/hwmon/pmbus.c
@@ -47,22 +47,29 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
if (info->func[0]
&& pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
info->func[0] |= PMBUS_HAVE_FAN12;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
}
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
info->func[0] |= PMBUS_HAVE_FAN34;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
}
- if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
info->func[0] |= PMBUS_HAVE_TEMP;
- if (pmbus_check_byte_register(client, 0,
- PMBUS_STATUS_TEMPERATURE))
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+ info->func[0] |= PMBUS_HAVE_TEMP2;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+ info->func[0] |= PMBUS_HAVE_TEMP3;
+ if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
+ | PMBUS_HAVE_TEMP3)
+ && pmbus_check_byte_register(client, 0,
+ PMBUS_STATUS_TEMPERATURE))
info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
- }
/* Sensors detected on all pages */
for (page = 0; page < info->pages; page++) {
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index 7df490e..8217d19 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -355,8 +355,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
* Convert linear sensor values to milli- or micro-units
* depending on sensor type.
*/
-static int pmbus_reg2data_linear(struct pmbus_data *data,
- struct pmbus_sensor *sensor)
+static long pmbus_reg2data_linear(struct pmbus_data *data,
+ struct pmbus_sensor *sensor)
{
s16 exponent;
s32 mantissa;
@@ -390,15 +390,15 @@ static int pmbus_reg2data_linear(struct pmbus_data *data,
else
val >>= -exponent;
- return (int)val;
+ return val;
}
/*
* Convert direct sensor values to milli- or micro-units
* depending on sensor type.
*/
-static int pmbus_reg2data_direct(struct pmbus_data *data,
- struct pmbus_sensor *sensor)
+static long pmbus_reg2data_direct(struct pmbus_data *data,
+ struct pmbus_sensor *sensor)
{
long val = (s16) sensor->data;
long m, b, R;
@@ -433,12 +433,12 @@ static int pmbus_reg2data_direct(struct pmbus_data *data,
R++;
}
- return (int)((val - b) / m);
+ return (val - b) / m;
}
-static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
+static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
{
- int val;
+ long val;
if (data->info->direct[sensor->class])
val = pmbus_reg2data_direct(data, sensor);
@@ -612,7 +612,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
if (!s1 && !s2)
*val = !!regval;
else {
- int v1, v2;
+ long v1, v2;
struct pmbus_sensor *sensor1, *sensor2;
sensor1 = &data->sensors[s1];
@@ -654,7 +654,7 @@ static ssize_t pmbus_show_sensor(struct device *dev,
if (sensor->data < 0)
return sensor->data;
- return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor));
+ return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
}
static ssize_t pmbus_set_sensor(struct device *dev,
@@ -1518,14 +1518,9 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
- /*
- * Bail out if status register or PMBus revision register
- * does not exist.
- */
- if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
- || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
- dev_err(&client->dev,
- "Status or revision register not found\n");
+ /* Bail out if PMBus status register does not exist. */
+ if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+ dev_err(&client->dev, "PMBus status register not found\n");
ret = -ENODEV;
goto out_data;
}
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index 1d47d4d..d4e466a 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -73,47 +73,27 @@ struct dib0070_state {
u8 wbd_gain_current;
u16 wbd_offset_3_3[2];
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[3];
- u8 i2c_read_buffer[2];
};
static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
{
- state->i2c_write_buffer[0] = reg;
-
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->cfg->i2c_address;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 1;
- state->msg[1].addr = state->cfg->i2c_address;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = state->i2c_read_buffer;
- state->msg[1].len = 2;
-
- if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+ u8 b[2];
+ struct i2c_msg msg[2] = {
+ { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 },
+ { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 },
+ };
+ if (i2c_transfer(state->i2c, msg, 2) != 2) {
printk(KERN_WARNING "DiB0070 I2C read failed\n");
return 0;
}
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (b[0] << 8) | b[1];
}
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
{
- state->i2c_write_buffer[0] = reg;
- state->i2c_write_buffer[1] = val >> 8;
- state->i2c_write_buffer[2] = val & 0xff;
-
- memset(state->msg, 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->cfg->i2c_address;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 3;
-
- if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+ u8 b[3] = { reg, val >> 8, val & 0xff };
+ struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0070 I2C write failed\n");
return -EREMOTEIO;
}
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index c9c935a..52ff1a2 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -191,11 +191,6 @@ struct dib0090_state {
u8 wbd_calibration_gain;
const struct dib0090_wbd_slope *current_wbd_table;
u16 wbdmux;
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[3];
- u8 i2c_read_buffer[2];
};
struct dib0090_fw_state {
@@ -203,48 +198,27 @@ struct dib0090_fw_state {
struct dvb_frontend *fe;
struct dib0090_identity identity;
const struct dib0090_config *config;
-
- /* for the I2C transfer */
- struct i2c_msg msg;
- u8 i2c_write_buffer[2];
- u8 i2c_read_buffer[2];
};
static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
{
- state->i2c_write_buffer[0] = reg;
-
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->config->i2c_address;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 1;
- state->msg[1].addr = state->config->i2c_address;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = state->i2c_read_buffer;
- state->msg[1].len = 2;
-
- if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
+ u8 b[2];
+ struct i2c_msg msg[2] = {
+ {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1},
+ {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
+ };
+ if (i2c_transfer(state->i2c, msg, 2) != 2) {
printk(KERN_WARNING "DiB0090 I2C read failed\n");
return 0;
}
-
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (b[0] << 8) | b[1];
}
static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
{
- state->i2c_write_buffer[0] = reg & 0xff;
- state->i2c_write_buffer[1] = val >> 8;
- state->i2c_write_buffer[2] = val & 0xff;
-
- memset(state->msg, 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->config->i2c_address;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 3;
-
- if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
+ u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
+ struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C write failed\n");
return -EREMOTEIO;
}
@@ -253,31 +227,20 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
{
- state->i2c_write_buffer[0] = reg;
-
- memset(&state->msg, 0, sizeof(struct i2c_msg));
- state->msg.addr = reg;
- state->msg.flags = I2C_M_RD;
- state->msg.buf = state->i2c_read_buffer;
- state->msg.len = 2;
- if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+ u8 b[2];
+ struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C read failed\n");
return 0;
}
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (b[0] << 8) | b[1];
}
static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
{
- state->i2c_write_buffer[0] = val >> 8;
- state->i2c_write_buffer[1] = val & 0xff;
-
- memset(&state->msg, 0, sizeof(struct i2c_msg));
- state->msg.addr = reg;
- state->msg.flags = 0;
- state->msg.buf = state->i2c_write_buffer;
- state->msg.len = 2;
- if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
+ u8 b[2] = { val >> 8, val & 0xff };
+ struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 };
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C write failed\n");
return -EREMOTEIO;
}
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 79cb1c2..289a798 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -50,11 +50,6 @@ struct dib7000m_state {
u16 revision;
u8 agc_state;
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[4];
- u8 i2c_read_buffer[2];
};
enum dib7000m_power_mode {
@@ -69,39 +64,29 @@ enum dib7000m_power_mode {
static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
{
- state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
- state->i2c_write_buffer[1] = reg & 0xff;
-
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 2;
- state->msg[1].addr = state->i2c_addr >> 1;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = state->i2c_read_buffer;
- state->msg[1].len = 2;
-
- if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+ u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[2] = {
+ { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
+ { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
+ };
+
+ if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
dprintk("i2c read error on %d",reg);
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (rb[0] << 8) | rb[1];
}
static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
{
- state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- state->i2c_write_buffer[1] = reg & 0xff;
- state->i2c_write_buffer[2] = (val >> 8) & 0xff;
- state->i2c_write_buffer[3] = val & 0xff;
-
- memset(&state->msg[0], 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 4;
-
- return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+ };
+ return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
{
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 0c9f40c..900af60 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -63,11 +63,6 @@ struct dib7000p_state {
u16 tuner_enable;
struct i2c_adapter dib7090_tuner_adap;
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[4];
- u8 i2c_read_buffer[2];
};
enum dib7000p_power_mode {
@@ -81,39 +76,29 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
{
- state->i2c_write_buffer[0] = reg >> 8;
- state->i2c_write_buffer[1] = reg & 0xff;
-
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 2;
- state->msg[1].addr = state->i2c_addr >> 1;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = state->i2c_read_buffer;
- state->msg[1].len = 2;
+ u8 wb[2] = { reg >> 8, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[2] = {
+ {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+ {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
+ };
- if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
+ if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
dprintk("i2c read error on %d", reg);
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (rb[0] << 8) | rb[1];
}
static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
{
- state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- state->i2c_write_buffer[1] = reg & 0xff;
- state->i2c_write_buffer[2] = (val >> 8) & 0xff;
- state->i2c_write_buffer[3] = val & 0xff;
-
- memset(&state->msg[0], 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 4;
-
- return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+ };
+ return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
@@ -1565,24 +1550,11 @@ static void dib7000p_release(struct dvb_frontend *demod)
int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{
- u8 *tx, *rx;
+ u8 tx[2], rx[2];
struct i2c_msg msg[2] = {
- {.addr = 18 >> 1, .flags = 0, .len = 2},
- {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
+ {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2},
+ {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2},
};
- int ret = 0;
-
- tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
- if (!tx)
- return -ENOMEM;
- rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
- if (!rx) {
- goto rx_memory_error;
- ret = -ENOMEM;
- }
-
- msg[0].buf = tx;
- msg[1].buf = rx;
tx[0] = 0x03;
tx[1] = 0x00;
@@ -1602,11 +1574,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
}
dprintk("-D- DiB7000PC not detected");
-
- kfree(rx);
-rx_memory_error:
- kfree(tx);
- return ret;
+ return 0;
}
EXPORT_SYMBOL(dib7000pc_detection);
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index 7d2ea11..c1c3e26 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -35,8 +35,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
struct i2c_device {
struct i2c_adapter *adap;
u8 addr;
- u8 *i2c_write_buffer;
- u8 *i2c_read_buffer;
};
struct dib8000_state {
@@ -72,11 +70,6 @@ struct dib8000_state {
u32 status;
struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[4];
- u8 i2c_read_buffer[2];
};
enum dib8000_power_mode {
@@ -86,41 +79,22 @@ enum dib8000_power_mode {
static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
{
+ u8 wb[2] = { reg >> 8, reg & 0xff };
+ u8 rb[2];
struct i2c_msg msg[2] = {
- {.addr = i2c->addr >> 1, .flags = 0,
- .buf = i2c->i2c_write_buffer, .len = 2},
- {.addr = i2c->addr >> 1, .flags = I2C_M_RD,
- .buf = i2c->i2c_read_buffer, .len = 2},
+ {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
+ {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
};
- msg[0].buf[0] = reg >> 8;
- msg[0].buf[1] = reg & 0xff;
-
if (i2c_transfer(i2c->adap, msg, 2) != 2)
dprintk("i2c read error on %d", reg);
- return (msg[1].buf[0] << 8) | msg[1].buf[1];
+ return (rb[0] << 8) | rb[1];
}
static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
{
- state->i2c_write_buffer[0] = reg >> 8;
- state->i2c_write_buffer[1] = reg & 0xff;
-
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c.addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 2;
- state->msg[1].addr = state->i2c.addr >> 1;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = state->i2c_read_buffer;
- state->msg[1].len = 2;
-
- if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
- dprintk("i2c read error on %d", reg);
-
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return dib8000_i2c_read16(&state->i2c, reg);
}
static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
@@ -135,34 +109,19 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
{
- struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
- .buf = i2c->i2c_write_buffer, .len = 4};
- int ret = 0;
-
- msg.buf[0] = (reg >> 8) & 0xff;
- msg.buf[1] = reg & 0xff;
- msg.buf[2] = (val >> 8) & 0xff;
- msg.buf[3] = val & 0xff;
-
- ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
-
- return ret;
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
+ };
+ return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
{
- state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- state->i2c_write_buffer[1] = reg & 0xff;
- state->i2c_write_buffer[2] = (val >> 8) & 0xff;
- state->i2c_write_buffer[3] = val & 0xff;
-
- memset(&state->msg[0], 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c.addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 4;
-
- return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+ return dib8000_i2c_write16(&state->i2c, reg, val);
}
static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
@@ -1021,31 +980,30 @@ static void dib8000_update_timf(struct dib8000_state *state)
dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
}
-static const u16 adc_target_16dB[11] = {
- (1 << 13) - 825 - 117,
- (1 << 13) - 837 - 117,
- (1 << 13) - 811 - 117,
- (1 << 13) - 766 - 117,
- (1 << 13) - 737 - 117,
- (1 << 13) - 693 - 117,
- (1 << 13) - 648 - 117,
- (1 << 13) - 619 - 117,
- (1 << 13) - 575 - 117,
- (1 << 13) - 531 - 117,
- (1 << 13) - 501 - 117
-};
-static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
-
static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
{
u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
u8 guard, crate, constellation, timeI;
+ u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
const s16 *ncoeff = NULL, *ana_fe;
u16 tmcc_pow = 0;
u16 coff_pow = 0x2800;
u16 init_prbs = 0xfff;
u16 ana_gain = 0;
+ u16 adc_target_16dB[11] = {
+ (1 << 13) - 825 - 117,
+ (1 << 13) - 837 - 117,
+ (1 << 13) - 811 - 117,
+ (1 << 13) - 766 - 117,
+ (1 << 13) - 737 - 117,
+ (1 << 13) - 693 - 117,
+ (1 << 13) - 648 - 117,
+ (1 << 13) - 619 - 117,
+ (1 << 13) - 575 - 117,
+ (1 << 13) - 531 - 117,
+ (1 << 13) - 501 - 117
+ };
if (state->ber_monitored_layer != LAYER_ALL)
dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
@@ -2421,22 +2379,10 @@ EXPORT_SYMBOL(dib8000_get_slave_frontend);
int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
{
- int k = 0, ret = 0;
+ int k = 0;
u8 new_addr = 0;
struct i2c_device client = {.adap = host };
- client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
- if (!client.i2c_write_buffer) {
- dprintk("%s: not enough memory", __func__);
- return -ENOMEM;
- }
- client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
- if (!client.i2c_read_buffer) {
- dprintk("%s: not enough memory", __func__);
- ret = -ENOMEM;
- goto error_memory;
- }
-
for (k = no_of_demods - 1; k >= 0; k--) {
/* designated i2c address */
new_addr = first_addr + (k << 1);
@@ -2448,8 +2394,7 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
client.addr = default_addr;
if (dib8000_identify(&client) == 0) {
dprintk("#%d: not identified", k);
- ret = -EINVAL;
- goto error;
+ return -EINVAL;
}
}
@@ -2475,12 +2420,7 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
dib8000_i2c_write16(&client, 1286, 0);
}
-error:
- kfree(client.i2c_read_buffer);
-error_memory:
- kfree(client.i2c_write_buffer);
-
- return ret;
+ return 0;
}
EXPORT_SYMBOL(dib8000_i2c_enumeration);
@@ -2579,8 +2519,6 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
state->i2c.adap = i2c_adap;
state->i2c.addr = i2c_addr;
- state->i2c.i2c_write_buffer = state->i2c_write_buffer;
- state->i2c.i2c_read_buffer = state->i2c_read_buffer;
state->gpio_val = cfg->gpio_val;
state->gpio_dir = cfg->gpio_dir;
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
index 451ffa2..9151876 100644
--- a/drivers/media/dvb/frontends/dib9000.c
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -27,8 +27,6 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
struct i2c_device {
struct i2c_adapter *i2c_adap;
u8 i2c_addr;
- u8 *i2c_read_buffer;
- u8 *i2c_write_buffer;
};
/* lock */
@@ -94,16 +92,11 @@ struct dib9000_state {
struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
u16 component_bus_speed;
-
- /* for the I2C transfer */
- struct i2c_msg msg[2];
- u8 i2c_write_buffer[255];
- u8 i2c_read_buffer[255];
};
-static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0
+ 0, 0, 0
};
enum dib9000_power_mode {
@@ -224,33 +217,25 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32
u32 chunk_size = 126;
u32 l;
int ret;
+ u8 wb[2] = { reg >> 8, reg & 0xff };
+ struct i2c_msg msg[2] = {
+ {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+ {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
+ };
if (state->platform.risc.fw_is_running && (reg < 1024))
return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
- memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c.i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = 2;
- state->msg[1].addr = state->i2c.i2c_addr >> 1;
- state->msg[1].flags = I2C_M_RD;
- state->msg[1].buf = b;
- state->msg[1].len = len;
-
- state->i2c_write_buffer[0] = reg >> 8;
- state->i2c_write_buffer[1] = reg & 0xff;
-
if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
- state->i2c_write_buffer[0] |= (1 << 5);
+ wb[0] |= (1 << 5);
if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
- state->i2c_write_buffer[0] |= (1 << 4);
+ wb[0] |= (1 << 4);
do {
l = len < chunk_size ? len : chunk_size;
- state->msg[1].len = l;
- state->msg[1].buf = b;
- ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
+ msg[1].len = l;
+ msg[1].buf = b;
+ ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0;
if (ret != 0) {
dprintk("i2c read error on %d", reg);
return -EREMOTEIO;
@@ -268,47 +253,50 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32
static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
{
+ u8 b[2];
+ u8 wb[2] = { reg >> 8, reg & 0xff };
struct i2c_msg msg[2] = {
- {.addr = i2c->i2c_addr >> 1, .flags = 0,
- .buf = i2c->i2c_write_buffer, .len = 2},
- {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
- .buf = i2c->i2c_read_buffer, .len = 2},
+ {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
+ {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2},
};
- i2c->i2c_write_buffer[0] = reg >> 8;
- i2c->i2c_write_buffer[1] = reg & 0xff;
-
if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
dprintk("read register %x error", reg);
return 0;
}
- return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
+ return (b[0] << 8) | b[1];
}
static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
{
- if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
+ u8 b[2];
+ if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
return 0;
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (b[0] << 8 | b[1]);
}
static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
{
- if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
- attribute) != 0)
+ u8 b[2];
+ if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0)
return 0;
- return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
+ return (b[0] << 8 | b[1]);
}
#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
{
+ u8 b[255];
u32 chunk_size = 126;
u32 l;
int ret;
+ struct i2c_msg msg = {
+ .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
+ };
+
if (state->platform.risc.fw_is_running && (reg < 1024)) {
if (dib9000_risc_apb_access_write
(state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
@@ -316,26 +304,20 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *
return 0;
}
- memset(&state->msg[0], 0, sizeof(struct i2c_msg));
- state->msg[0].addr = state->i2c.i2c_addr >> 1;
- state->msg[0].flags = 0;
- state->msg[0].buf = state->i2c_write_buffer;
- state->msg[0].len = len + 2;
-
- state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- state->i2c_write_buffer[1] = (reg) & 0xff;
+ b[0] = (reg >> 8) & 0xff;
+ b[1] = (reg) & 0xff;
if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
- state->i2c_write_buffer[0] |= (1 << 5);
+ b[0] |= (1 << 5);
if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
- state->i2c_write_buffer[0] |= (1 << 4);
+ b[0] |= (1 << 4);
do {
l = len < chunk_size ? len : chunk_size;
- state->msg[0].len = l + 2;
- memcpy(&state->i2c_write_buffer[2], buf, l);
+ msg.len = l + 2;
+ memcpy(&b[2], buf, l);
- ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
+ ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
buf += l;
len -= l;
@@ -349,16 +331,11 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *
static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
{
+ u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
struct i2c_msg msg = {
- .addr = i2c->i2c_addr >> 1, .flags = 0,
- .buf = i2c->i2c_write_buffer, .len = 4
+ .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
};
- i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- i2c->i2c_write_buffer[1] = reg & 0xff;
- i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
- i2c->i2c_write_buffer[3] = val & 0xff;
-
return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
@@ -1038,8 +1015,8 @@ static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
return 0;
dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
do {
- dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
- } while (state->i2c_read_buffer[0] && index_loop--);
+ dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1);
+ } while (i && index_loop--);
if (index_loop > 0)
return 0;
@@ -1162,7 +1139,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
s8 intlv_native;
};
- struct dibDVBTChannel *ch;
+ struct dibDVBTChannel ch;
int ret = 0;
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
@@ -1171,12 +1148,9 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
ret = -EIO;
}
- dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
- state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
- ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
-
+ dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel));
- switch (ch->spectrum_inversion & 0x7) {
+ switch (ch.spectrum_inversion & 0x7) {
case 1:
state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
break;
@@ -1188,7 +1162,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
break;
}
- switch (ch->nfft) {
+ switch (ch.nfft) {
case 0:
state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
break;
@@ -1203,7 +1177,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
break;
}
- switch (ch->guard) {
+ switch (ch.guard) {
case 0:
state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
break;
@@ -1221,7 +1195,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
break;
}
- switch (ch->constellation) {
+ switch (ch.constellation) {
case 2:
state->fe[0]->dtv_property_cache.modulation = QAM_64;
break;
@@ -1236,7 +1210,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
break;
}
- switch (ch->hrch) {
+ switch (ch.hrch) {
case 0:
state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
break;
@@ -1248,7 +1222,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
break;
}
- switch (ch->code_rate_hp) {
+ switch (ch.code_rate_hp) {
case 1:
state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
break;
@@ -1269,7 +1243,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p
state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
break;
}
- switch (ch->code_rate_lp) {
+ switch (ch.code_rate_lp) {
case 1:
state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
break;
@@ -1465,10 +1439,9 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete
break;
case CT_DEMOD_STEP_1:
if (search)
- dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
+ dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1);
else
- dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
- i = (s8)state->i2c_read_buffer[0];
+ dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1);
switch (i) { /* something happened */
case 0:
break;
@@ -2065,17 +2038,14 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
{
struct dib9000_state *state = fe->demodulator_priv;
- u16 *c;
+ u16 c[16];
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
return -EIO;
- dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
- state->i2c_read_buffer, 16 * 2);
+ dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
DibReleaseLock(&state->platform.risc.mem_mbx_lock);
- c = (u16 *)state->i2c_read_buffer;
-
*ber = c[10] << 16 | c[11];
return 0;
}
@@ -2084,7 +2054,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
{
struct dib9000_state *state = fe->demodulator_priv;
u8 index_frontend;
- u16 *c = (u16 *)state->i2c_read_buffer;
+ u16 c[16];
u16 val;
*strength = 0;
@@ -2099,7 +2069,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
return -EIO;
- dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+ dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
DibReleaseLock(&state->platform.risc.mem_mbx_lock);
val = 65535 - c[4];
@@ -2113,14 +2083,14 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
static u32 dib9000_get_snr(struct dvb_frontend *fe)
{
struct dib9000_state *state = fe->demodulator_priv;
- u16 *c = (u16 *)state->i2c_read_buffer;
+ u16 c[16];
u32 n, s, exp;
u16 val;
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
return -EIO;
- dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+ dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
DibReleaseLock(&state->platform.risc.mem_mbx_lock);
val = c[7];
@@ -2167,12 +2137,12 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
{
struct dib9000_state *state = fe->demodulator_priv;
- u16 *c = (u16 *)state->i2c_read_buffer;
+ u16 c[16];
DibAcquireLock(&state->platform.risc.mem_mbx_lock);
if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
return -EIO;
- dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
+ dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
DibReleaseLock(&state->platform.risc.mem_mbx_lock);
*unc = c[12];
@@ -2181,22 +2151,10 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
{
- int k = 0, ret = 0;
+ int k = 0;
u8 new_addr = 0;
struct i2c_device client = {.i2c_adap = i2c };
- client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
- if (!client.i2c_write_buffer) {
- dprintk("%s: not enough memory", __func__);
- return -ENOMEM;
- }
- client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
- if (!client.i2c_read_buffer) {
- dprintk("%s: not enough memory", __func__);
- ret = -ENOMEM;
- goto error_memory;
- }
-
client.i2c_addr = default_addr + 16;
dib9000_i2c_write16(&client, 1796, 0x0);
@@ -2220,8 +2178,7 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul
client.i2c_addr = default_addr;
if (dib9000_identify(&client) == 0) {
dprintk("DiB9000 #%d: not identified", k);
- ret = -EIO;
- goto error;
+ return -EIO;
}
}
@@ -2239,12 +2196,7 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul
dib9000_i2c_write16(&client, 1795, 0);
}
-error:
- kfree(client.i2c_read_buffer);
-error_memory:
- kfree(client.i2c_write_buffer);
-
- return ret;
+ return 0;
}
EXPORT_SYMBOL(dib9000_i2c_enumeration);
@@ -2309,8 +2261,6 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c
memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
st->i2c.i2c_adap = i2c_adap;
st->i2c.i2c_addr = i2c_addr;
- st->i2c.i2c_write_buffer = st->i2c_write_buffer;
- st->i2c.i2c_read_buffer = st->i2c_read_buffer;
st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index dc5d17a..f6938f9 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -10,39 +10,30 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
{
- mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
- mst->i2c_write_buffer[1] = reg & 0xff;
- mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
- mst->i2c_write_buffer[3] = val & 0xff;
-
- memset(mst->msg, 0, sizeof(struct i2c_msg));
- mst->msg[0].addr = mst->i2c_addr;
- mst->msg[0].flags = 0;
- mst->msg[0].buf = mst->i2c_write_buffer;
- mst->msg[0].len = 4;
-
- return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
+ u8 b[4] = {
+ (reg >> 8) & 0xff, reg & 0xff,
+ (val >> 8) & 0xff, val & 0xff,
+ };
+ struct i2c_msg msg = {
+ .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
+ };
+
+ return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
}
static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
{
- mst->i2c_write_buffer[0] = reg >> 8;
- mst->i2c_write_buffer[1] = reg & 0xff;
-
- memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
- mst->msg[0].addr = mst->i2c_addr;
- mst->msg[0].flags = 0;
- mst->msg[0].buf = mst->i2c_write_buffer;
- mst->msg[0].len = 2;
- mst->msg[1].addr = mst->i2c_addr;
- mst->msg[1].flags = I2C_M_RD;
- mst->msg[1].buf = mst->i2c_read_buffer;
- mst->msg[1].len = 2;
-
- if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
+ u8 wb[2] = { reg >> 8, reg & 0xff };
+ u8 rb[2];
+ struct i2c_msg msg[2] = {
+ {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
+ {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
+ };
+
+ if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
dprintk("i2c read error on %d", reg);
- return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
+ return (rb[0] << 8) | rb[1];
}
static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
@@ -257,32 +248,26 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msg[], int num)
{
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+ struct i2c_msg m[2 + num];
+ u8 tx_open[4], tx_close[4];
- if (num > 32) {
- dprintk("%s: too much I2C message to be transmitted (%i).\
- Maximum is 32", __func__, num);
- return -ENOMEM;
- }
-
- memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+ memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
- /* open the gate */
- dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
- mst->msg[0].addr = mst->i2c_addr;
- mst->msg[0].buf = &mst->i2c_write_buffer[0];
- mst->msg[0].len = 4;
+ dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+ m[0].addr = mst->i2c_addr;
+ m[0].buf = tx_open;
+ m[0].len = 4;
- memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+ memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
- /* close the gate */
- dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
- mst->msg[num + 1].addr = mst->i2c_addr;
- mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
- mst->msg[num + 1].len = 4;
+ dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
+ m[num + 1].addr = mst->i2c_addr;
+ m[num + 1].buf = tx_close;
+ m[num + 1].len = 4;
- return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
+ return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
}
static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
@@ -294,32 +279,26 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msg[], int num)
{
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
+ struct i2c_msg m[2 + num];
+ u8 tx_open[4], tx_close[4];
- if (num > 32) {
- dprintk("%s: too much I2C message to be transmitted (%i).\
- Maximum is 32", __func__, num);
- return -ENOMEM;
- }
-
- memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
+ memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
- /* open the gate */
- dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
- mst->msg[0].addr = mst->i2c_addr;
- mst->msg[0].buf = &mst->i2c_write_buffer[0];
- mst->msg[0].len = 4;
+ dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
+ m[0].addr = mst->i2c_addr;
+ m[0].buf = tx_open;
+ m[0].len = 4;
- memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
+ memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
- /* close the gate */
- dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
- mst->msg[num + 1].addr = mst->i2c_addr;
- mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
- mst->msg[num + 1].len = 4;
+ dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
+ m[num + 1].addr = mst->i2c_addr;
+ m[num + 1].buf = tx_close;
+ m[num + 1].len = 4;
- return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
+ return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
}
static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index f031165..977d343 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -28,11 +28,6 @@ struct dibx000_i2c_master {
u8 i2c_addr;
u16 base_reg;
-
- /* for the I2C transfer */
- struct i2c_msg msg[34];
- u8 i2c_write_buffer[8];
- u8 i2c_read_buffer[2];
};
extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index deca2e0..c9f4a8e 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -1033,7 +1033,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
char ps_name[MAX_RDS_PS_NAME + 1];
len = control->size - 1;
- if (len > MAX_RDS_PS_NAME) {
+ if (len < 0 || len > MAX_RDS_PS_NAME) {
rval = -ERANGE;
goto exit;
}
@@ -1057,7 +1057,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
char radio_text[MAX_RDS_RADIO_TEXT + 1];
len = control->size - 1;
- if (len > MAX_RDS_RADIO_TEXT) {
+ if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
rval = -ERANGE;
goto exit;
}
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 91399c9..3ea1a5d 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- bttv_call_all(btv, tuner, g_tuner, t);
+ bttv_call_all(btv, tuner, s_tuner, t);
return 0;
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 9933810..2a3fab1 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -2060,12 +2060,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- if (!pci_enable_msi(pci_dev))
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_DISABLED, dev->name, dev);
- else
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+ err = request_irq(pci_dev->irq, cx23885_irq,
+ IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->name, pci_dev->irq);
@@ -2114,7 +2110,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_disable_msi(pci_dev);
cx23885_dev_unregister(dev);
v4l2_device_unregister(v4l2_dev);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 9d0dd08..e98d382 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
struct v4l2_tuner vt;
memset(&vt, 0, sizeof(vt));
+ vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
vt.audmode = hdw->audiomode_val;
v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
}
@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
{
struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
memset(vtp, 0, sizeof(*vtp));
+ vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
hdw->tuner_signal_stale = 0;
/* Note: There apparently is no replacement for VIDIOC_CROPCAP
using v4l2-subdev - therefore we can't support that AT ALL right
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 9363ed9..1843fc2 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -724,19 +724,15 @@ static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
}
/**
- * set_mode_freq - Switch tuner to other mode.
- * @client: struct i2c_client pointer
+ * set_mode - Switch tuner to other mode.
* @t: a pointer to the module's internal struct_tuner
* @mode: enum v4l2_type (radio or TV)
- * @freq: frequency to set (0 means to use the previous one)
*
* If tuner doesn't support the needed mode (radio or TV), prints a
* debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the state and sets frequency to the last value, if
- * the tuner can sleep or if it supports both Radio and TV.
+ * Otherwise, changes the mode and returns 0.
*/
-static int set_mode_freq(struct i2c_client *client, struct tuner *t,
- enum v4l2_tuner_type mode, unsigned int freq)
+static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
{
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
@@ -752,17 +748,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t,
t->mode = mode;
tuner_dbg("Changing to mode %d\n", mode);
}
+ return 0;
+}
+
+/**
+ * set_freq - Set the tuner to the desired frequency.
+ * @t: a pointer to the module's internal struct_tuner
+ * @freq: frequency to set (0 means to use the current frequency)
+ */
+static void set_freq(struct tuner *t, unsigned int freq)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
if (t->mode == V4L2_TUNER_RADIO) {
- if (freq)
- t->radio_freq = freq;
- set_radio_freq(client, t->radio_freq);
+ if (!freq)
+ freq = t->radio_freq;
+ set_radio_freq(client, freq);
} else {
- if (freq)
- t->tv_freq = freq;
- set_tv_freq(client, t->tv_freq);
+ if (!freq)
+ freq = t->tv_freq;
+ set_tv_freq(client, freq);
}
-
- return 0;
}
/*
@@ -1058,10 +1064,9 @@ static void tuner_status(struct dvb_frontend *fe)
static int tuner_s_radio(struct v4l2_subdev *sd)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
- return 0;
+ if (set_mode(t, V4L2_TUNER_RADIO) == 0)
+ set_freq(t, 0);
return 0;
}
@@ -1093,25 +1098,22 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
+ if (set_mode(t, V4L2_TUNER_ANALOG_TV))
return 0;
t->std = std;
tuner_fixup_std(t);
-
+ set_freq(t, 0);
return 0;
}
static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
- return 0;
+ if (set_mode(t, f->type) == 0)
+ set_freq(t, f->frequency);
return 0;
}
@@ -1180,13 +1182,13 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
+ if (set_mode(t, vt->type))
return 0;
if (t->mode == V4L2_TUNER_RADIO)
t->audmode = vt->audmode;
+ set_freq(t, 0);
return 0;
}
@@ -1221,7 +1223,8 @@ static int tuner_resume(struct i2c_client *c)
tuner_dbg("resume\n");
if (!t->standby)
- set_mode_freq(c, t, t->type, 0);
+ if (set_mode(t, t->mode) == 0)
+ set_freq(t, 0);
return 0;
}
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 506edcc..a2e442a 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_tuner)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
ret = ops->vidioc_g_tuner(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_s_tuner)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
dbgarg(cmd, "index=%d, name=%s, type=%d, "
"capability=0x%x, rangelow=%d, "
"rangehigh=%d, signal=%d, afc=%d, "
@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_frequency)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
ret = ops->vidioc_g_frequency(file, fh, p);
if (!ret)
dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index a19967d..ba31abe 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -74,7 +74,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
if (boarddata && gpio_is_valid(boarddata->cd_gpio)
&& gpio_get_value(boarddata->cd_gpio))
/* no card, if a valid gpio says so... */
- val &= SDHCI_CARD_PRESENT;
+ val &= ~SDHCI_CARD_PRESENT;
else
/* ... in all other cases assume card is present */
val |= SDHCI_CARD_PRESENT;
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index 3c44689..2e251f6 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -265,7 +265,9 @@ ath5k_pci_remove(struct pci_dev *pdev)
#ifdef CONFIG_PM_SLEEP
static int ath5k_pci_suspend(struct device *dev)
{
- struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev));
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath5k_softc *sc = hw->priv;
ath5k_led_off(sc);
return 0;
@@ -274,7 +276,8 @@ static int ath5k_pci_suspend(struct device *dev)
static int ath5k_pci_resume(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
- struct ath5k_softc *sc = pci_get_drvdata(pdev);
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct ath5k_softc *sc = hw->priv;
/*
* Suspend/Resume resets the PCI configuration space, so we have to
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c
index 929c68c..a073cdc 100644
--- a/drivers/net/wireless/ath/ath5k/sysfs.c
+++ b/drivers/net/wireless/ath/ath5k/sysfs.c
@@ -10,7 +10,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
- struct ath5k_softc *sc = dev_get_drvdata(dev); \
+ struct ieee80211_hw *hw = dev_get_drvdata(dev); \
+ struct ath5k_softc *sc = hw->priv; \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
} \
\
@@ -18,7 +19,8 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
- struct ath5k_softc *sc = dev_get_drvdata(dev); \
+ struct ieee80211_hw *hw = dev_get_drvdata(dev); \
+ struct ath5k_softc *sc = hw->priv; \
int val; \
\
val = (int)simple_strtoul(buf, NULL, 10); \
@@ -33,7 +35,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
- struct ath5k_softc *sc = dev_get_drvdata(dev); \
+ struct ieee80211_hw *hw = dev_get_drvdata(dev); \
+ struct ath5k_softc *sc = hw->priv; \
return snprintf(buf, PAGE_SIZE, "%d\n", get); \
} \
static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 88fa7fd..4f2c8df 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -662,7 +662,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
* TODO - this could be improved to be dependent on the rate.
* The hardware can keep up at lower rates, but not higher rates
*/
- if (fi->keyix != ATH9K_TXKEYIX_INVALID)
+ if ((fi->keyix != ATH9K_TXKEYIX_INVALID) &&
+ !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))
ndelim += ATH_AGGR_ENCRYPTDELIM;
/*
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index 2fb53d0..333b69e 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -112,6 +112,8 @@ static struct usb_device_id carl9170_usb_ids[] = {
{ USB_DEVICE(0x04bb, 0x093f) },
/* NEC WL300NU-G */
{ USB_DEVICE(0x0409, 0x0249) },
+ /* NEC WL300NU-AG */
+ { USB_DEVICE(0x0409, 0x02b4) },
/* AVM FRITZ!WLAN USB Stick N */
{ USB_DEVICE(0x057c, 0x8401) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 71244a3..91bf182 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -278,6 +278,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
+ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
{RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
{RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
/* HP - Lite-On ,8188CUS Slim Combo */
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index a5747c2..362e3b3 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2755,6 +2755,29 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+
+ /*
+ * RICOH 0xe823 SD/MMC card reader fails to recognize
+ * certain types of SD/MMC cards. Lowering the SD base
+ * clock frequency from 200Mhz to 50Mhz fixes this issue.
+ *
+ * 0x150 - SD2.0 mode enable for changing base clock
+ * frequency to 50Mhz
+ * 0xe1 - Base clock frequency
+ * 0x32 - 50Mhz new clock frequency
+ * 0xf9 - Key register for 0x150
+ * 0xfc - key register for 0xe1
+ */
+ if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) {
+ pci_write_config_byte(dev, 0xf9, 0xfc);
+ pci_write_config_byte(dev, 0x150, 0x10);
+ pci_write_config_byte(dev, 0xf9, 0x00);
+ pci_write_config_byte(dev, 0xfc, 0x01);
+ pci_write_config_byte(dev, 0xe1, 0x32);
+ pci_write_config_byte(dev, 0xfc, 0x00);
+
+ dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
+ }
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index de301aa8..fdfb9e7 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -290,12 +290,9 @@ static int dell_rfkill_set(void *data, bool blocked)
dell_send_request(buffer, 17, 11);
/* If the hardware switch controls this radio, and the hardware
- switch is disabled, don't allow changing the software state.
- If the hardware switch is reported as not supported, always
- fire the SMI to toggle the killswitch. */
+ switch is disabled, don't allow changing the software state */
if ((hwswitch_state & BIT(hwswitch_bit)) &&
- !(buffer->output[1] & BIT(16)) &&
- (buffer->output[1] & BIT(0))) {
+ !(buffer->output[1] & BIT(16))) {
ret = -EINVAL;
goto out;
}
@@ -401,23 +398,6 @@ static const struct file_operations dell_debugfs_fops = {
static void dell_update_rfkill(struct work_struct *ignored)
{
- int status;
-
- get_buffer();
- dell_send_request(buffer, 17, 11);
- status = buffer->output[1];
- release_buffer();
-
- /* if hardware rfkill is not supported, set it explicitly */
- if (!(status & BIT(0))) {
- if (wifi_rfkill)
- dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
- if (bluetooth_rfkill)
- dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
- if (wwan_rfkill)
- dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
- }
-
if (wifi_rfkill)
dell_rfkill_query(wifi_rfkill, (void *)1);
if (bluetooth_rfkill)
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 30461fc..0c20831 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
+ { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 1b025f7..ca0d237 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -144,3 +144,7 @@
/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
#define ADLINK_VENDOR_ID 0x0b63
#define ADLINK_ND6530_PRODUCT_ID 0x6530
+
+/* WinChipHead USB->RS 232 adapter */
+#define WINCHIPHEAD_VENDOR_ID 0x4348
+#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 5236582..01db14c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2571,23 +2571,6 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
else /* default */
cifs_sb->rsize = CIFSMaxBufSize;
- if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
- cERROR(1, "wsize %d too large, using 4096 instead",
- pvolume_info->wsize);
- cifs_sb->wsize = 4096;
- } else if (pvolume_info->wsize)
- cifs_sb->wsize = pvolume_info->wsize;
- else
- cifs_sb->wsize = min_t(const int,
- PAGEVEC_SIZE * PAGE_CACHE_SIZE,
- 127*1024);
- /* old default of CIFSMaxBufSize was too small now
- that SMB Write2 can send multiple pages in kvec.
- RFC1001 does not describe what happens when frame
- bigger than 128K is sent so use that as max in
- conjunction with 52K kvec constraint on arch with 4K
- page size */
-
if (cifs_sb->rsize < 2048) {
cifs_sb->rsize = 2048;
/* Windows ME may prefer this */
@@ -2665,6 +2648,48 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
"mount option supported");
}
+/* Prior to 3.0, cifs couldn't handle writes larger than this */
+#define CIFS_MAX_WSIZE (PAGEVEC_SIZE * PAGE_CACHE_SIZE)
+
+/*
+ * When the server doesn't allow large posix writes, only allow a wsize of
+ * 128k minus the size of the WRITE_AND_X header. That allows for a write up
+ * to the maximum size described by RFC1002.
+ */
+#define CIFS_MAX_RFC1002_WSIZE (128 * 1024 - sizeof(WRITE_REQ) + 4)
+
+/* Make the default the same as the max */
+#define CIFS_DEFAULT_WSIZE CIFS_MAX_WSIZE
+
+static unsigned int
+cifs_negotiate_wsize(struct cifsTconInfo *tcon, struct smb_vol *pvolume_info)
+{
+ __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
+ struct TCP_Server_Info *server = tcon->ses->server;
+ unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
+ CIFS_DEFAULT_WSIZE;
+
+ /* can server support 24-bit write sizes? (via UNIX extensions) */
+ if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
+ wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE);
+
+ /*
+ * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set?
+ * Limit it to max buffer offered by the server, minus the size of the
+ * WRITEX header, not including the 4 byte RFC1001 length.
+ */
+ if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
+ (!(server->capabilities & CAP_UNIX) &&
+ (server->secMode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED))))
+ wsize = min_t(unsigned int, wsize,
+ server->maxBuf - sizeof(WRITE_REQ) + 4);
+
+ /* hard limit of CIFS_MAX_WSIZE */
+ wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
+
+ return wsize;
+}
+
static int
is_path_accessible(int xid, struct cifsTconInfo *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path)
@@ -2866,13 +2891,12 @@ try_mount_again:
cifs_sb->rsize = 1024 * 127;
cFYI(DBG2, "no very large read support, rsize now 127K");
}
- if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
- cifs_sb->wsize = min(cifs_sb->wsize,
- (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
cifs_sb->rsize = min(cifs_sb->rsize,
(tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
+ cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
+
remote_path_check:
/* check if a whole path (including prepath) is not remote */
if (!rc && tcon) {
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index e28c0f2..e6ea384 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4635,6 +4635,9 @@ static int ext4_quota_off(struct super_block *sb, int type)
if (test_opt(sb, DELALLOC))
sync_filesystem(sb);
+ if (!inode)
+ goto out;
+
/* Update modification times of quota files when userspace can
* start looking at them */
handle = ext4_journal_start(inode, 1);
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 52b59e2..fd03b0e 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -989,16 +989,12 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
pagevec_init(&pvec, 0);
next = 0;
- while (next <= (loff_t)-1 &&
- pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)
- ) {
+ do {
+ if (!pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE))
+ break;
for (i = 0; i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
- pgoff_t page_index = page->index;
-
- ASSERTCMP(page_index, >=, next);
- next = page_index + 1;
-
+ next = page->index;
if (PageFsCache(page)) {
__fscache_wait_on_page_write(cookie, page);
__fscache_uncache_page(cookie, page);
@@ -1006,7 +1002,7 @@ void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
}
pagevec_release(&pvec);
cond_resched();
- }
+ } while (++next);
_leave("");
}
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index e483108..418728f 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -826,6 +826,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
loff_t bytes, max_bytes;
struct gfs2_alloc *al;
int error;
+ loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1);
loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift;
next = (next + 1) << sdp->sd_sb.sb_bsize_shift;
@@ -833,13 +834,15 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset,
if (mode & ~FALLOC_FL_KEEP_SIZE)
return -EOPNOTSUPP;
- offset = (offset >> sdp->sd_sb.sb_bsize_shift) <<
- sdp->sd_sb.sb_bsize_shift;
+ offset &= bsize_mask;
len = next - offset;
bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2;
if (!bytes)
bytes = UINT_MAX;
+ bytes &= bsize_mask;
+ if (bytes == 0)
+ bytes = sdp->sd_sb.sb_bsize;
gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh);
error = gfs2_glock_nq(&ip->i_gh);
@@ -870,6 +873,9 @@ retry:
if (error) {
if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) {
bytes >>= 1;
+ bytes &= bsize_mask;
+ if (bytes == 0)
+ bytes = sdp->sd_sb.sb_bsize;
goto retry;
}
goto out_qunlock;
diff --git a/fs/namei.c b/fs/namei.c
index 6ff858c..732a754 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1013,7 +1013,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
* Don't forget we might have a non-mountpoint managed dentry
* that wants to block transit.
*/
- *inode = path->dentry->d_inode;
if (!reverse_transit &&
unlikely(managed_dentry_might_block(path->dentry)))
return false;
@@ -1027,6 +1026,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
path->mnt = mounted;
path->dentry = mounted->mnt_root;
nd->seq = read_seqcount_begin(&path->dentry->d_seq);
+ /*
+ * Update the inode too. We don't need to re-check the
+ * dentry sequence number here after this d_inode read,
+ * because a mount-point is always pinned.
+ */
+ *inode = path->dentry->d_inode;
}
if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 7685279..a58bd56 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -91,7 +91,7 @@ static int nfs4_stat_to_errno(int);
#define encode_getfh_maxsz (op_encode_hdr_maxsz)
#define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \
((3+NFS4_FHSIZE) >> 2))
-#define nfs4_fattr_bitmap_maxsz 3
+#define nfs4_fattr_bitmap_maxsz 4
#define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
#define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index 19d6750..6296b40 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -310,6 +310,15 @@ static int is_gpt_valid(struct parsed_partitions *state, u64 lba,
goto fail;
}
+ /* Check the GUID Partition Table header size */
+ if (le32_to_cpu((*gpt)->header_size) >
+ bdev_logical_block_size(state->bdev)) {
+ pr_debug("GUID Partition Table Header size is wrong: %u > %u\n",
+ le32_to_cpu((*gpt)->header_size),
+ bdev_logical_block_size(state->bdev));
+ goto fail;
+ }
+
/* Check the GUID Partition Table CRC */
origcrc = le32_to_cpu((*gpt)->header_crc32);
(*gpt)->header_crc32 = 0;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index dfa5327..0352336 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2762,6 +2762,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
struct task_io_accounting acct = task->ioac;
unsigned long flags;
+ if (!ptrace_may_access(task, PTRACE_MODE_READ))
+ return -EACCES;
+
if (whole && lock_task_sighand(task, &flags)) {
struct task_struct *t = task;
@@ -2892,7 +2895,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
#endif
#ifdef CONFIG_TASK_IO_ACCOUNTING
- INF("io", S_IRUGO, proc_tgid_io_accounting),
+ INF("io", S_IRUSR, proc_tgid_io_accounting),
#endif
};
@@ -3230,7 +3233,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
#endif
#ifdef CONFIG_TASK_IO_ACCOUNTING
- INF("io", S_IRUGO, proc_tid_io_accounting),
+ INF("io", S_IRUSR, proc_tid_io_accounting),
#endif
};
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 27d64d7..a892ed9 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -2610,6 +2610,12 @@ restart:
new->bno + new->length) -
min(busyp->bno, new->bno);
new->bno = min(busyp->bno, new->bno);
+ /*
+ * Start the search over from the tree root, because
+ * erasing the node can rearrange the tree topology.
+ */
+ spin_unlock(&pag->pagb_lock);
+ goto restart;
} else
busyp = NULL;
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index f04b2a3..06cd510 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -182,6 +182,7 @@
{0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
@@ -192,6 +193,7 @@
{0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 0249fe7..66b22bf 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1680,9 +1680,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
unsigned int offset)
{
+ if (!pskb_may_pull(skb, hlen))
+ return NULL;
+
NAPI_GRO_CB(skb)->frag0 = NULL;
NAPI_GRO_CB(skb)->frag0_len = 0;
- return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
+ return skb->data + offset;
}
static inline void *skb_gro_mac_header(struct sk_buff *skb)
diff --git a/mm/compaction.c b/mm/compaction.c
index 021a296..e4e0166 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -144,9 +144,20 @@ static void isolate_freepages(struct zone *zone,
int nr_freepages = cc->nr_freepages;
struct list_head *freelist = &cc->freepages;
+ /*
+ * Initialise the free scanner. The starting point is where we last
+ * scanned from (or the end of the zone if starting). The low point
+ * is the end of the pageblock the migration scanner is using.
+ */
pfn = cc->free_pfn;
low_pfn = cc->migrate_pfn + pageblock_nr_pages;
- high_pfn = low_pfn;
+
+ /*
+ * Take care that if the migration scanner is at the end of the zone
+ * that the free scanner does not accidentally move to the next zone
+ * in the next isolation cycle.
+ */
+ high_pfn = min(low_pfn, pfn);
/*
* Isolate free pages until enough are available to migrate the
@@ -240,11 +251,18 @@ static bool too_many_isolated(struct zone *zone)
return isolated > (inactive + active) / 2;
}
+/* possible outcome of isolate_migratepages */
+typedef enum {
+ ISOLATE_ABORT, /* Abort compaction now */
+ ISOLATE_NONE, /* No pages isolated, continue scanning */
+ ISOLATE_SUCCESS, /* Pages isolated, migrate */
+} isolate_migrate_t;
+
/*
* Isolate all pages that can be migrated from the block pointed to by
* the migrate scanner within compact_control.
*/
-static unsigned long isolate_migratepages(struct zone *zone,
+static isolate_migrate_t isolate_migratepages(struct zone *zone,
struct compact_control *cc)
{
unsigned long low_pfn, end_pfn;
@@ -261,7 +279,7 @@ static unsigned long isolate_migratepages(struct zone *zone,
/* Do not cross the free scanner or scan within a memory hole */
if (end_pfn > cc->free_pfn || !pfn_valid(low_pfn)) {
cc->migrate_pfn = end_pfn;
- return 0;
+ return ISOLATE_NONE;
}
/*
@@ -270,10 +288,14 @@ static unsigned long isolate_migratepages(struct zone *zone,
* delay for some time until fewer pages are isolated
*/
while (unlikely(too_many_isolated(zone))) {
+ /* async migration should just abort */
+ if (!cc->sync)
+ return ISOLATE_ABORT;
+
congestion_wait(BLK_RW_ASYNC, HZ/10);
if (fatal_signal_pending(current))
- return 0;
+ return ISOLATE_ABORT;
}
/* Time to isolate some pages for migration */
@@ -358,7 +380,7 @@ static unsigned long isolate_migratepages(struct zone *zone,
trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
- return cc->nr_migratepages;
+ return ISOLATE_SUCCESS;
}
/*
@@ -522,8 +544,15 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
unsigned long nr_migrate, nr_remaining;
int err;
- if (!isolate_migratepages(zone, cc))
+ switch (isolate_migratepages(zone, cc)) {
+ case ISOLATE_ABORT:
+ ret = COMPACT_PARTIAL;
+ goto out;
+ case ISOLATE_NONE:
continue;
+ case ISOLATE_SUCCESS:
+ ;
+ }
nr_migrate = cc->nr_migratepages;
err = migrate_pages(&cc->migratepages, compaction_alloc,
@@ -547,6 +576,7 @@ static int compact_zone(struct zone *zone, struct compact_control *cc)
}
+out:
/* Release free pages and check accounting */
cc->nr_freepages -= release_freepages(&cc->freepages);
VM_BUG_ON(cc->nr_freepages != 0);
diff --git a/mm/nommu.c b/mm/nommu.c
index c4c542c..0376a4c 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1819,10 +1819,13 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
return NULL;
}
-int remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
- unsigned long to, unsigned long size, pgprot_t prot)
+int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long pfn, unsigned long size, pgprot_t prot)
{
- vma->vm_start = vma->vm_pgoff << PAGE_SHIFT;
+ if (addr != (pfn << PAGE_SHIFT))
+ return -EINVAL;
+
+ vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
return 0;
}
EXPORT_SYMBOL(remap_pfn_range);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f52e85c..5299cb8 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -285,7 +285,7 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
do_each_thread(g, p) {
unsigned int points;
- if (!p->mm)
+ if (p->exit_state)
continue;
if (oom_unkillable_task(p, mem, nodemask))
continue;
@@ -301,6 +301,8 @@ static struct task_struct *select_bad_process(unsigned int *ppoints,
*/
if (test_tsk_thread_flag(p, TIF_MEMDIE))
return ERR_PTR(-1UL);
+ if (!p->mm)
+ continue;
if (p->flags & PF_EXITING) {
/*
diff --git a/mm/vmscan.c b/mm/vmscan.c
index cc1470b..7f3270f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1114,8 +1114,20 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
nr_lumpy_dirty++;
scan++;
} else {
- /* the page is freed already. */
- if (!page_count(cursor_page))
+ /*
+ * Check if the page is freed already.
+ *
+ * We can't use page_count() as that
+ * requires compound_head and we don't
+ * have a pin on the page here. If a
+ * page is tail, we may or may not
+ * have isolated the head, so assume
+ * it's not free, it'd be tricky to
+ * track the head status without a
+ * page pin.
+ */
+ if (!PageTail(cursor_page) &&
+ !atomic_read(&cursor_page->_count))
continue;
break;
}
@@ -2245,7 +2257,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages,
for (i = 0; i <= classzone_idx; i++)
present_pages += pgdat->node_zones[i].present_pages;
- return balanced_pages > (present_pages >> 2);
+ /* A special case here: if zone has no page, we think it's balanced */
+ return balanced_pages >= (present_pages >> 2);
}
/* is kswapd sleeping prematurely? */
@@ -2261,7 +2274,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
return true;
/* Check the watermark levels */
- for (i = 0; i < pgdat->nr_zones; i++) {
+ for (i = 0; i <= classzone_idx; i++) {
struct zone *zone = pgdat->node_zones + i;
if (!populated_zone(zone))
@@ -2279,7 +2292,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining,
}
if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
- classzone_idx, 0))
+ i, 0))
all_zones_ok = false;
else
balanced += zone->present_pages;
@@ -2381,7 +2394,6 @@ loop_again:
if (!zone_watermark_ok_safe(zone, order,
high_wmark_pages(zone), 0, 0)) {
end_zone = i;
- *classzone_idx = i;
break;
}
}
@@ -2436,19 +2448,19 @@ loop_again:
KSWAPD_ZONE_BALANCE_GAP_RATIO);
if (!zone_watermark_ok_safe(zone, order,
high_wmark_pages(zone) + balance_gap,
- end_zone, 0))
+ end_zone, 0)) {
shrink_zone(priority, zone, &sc);
- reclaim_state->reclaimed_slab = 0;
- nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
- lru_pages);
- sc.nr_reclaimed += reclaim_state->reclaimed_slab;
- total_scanned += sc.nr_scanned;
- if (zone->all_unreclaimable)
- continue;
- if (nr_slab == 0 &&
- !zone_reclaimable(zone))
- zone->all_unreclaimable = 1;
+ reclaim_state->reclaimed_slab = 0;
+ nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
+ lru_pages);
+ sc.nr_reclaimed += reclaim_state->reclaimed_slab;
+ total_scanned += sc.nr_scanned;
+
+ if (nr_slab == 0 && !zone_reclaimable(zone))
+ zone->all_unreclaimable = 1;
+ }
+
/*
* If we've done a decent amount of scanning and
* the reclaim ratio is low, start doing writepage
@@ -2458,6 +2470,12 @@ loop_again:
total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
sc.may_writepage = 1;
+ if (zone->all_unreclaimable) {
+ if (end_zone && end_zone == i)
+ end_zone--;
+ continue;
+ }
+
if (!zone_watermark_ok_safe(zone, order,
high_wmark_pages(zone), end_zone, 0)) {
all_zones_ok = 0;
@@ -2636,8 +2654,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx)
*/
static int kswapd(void *p)
{
- unsigned long order;
- int classzone_idx;
+ unsigned long order, new_order;
+ int classzone_idx, new_classzone_idx;
pg_data_t *pgdat = (pg_data_t*)p;
struct task_struct *tsk = current;
@@ -2667,17 +2685,23 @@ static int kswapd(void *p)
tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
set_freezable();
- order = 0;
- classzone_idx = MAX_NR_ZONES - 1;
+ order = new_order = 0;
+ classzone_idx = new_classzone_idx = pgdat->nr_zones - 1;
for ( ; ; ) {
- unsigned long new_order;
- int new_classzone_idx;
int ret;
- new_order = pgdat->kswapd_max_order;
- new_classzone_idx = pgdat->classzone_idx;
- pgdat->kswapd_max_order = 0;
- pgdat->classzone_idx = MAX_NR_ZONES - 1;
+ /*
+ * If the last balance_pgdat was unsuccessful it's unlikely a
+ * new request of a similar or harder type will succeed soon
+ * so consider going to sleep on the basis we reclaimed at
+ */
+ if (classzone_idx >= new_classzone_idx && order == new_order) {
+ new_order = pgdat->kswapd_max_order;
+ new_classzone_idx = pgdat->classzone_idx;
+ pgdat->kswapd_max_order = 0;
+ pgdat->classzone_idx = pgdat->nr_zones - 1;
+ }
+
if (order < new_order || classzone_idx > new_classzone_idx) {
/*
* Don't sleep if someone wants a larger 'order'
@@ -2690,7 +2714,7 @@ static int kswapd(void *p)
order = pgdat->kswapd_max_order;
classzone_idx = pgdat->classzone_idx;
pgdat->kswapd_max_order = 0;
- pgdat->classzone_idx = MAX_NR_ZONES - 1;
+ pgdat->classzone_idx = pgdat->nr_zones - 1;
}
ret = try_to_freeze();
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 387013d..5e9ae57 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -123,6 +123,7 @@ struct net_bridge_port
bridge_id designated_bridge;
u32 path_cost;
u32 designated_cost;
+ unsigned long designated_age;
struct timer_list forward_delay_timer;
struct timer_list hold_timer;
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 7370d14..c24ae0d 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -164,8 +164,7 @@ void br_transmit_config(struct net_bridge_port *p)
else {
struct net_bridge_port *root
= br_get_port(br, br->root_port);
- bpdu.message_age = br->max_age
- - (root->message_age_timer.expires - jiffies)
+ bpdu.message_age = (jiffies - root->designated_age)
+ MESSAGE_AGE_INCR;
}
bpdu.max_age = br->max_age;
@@ -189,6 +188,7 @@ static inline void br_record_config_information(struct net_bridge_port *p,
p->designated_cost = bpdu->root_path_cost;
p->designated_bridge = bpdu->bridge_id;
p->designated_port = bpdu->port_id;
+ p->designated_age = jiffies + bpdu->message_age;
mod_timer(&p->message_age_timer, jiffies
+ (p->br->max_age - bpdu->message_age));
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index f1765de..3814b81 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -86,6 +86,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ int queue = rx->queue;
+
+ /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
+ if (rx->queue == NUM_RX_DATA_QUEUES - 1)
+ queue = 0;
/* No way to verify the MIC if the hardware stripped it */
if (status->flag & RX_FLAG_MMIC_STRIPPED)
@@ -119,8 +124,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
/* update IV in key information to be able to detect replays */
- rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32;
- rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16;
+ rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32;
+ rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16;
return RX_CONTINUE;
}
@@ -201,6 +206,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
struct ieee80211_key *key = rx->key;
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+ int queue = rx->queue;
+
+ /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */
+ if (rx->queue == NUM_RX_DATA_QUEUES - 1)
+ queue = 0;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -221,7 +231,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
key, skb->data + hdrlen,
skb->len - hdrlen, rx->sta->sta.addr,
- hdr->addr1, hwaccel, rx->queue,
+ hdr->addr1, hwaccel, queue,
&rx->tkip_iv32,
&rx->tkip_iv16);
if (res != TKIP_DECRYPT_OK)
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index c652e4c..9574bc4 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -528,7 +528,7 @@ void rpcb_getport_async(struct rpc_task *task)
u32 bind_version;
struct rpc_xprt *xprt;
struct rpc_clnt *rpcb_clnt;
- static struct rpcbind_args *map;
+ struct rpcbind_args *map;
struct rpc_task *child;
struct sockaddr_storage addr;
struct sockaddr *sap = (struct sockaddr *)&addr;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index a27406b..4814e24 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -616,30 +616,25 @@ static void __rpc_execute(struct rpc_task *task)
BUG_ON(RPC_IS_QUEUED(task));
for (;;) {
+ void (*do_action)(struct rpc_task *);
/*
- * Execute any pending callback.
+ * Execute any pending callback first.
*/
- if (task->tk_callback) {
- void (*save_callback)(struct rpc_task *);
-
- /*
- * We set tk_callback to NULL before calling it,
- * in case it sets the tk_callback field itself:
- */
- save_callback = task->tk_callback;
- task->tk_callback = NULL;
- save_callback(task);
- } else {
+ do_action = task->tk_callback;
+ task->tk_callback = NULL;
+ if (do_action == NULL) {
/*
* Perform the next FSM step.
- * tk_action may be NULL when the task has been killed
- * by someone else.
+ * tk_action may be NULL if the task has been killed.
+ * In particular, note that rpc_killall_tasks may
+ * do this at any time, so beware when dereferencing.
*/
- if (task->tk_action == NULL)
+ do_action = task->tk_action;
+ if (do_action == NULL)
break;
- task->tk_action(task);
}
+ do_action(task);
/*
* Lockless check for whether task is sleeping or not.
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 890a0dc..bd11e33 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -138,11 +138,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
pr_debug("%s enter\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
diff = sport_curr_offset_tx(sport);
- frames = bytes_to_frames(substream->runtime, diff);
} else {
diff = sport_curr_offset_rx(sport);
- frames = bytes_to_frames(substream->runtime, diff);
}
+
+ /*
+ * TX at least can report one frame beyond the end of the
+ * buffer if we hit the wraparound case - clamp to within the
+ * buffer as the ALSA APIs require.
+ */
+ if (diff == snd_pcm_lib_buffer_bytes(substream))
+ diff = 0;
+
+ frames = bytes_to_frames(substream->runtime, diff);
+
return frames;
}
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 4be0570..65f4604 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -357,7 +357,7 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
default:
return -EINVAL;
}
- snd_soc_update_bits(codec, PW_MGMT2, MS, data);
+ snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
/* format type */
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 84e1bd1..89acb0f 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1446,7 +1446,6 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"),
SND_SOC_DAPM_INPUT("DMIC2DAT"),
SND_SOC_DAPM_INPUT("Clock"),
-SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0),
SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev,
SND_SOC_DAPM_PRE_PMU),
@@ -1765,8 +1764,10 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = {
{ "AIF2DACDAT", NULL, "AIF1DACDAT" },
{ "AIF1ADCDAT", NULL, "AIF2ADCDAT" },
{ "AIF2ADCDAT", NULL, "AIF1ADCDAT" },
- { "MICBIAS", NULL, "CLK_SYS" },
- { "MICBIAS", NULL, "MICBIAS Supply" },
+ { "MICBIAS1", NULL, "CLK_SYS" },
+ { "MICBIAS1", NULL, "MICBIAS Supply" },
+ { "MICBIAS2", NULL, "CLK_SYS" },
+ { "MICBIAS2", NULL, "MICBIAS Supply" },
};
static const struct snd_soc_dapm_route wm8994_intercon[] = {
@@ -1969,6 +1970,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
reg);
+
+ msleep(5);
}
wm8994->fll[id].in = freq_in;
@@ -3018,7 +3021,7 @@ static void wm8958_default_micdet(u16 status, void *data)
report = SND_JACK_MICROPHONE;
/* Everything else is buttons; just assign slots */
- if (status & 0x1c0)
+ if (status & 0x1c)
report |= SND_JACK_BTN_0;
done:
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/