Merge branch 'sh/stable-updates' into sh-latest

This commit is contained in:
Paul Mundt 2011-06-21 17:47:44 +09:00
commit 9dd056e9eb
215 changed files with 2487 additions and 1483 deletions

View File

@ -843,6 +843,7 @@ Provides counts of softirq handlers serviced since boot time, for each cpu.
TASKLET: 0 0 0 290 TASKLET: 0 0 0 290
SCHED: 27035 26983 26971 26746 SCHED: 27035 26983 26971 26746
HRTIMER: 0 0 0 0 HRTIMER: 0 0 0 0
RCU: 1678 1769 2178 2250
1.3 IDE devices in /proc/ide 1.3 IDE devices in /proc/ide

View File

@ -2291,8 +2291,7 @@ F: drivers/scsi/eata_pio.*
EBTABLES EBTABLES
M: Bart De Schuymer <bart.de.schuymer@pandora.be> M: Bart De Schuymer <bart.de.schuymer@pandora.be>
L: ebtables-user@lists.sourceforge.net L: netfilter-devel@vger.kernel.org
L: ebtables-devel@lists.sourceforge.net
W: http://ebtables.sourceforge.net/ W: http://ebtables.sourceforge.net/
S: Maintained S: Maintained
F: include/linux/netfilter_bridge/ebt_*.h F: include/linux/netfilter_bridge/ebt_*.h
@ -6463,7 +6462,7 @@ M: Jiri Kosina <jkosina@suse.cz>
L: linux-usb@vger.kernel.org L: linux-usb@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
S: Maintained S: Maintained
F: Documentation/usb/hiddev.txt F: Documentation/hid/hiddev.txt
F: drivers/hid/usbhid/ F: drivers/hid/usbhid/
USB ISP116X DRIVER USB ISP116X DRIVER
@ -7007,6 +7006,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
S: Maintained S: Maintained
F: drivers/platform/x86 F: drivers/platform/x86
X86 MCE INFRASTRUCTURE
M: Tony Luck <tony.luck@intel.com>
M: Borislav Petkov <bp@amd64.org>
L: linux-edac@vger.kernel.org
S: Maintained
F: arch/x86/kernel/cpu/mcheck/*
XEN HYPERVISOR INTERFACE XEN HYPERVISOR INTERFACE
M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

View File

@ -1,7 +1,7 @@
VERSION = 3 VERSION = 3
PATCHLEVEL = 0 PATCHLEVEL = 0
SUBLEVEL = 0 SUBLEVEL = 0
EXTRAVERSION = -rc3 EXTRAVERSION = -rc4
NAME = Sneaky Weasel NAME = Sneaky Weasel
# *DOCUMENTATION* # *DOCUMENTATION*
@ -1526,7 +1526,8 @@ quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files))
# Run depmod only if we have System.map and depmod is executable # Run depmod only if we have System.map and depmod is executable
quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
cmd_depmod = $(srctree)/scripts/depmod.sh $(DEPMOD) $(KERNELRELEASE) cmd_depmod = $(CONFIG_SHELL) $(srctree)/scripts/depmod.sh $(DEPMOD) \
$(KERNELRELEASE)
# Create temporary dir for module support files # Create temporary dir for module support files
# clean it up only when building all modules # clean it up only when building all modules

View File

@ -23,6 +23,8 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <asm/hardware/gic.h>
#include <mach/msm_iomap.h> #include <mach/msm_iomap.h>
#include <mach/cpu.h> #include <mach/cpu.h>
@ -55,10 +57,12 @@ enum timer_location {
#if defined(CONFIG_ARCH_QSD8X50) #if defined(CONFIG_ARCH_QSD8X50)
#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */ #define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
#define MSM_DGT_SHIFT (0) #define MSM_DGT_SHIFT (0)
#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \ #elif defined(CONFIG_ARCH_MSM7X30)
defined(CONFIG_ARCH_MSM8960)
#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */ #define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
#define MSM_DGT_SHIFT (0) #define MSM_DGT_SHIFT (0)
#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */
#define MSM_DGT_SHIFT (0)
#else #else
#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */ #define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
#define MSM_DGT_SHIFT (5) #define MSM_DGT_SHIFT (5)
@ -100,7 +104,11 @@ static cycle_t msm_read_timer_count(struct clocksource *cs)
{ {
struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource); struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource);
return readl(clk->global_counter); /*
* Shift timer count down by a constant due to unreliable lower bits
* on some targets.
*/
return readl(clk->global_counter) >> clk->shift;
} }
static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt) static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt)

View File

@ -4,14 +4,14 @@
# Common support # Common support
obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
obj-y += clock.o clock_data.o opp_data.o reset.o obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o obj-$(CONFIG_PM) += pm.o sleep.o
# DSP # DSP
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o

View File

@ -56,9 +56,13 @@ static struct dev_power_domain default_power_domain = {
USE_PLATFORM_PM_SLEEP_OPS USE_PLATFORM_PM_SLEEP_OPS
}, },
}; };
#define OMAP1_PWR_DOMAIN (&default_power_domain)
#else
#define OMAP1_PWR_DOMAIN NULL
#endif /* CONFIG_PM_RUNTIME */
static struct pm_clk_notifier_block platform_bus_notifier = { static struct pm_clk_notifier_block platform_bus_notifier = {
.pwr_domain = &default_power_domain, .pwr_domain = OMAP1_PWR_DOMAIN,
.con_ids = { "ick", "fck", NULL, }, .con_ids = { "ick", "fck", NULL, },
}; };
@ -72,4 +76,4 @@ static int __init omap1_pm_runtime_init(void)
return 0; return 0;
} }
core_initcall(omap1_pm_runtime_init); core_initcall(omap1_pm_runtime_init);
#endif /* CONFIG_PM_RUNTIME */

View File

@ -84,7 +84,8 @@ static struct mtd_partition omap3pandora_nand_partitions[] = {
static struct omap_nand_platform_data pandora_nand_data = { static struct omap_nand_platform_data pandora_nand_data = {
.cs = 0, .cs = 0,
.devsize = 1, /* '0' for 8-bit, '1' for 16-bit device */ .devsize = NAND_BUSWIDTH_16,
.xfer_type = NAND_OMAP_PREFETCH_DMA,
.parts = omap3pandora_nand_partitions, .parts = omap3pandora_nand_partitions,
.nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions), .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
}; };

View File

@ -189,7 +189,7 @@ static struct dentry *pm_dbg_dir;
static int pm_dbg_init_done; static int pm_dbg_init_done;
static int __init pm_dbg_init(void); static int pm_dbg_init(void);
enum { enum {
DEBUG_FILE_COUNTERS = 0, DEBUG_FILE_COUNTERS = 0,
@ -595,7 +595,7 @@ static int option_set(void *data, u64 val)
DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n"); DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
static int __init pm_dbg_init(void) static int pm_dbg_init(void)
{ {
int i; int i;
struct dentry *d; struct dentry *d;

View File

@ -14,6 +14,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/apm-emulation.h> #include <linux/apm-emulation.h>

View File

@ -382,10 +382,8 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
} }
static struct sh_mobile_sdhi_info sh_sdhi1_platdata = { static struct sh_mobile_sdhi_info sh_sdhi1_platdata = {
.dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
.dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
.tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
.tmio_caps = MMC_CAP_NONREMOVABLE, .tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
.tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
.set_pwr = ag5evm_sdhi1_set_pwr, .set_pwr = ag5evm_sdhi1_set_pwr,
}; };

View File

@ -126,7 +126,7 @@
* ------+--------------------+--------------------+------- * ------+--------------------+--------------------+-------
* IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low * IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
* IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High * IRQ6 | ICR1A.IRQ6SA=0011 | Ether(LAN9220) | High
* IRQ7 | ICR1A.IRQ7SA=0010 | LCD Tuch Panel | Low * IRQ7 | ICR1A.IRQ7SA=0010 | LCD Touch Panel | Low
* IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low * IRQ8 | ICR2A.IRQ8SA=0010 | MMC/SD card detect | Low
* IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low * IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
* IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
@ -165,10 +165,10 @@
* USB1 can become Host by r8a66597, and become Function by renesas_usbhs. * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
* But don't select both drivers in same time. * But don't select both drivers in same time.
* These uses same IRQ number for request_irq(), and aren't supporting * These uses same IRQ number for request_irq(), and aren't supporting
* IRQF_SHARD / IORESOURCE_IRQ_SHAREABLE. * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
* *
* Actually these are old/new version of USB driver. * Actually these are old/new version of USB driver.
* This mean its register will be broken if it supports SHARD IRQ, * This mean its register will be broken if it supports shared IRQ,
*/ */
/* /*
@ -562,7 +562,121 @@ out:
clk_put(hdmi_ick); clk_put(hdmi_ick);
} }
/* USB1 (Host) */ /* USBHS0 is connected to CN22 which takes a USB Mini-B plug
*
* The sh7372 SoC has IRQ7 set aside for USBHS0 hotplug,
* but on this particular board IRQ7 is already used by
* the touch screen. This leaves us with software polling.
*/
#define USBHS0_POLL_INTERVAL (HZ * 5)
struct usbhs_private {
unsigned int usbphyaddr;
unsigned int usbcrcaddr;
struct renesas_usbhs_platform_info info;
struct delayed_work work;
struct platform_device *pdev;
};
#define usbhs_get_priv(pdev) \
container_of(renesas_usbhs_get_info(pdev), \
struct usbhs_private, info)
#define usbhs_is_connected(priv) \
(!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
static int usbhs_get_vbus(struct platform_device *pdev)
{
return usbhs_is_connected(usbhs_get_priv(pdev));
}
static void usbhs_phy_reset(struct platform_device *pdev)
{
struct usbhs_private *priv = usbhs_get_priv(pdev);
/* init phy */
__raw_writew(0x8a0a, priv->usbcrcaddr);
}
static int usbhs0_get_id(struct platform_device *pdev)
{
return USBHS_GADGET;
}
static void usbhs0_work_function(struct work_struct *work)
{
struct usbhs_private *priv = container_of(work, struct usbhs_private,
work.work);
renesas_usbhs_call_notify_hotplug(priv->pdev);
schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
}
static int usbhs0_hardware_init(struct platform_device *pdev)
{
struct usbhs_private *priv = usbhs_get_priv(pdev);
priv->pdev = pdev;
INIT_DELAYED_WORK(&priv->work, usbhs0_work_function);
schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
return 0;
}
static void usbhs0_hardware_exit(struct platform_device *pdev)
{
struct usbhs_private *priv = usbhs_get_priv(pdev);
cancel_delayed_work_sync(&priv->work);
}
static struct usbhs_private usbhs0_private = {
.usbcrcaddr = 0xe605810c, /* USBCR2 */
.info = {
.platform_callback = {
.hardware_init = usbhs0_hardware_init,
.hardware_exit = usbhs0_hardware_exit,
.phy_reset = usbhs_phy_reset,
.get_id = usbhs0_get_id,
.get_vbus = usbhs_get_vbus,
},
.driver_param = {
.buswait_bwait = 4,
},
},
};
static struct resource usbhs0_resources[] = {
[0] = {
.name = "USBHS0",
.start = 0xe6890000,
.end = 0xe68900e6 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = evt2irq(0x1ca0) /* USB0_USB0I0 */,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usbhs0_device = {
.name = "renesas_usbhs",
.id = 0,
.dev = {
.platform_data = &usbhs0_private.info,
},
.num_resources = ARRAY_SIZE(usbhs0_resources),
.resource = usbhs0_resources,
};
/* USBHS1 is connected to CN31 which takes a USB Mini-AB plug
*
* Use J30 to select between Host and Function. This setting
* can however not be detected by software. Hotplug of USBHS1
* is provided via IRQ8.
*/
#define IRQ8 evt2irq(0x0300)
/* USBHS1 USB Host support via r8a66597_hcd */
static void usb1_host_port_power(int port, int power) static void usb1_host_port_power(int port, int power)
{ {
if (!power) /* only power-on is supported for now */ if (!power) /* only power-on is supported for now */
@ -579,9 +693,9 @@ static struct r8a66597_platdata usb1_host_data = {
static struct resource usb1_host_resources[] = { static struct resource usb1_host_resources[] = {
[0] = { [0] = {
.name = "USBHS", .name = "USBHS1",
.start = 0xE68B0000, .start = 0xe68b0000,
.end = 0xE68B00E6 - 1, .end = 0xe68b00e6 - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
@ -602,37 +716,14 @@ static struct platform_device usb1_host_device = {
.resource = usb1_host_resources, .resource = usb1_host_resources,
}; };
/* USB1 (Function) */ /* USBHS1 USB Function support via renesas_usbhs */
#define USB_PHY_MODE (1 << 4) #define USB_PHY_MODE (1 << 4)
#define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) #define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
#define USB_PHY_ON (1 << 1) #define USB_PHY_ON (1 << 1)
#define USB_PHY_OFF (1 << 0) #define USB_PHY_OFF (1 << 0)
#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF) #define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
struct usbhs_private {
unsigned int irq;
unsigned int usbphyaddr;
unsigned int usbcrcaddr;
struct renesas_usbhs_platform_info info;
};
#define usbhs_get_priv(pdev) \
container_of(renesas_usbhs_get_info(pdev), \
struct usbhs_private, info)
#define usbhs_is_connected(priv) \
(!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
static int usbhs1_get_id(struct platform_device *pdev)
{
return USBHS_GADGET;
}
static int usbhs1_get_vbus(struct platform_device *pdev)
{
return usbhs_is_connected(usbhs_get_priv(pdev));
}
static irqreturn_t usbhs1_interrupt(int irq, void *data) static irqreturn_t usbhs1_interrupt(int irq, void *data)
{ {
struct platform_device *pdev = data; struct platform_device *pdev = data;
@ -654,12 +745,10 @@ static int usbhs1_hardware_init(struct platform_device *pdev)
struct usbhs_private *priv = usbhs_get_priv(pdev); struct usbhs_private *priv = usbhs_get_priv(pdev);
int ret; int ret;
irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
/* clear interrupt status */ /* clear interrupt status */
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
ret = request_irq(priv->irq, usbhs1_interrupt, 0, ret = request_irq(IRQ8, usbhs1_interrupt, IRQF_TRIGGER_HIGH,
dev_name(&pdev->dev), pdev); dev_name(&pdev->dev), pdev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "request_irq err\n"); dev_err(&pdev->dev, "request_irq err\n");
@ -679,15 +768,12 @@ static void usbhs1_hardware_exit(struct platform_device *pdev)
/* clear interrupt status */ /* clear interrupt status */
__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
free_irq(priv->irq, pdev); free_irq(IRQ8, pdev);
} }
static void usbhs1_phy_reset(struct platform_device *pdev) static int usbhs1_get_id(struct platform_device *pdev)
{ {
struct usbhs_private *priv = usbhs_get_priv(pdev); return USBHS_GADGET;
/* init phy */
__raw_writew(0x8a0a, priv->usbcrcaddr);
} }
static u32 usbhs1_pipe_cfg[] = { static u32 usbhs1_pipe_cfg[] = {
@ -710,16 +796,15 @@ static u32 usbhs1_pipe_cfg[] = {
}; };
static struct usbhs_private usbhs1_private = { static struct usbhs_private usbhs1_private = {
.irq = evt2irq(0x0300), /* IRQ8 */ .usbphyaddr = 0xe60581e2, /* USBPHY1INTAP */
.usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */ .usbcrcaddr = 0xe6058130, /* USBCR4 */
.usbcrcaddr = 0xE6058130, /* USBCR4 */
.info = { .info = {
.platform_callback = { .platform_callback = {
.hardware_init = usbhs1_hardware_init, .hardware_init = usbhs1_hardware_init,
.hardware_exit = usbhs1_hardware_exit, .hardware_exit = usbhs1_hardware_exit,
.phy_reset = usbhs1_phy_reset,
.get_id = usbhs1_get_id, .get_id = usbhs1_get_id,
.get_vbus = usbhs1_get_vbus, .phy_reset = usbhs_phy_reset,
.get_vbus = usbhs_get_vbus,
}, },
.driver_param = { .driver_param = {
.buswait_bwait = 4, .buswait_bwait = 4,
@ -731,9 +816,9 @@ static struct usbhs_private usbhs1_private = {
static struct resource usbhs1_resources[] = { static struct resource usbhs1_resources[] = {
[0] = { [0] = {
.name = "USBHS", .name = "USBHS1",
.start = 0xE68B0000, .start = 0xe68b0000,
.end = 0xE68B00E6 - 1, .end = 0xe68b00e6 - 1,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
@ -752,7 +837,6 @@ static struct platform_device usbhs1_device = {
.resource = usbhs1_resources, .resource = usbhs1_resources,
}; };
/* LED */ /* LED */
static struct gpio_led mackerel_leds[] = { static struct gpio_led mackerel_leds[] = {
{ {
@ -1203,6 +1287,7 @@ static struct platform_device *mackerel_devices[] __initdata = {
&nor_flash_device, &nor_flash_device,
&smc911x_device, &smc911x_device,
&lcdc_device, &lcdc_device,
&usbhs0_device,
&usb1_host_device, &usb1_host_device,
&usbhs1_device, &usbhs1_device,
&leds_device, &leds_device,
@ -1301,6 +1386,7 @@ static void __init mackerel_map_io(void)
#define GPIO_PORT9CR 0xE6051009 #define GPIO_PORT9CR 0xE6051009
#define GPIO_PORT10CR 0xE605100A #define GPIO_PORT10CR 0xE605100A
#define GPIO_PORT167CR 0xE60520A7
#define GPIO_PORT168CR 0xE60520A8 #define GPIO_PORT168CR 0xE60520A8
#define SRCR4 0xe61580bc #define SRCR4 0xe61580bc
#define USCCR1 0xE6058144 #define USCCR1 0xE6058144
@ -1354,17 +1440,17 @@ static void __init mackerel_init(void)
gpio_request(GPIO_PORT151, NULL); /* LCDDON */ gpio_request(GPIO_PORT151, NULL); /* LCDDON */
gpio_direction_output(GPIO_PORT151, 1); gpio_direction_output(GPIO_PORT151, 1);
/* USB enable */ /* USBHS0 */
gpio_request(GPIO_FN_VBUS0_1, NULL); gpio_request(GPIO_FN_VBUS0_0, NULL);
gpio_request(GPIO_FN_IDIN_1_18, NULL); gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
gpio_request(GPIO_FN_PWEN_1_115, NULL);
gpio_request(GPIO_FN_OVCN_1_114, NULL);
gpio_request(GPIO_FN_EXTLP_1, NULL);
gpio_request(GPIO_FN_OVCN2_1, NULL);
gpio_pull_down(GPIO_PORT168CR);
/* setup USB phy */ /* USBHS1 */
__raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */ gpio_request(GPIO_FN_VBUS0_1, NULL);
gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
gpio_request(GPIO_FN_IDIN_1_113, NULL);
/* USB phy tweak to make the r8a66597_hcd host driver work */
__raw_writew(0x8a0a, 0xe6058130); /* USBCR4 */
/* enable FSI2 port A (ak4643) */ /* enable FSI2 port A (ak4643) */
gpio_request(GPIO_FN_FSIAIBT, NULL); gpio_request(GPIO_FN_FSIAIBT, NULL);

View File

@ -250,6 +250,11 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
{
return 0; /* always allow wakeup */
}
void __init sh73a0_init_irq(void) void __init sh73a0_init_irq(void)
{ {
void __iomem *gic_dist_base = __io(0xf0001000); void __iomem *gic_dist_base = __io(0xf0001000);
@ -257,6 +262,7 @@ void __init sh73a0_init_irq(void)
void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE); void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
gic_init(0, 29, gic_dist_base, gic_cpu_base); gic_init(0, 29, gic_dist_base, gic_cpu_base);
gic_arch_extn.irq_set_wake = sh73a0_set_wake;
register_intc_controller(&intcs_desc); register_intc_controller(&intcs_desc);

View File

@ -38,7 +38,7 @@ static struct plat_sci_port scif0_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xc00), evt2irq(0xc00), .irqs = { evt2irq(0xc00), evt2irq(0xc00),
evt2irq(0xc00), evt2irq(0xc00) }, evt2irq(0xc00), evt2irq(0xc00) },
}; };
@ -57,7 +57,7 @@ static struct plat_sci_port scif1_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xc20), evt2irq(0xc20), .irqs = { evt2irq(0xc20), evt2irq(0xc20),
evt2irq(0xc20), evt2irq(0xc20) }, evt2irq(0xc20), evt2irq(0xc20) },
}; };
@ -76,7 +76,7 @@ static struct plat_sci_port scif2_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xc40), evt2irq(0xc40), .irqs = { evt2irq(0xc40), evt2irq(0xc40),
evt2irq(0xc40), evt2irq(0xc40) }, evt2irq(0xc40), evt2irq(0xc40) },
}; };
@ -95,7 +95,7 @@ static struct plat_sci_port scif3_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xc60), evt2irq(0xc60), .irqs = { evt2irq(0xc60), evt2irq(0xc60),
evt2irq(0xc60), evt2irq(0xc60) }, evt2irq(0xc60), evt2irq(0xc60) },
}; };
@ -114,7 +114,7 @@ static struct plat_sci_port scif4_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xd20), evt2irq(0xd20), .irqs = { evt2irq(0xd20), evt2irq(0xd20),
evt2irq(0xd20), evt2irq(0xd20) }, evt2irq(0xd20), evt2irq(0xd20) },
}; };
@ -133,7 +133,7 @@ static struct plat_sci_port scif5_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFA,
.irqs = { evt2irq(0xd40), evt2irq(0xd40), .irqs = { evt2irq(0xd40), evt2irq(0xd40),
evt2irq(0xd40), evt2irq(0xd40) }, evt2irq(0xd40), evt2irq(0xd40) },
}; };
@ -152,7 +152,7 @@ static struct plat_sci_port scif6_platform_data = {
.flags = UPF_BOOT_AUTOCONF, .flags = UPF_BOOT_AUTOCONF,
.scscr = SCSCR_RE | SCSCR_TE, .scscr = SCSCR_RE | SCSCR_TE,
.scbrr_algo_id = SCBRR_ALGO_4, .scbrr_algo_id = SCBRR_ALGO_4,
.type = PORT_SCIF, .type = PORT_SCIFB,
.irqs = { evt2irq(0xd60), evt2irq(0xd60), .irqs = { evt2irq(0xd60), evt2irq(0xd60),
evt2irq(0xd60), evt2irq(0xd60) }, evt2irq(0xd60), evt2irq(0xd60) },
}; };

View File

@ -84,6 +84,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clkdev.h> #include <linux/clkdev.h>
#include <linux/pm_runtime.h>
#include <plat/omap_device.h> #include <plat/omap_device.h>
#include <plat/omap_hwmod.h> #include <plat/omap_hwmod.h>
@ -539,20 +540,34 @@ int omap_early_device_register(struct omap_device *od)
static int _od_runtime_suspend(struct device *dev) static int _od_runtime_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
int ret;
return omap_device_idle(pdev); ret = pm_generic_runtime_suspend(dev);
if (!ret)
omap_device_idle(pdev);
return ret;
}
static int _od_runtime_idle(struct device *dev)
{
return pm_generic_runtime_idle(dev);
} }
static int _od_runtime_resume(struct device *dev) static int _od_runtime_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct platform_device *pdev = to_platform_device(dev);
return omap_device_enable(pdev); omap_device_enable(pdev);
return pm_generic_runtime_resume(dev);
} }
static struct dev_power_domain omap_device_power_domain = { static struct dev_power_domain omap_device_power_domain = {
.ops = { .ops = {
.runtime_suspend = _od_runtime_suspend, .runtime_suspend = _od_runtime_suspend,
.runtime_idle = _od_runtime_idle,
.runtime_resume = _od_runtime_resume, .runtime_resume = _od_runtime_resume,
USE_PLATFORM_PM_SLEEP_OPS USE_PLATFORM_PM_SLEEP_OPS
} }

View File

@ -9,7 +9,6 @@ CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_LOG_BUF_SHIFT=14 CONFIG_LOG_BUF_SHIFT=14
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
# CONFIG_SYSCTL_SYSCALL is not set # CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y CONFIG_SLAB=y
@ -39,8 +38,6 @@ CONFIG_IPV6=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set # CONFIG_FW_LOADER is not set
CONFIG_MTD=y CONFIG_MTD=y
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y CONFIG_MTD_BLOCK=y
CONFIG_MTD_M25P80=y CONFIG_MTD_M25P80=y
@ -56,18 +53,19 @@ CONFIG_SH_ETH=y
# CONFIG_KEYBOARD_ATKBD is not set # CONFIG_KEYBOARD_ATKBD is not set
# CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_PS2 is not set
# CONFIG_SERIO is not set # CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=3 CONFIG_SERIAL_SH_SCI_NR_UARTS=3
CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_SH_SCI_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_HW_RANDOM is not set # CONFIG_HW_RANDOM is not set
CONFIG_SPI=y CONFIG_SPI=y
CONFIG_SPI_SH=y CONFIG_SPI_SH=y
# CONFIG_HWMON is not set # CONFIG_HWMON is not set
CONFIG_MFD_SH_MOBILE_SDHI=y
CONFIG_USB=y CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_SH=y
CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_SH=y
CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE=y
CONFIG_MMC=y CONFIG_MMC=y
CONFIG_MMC_SDHI=y CONFIG_MMC_SDHI=y

View File

@ -659,6 +659,54 @@ static struct platform_device spi0_device = {
.resource = spi0_resources, .resource = spi0_resources,
}; };
static struct resource usb_ehci_resources[] = {
[0] = {
.start = 0xfe4f1000,
.end = 0xfe4f10ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 57,
.end = 57,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usb_ehci_device = {
.name = "sh_ehci",
.id = -1,
.dev = {
.dma_mask = &usb_ehci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(usb_ehci_resources),
.resource = usb_ehci_resources,
};
static struct resource usb_ohci_resources[] = {
[0] = {
.start = 0xfe4f1800,
.end = 0xfe4f18ff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 57,
.end = 57,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device usb_ohci_device = {
.name = "sh_ohci",
.id = -1,
.dev = {
.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(usb_ohci_resources),
.resource = usb_ohci_resources,
};
static struct platform_device *sh7757_devices[] __initdata = { static struct platform_device *sh7757_devices[] __initdata = {
&scif2_device, &scif2_device,
&scif3_device, &scif3_device,
@ -670,6 +718,8 @@ static struct platform_device *sh7757_devices[] __initdata = {
&dma2_device, &dma2_device,
&dma3_device, &dma3_device,
&spi0_device, &spi0_device,
&usb_ehci_device,
&usb_ohci_device,
}; };
static int __init sh7757_devices_setup(void) static int __init sh7757_devices_setup(void)

View File

@ -4,7 +4,6 @@
#define ARCH_DISCARD_MEMBLOCK #define ARCH_DISCARD_MEMBLOCK
u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align); u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align);
void memblock_x86_to_bootmem(u64 start, u64 end);
void memblock_x86_reserve_range(u64 start, u64 end, char *name); void memblock_x86_reserve_range(u64 start, u64 end, char *name);
void memblock_x86_free_range(u64 start, u64 end); void memblock_x86_free_range(u64 start, u64 end);
@ -19,5 +18,6 @@ u64 memblock_x86_hole_size(u64 start, u64 end);
u64 memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align); u64 memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align);
u64 memblock_x86_free_memory_in_range(u64 addr, u64 limit); u64 memblock_x86_free_memory_in_range(u64 addr, u64 limit);
u64 memblock_x86_memory_in_range(u64 addr, u64 limit); u64 memblock_x86_memory_in_range(u64 addr, u64 limit);
bool memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align);
#endif #endif

View File

@ -22,6 +22,8 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
u64 product; u64 product;
#ifdef __i386__ #ifdef __i386__
u32 tmp1, tmp2; u32 tmp1, tmp2;
#else
ulong tmp;
#endif #endif
if (shift < 0) if (shift < 0)
@ -42,8 +44,11 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) ); : "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
#elif defined(__x86_64__) #elif defined(__x86_64__)
__asm__ ( __asm__ (
"mul %%rdx ; shrd $32,%%rdx,%%rax" "mul %[mul_frac] ; shrd $32, %[hi], %[lo]"
: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) ); : [lo]"=a"(product),
[hi]"=d"(tmp)
: "0"(delta),
[mul_frac]"rm"((u64)mul_frac));
#else #else
#error implement me! #error implement me!
#endif #endif

View File

@ -565,7 +565,7 @@ gfn_to_memslot_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t gfn,
static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn) static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn)
{ {
return gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true); return !gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
} }
static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn) static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)

View File

@ -121,7 +121,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
gva_t addr, u32 access) gva_t addr, u32 access)
{ {
pt_element_t pte; pt_element_t pte;
pt_element_t __user *ptep_user; pt_element_t __user *uninitialized_var(ptep_user);
gfn_t table_gfn; gfn_t table_gfn;
unsigned index, pt_access, uninitialized_var(pte_access); unsigned index, pt_access, uninitialized_var(pte_access);
gpa_t pte_gpa; gpa_t pte_gpa;

View File

@ -2047,6 +2047,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
unsigned long cr0, unsigned long cr0,
struct kvm_vcpu *vcpu) struct kvm_vcpu *vcpu)
{ {
if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail))
vmx_decache_cr3(vcpu); vmx_decache_cr3(vcpu);
if (!(cr0 & X86_CR0_PG)) { if (!(cr0 & X86_CR0_PG)) {
/* From paging/starting to nonpaging */ /* From paging/starting to nonpaging */

View File

@ -8,7 +8,7 @@
#include <linux/range.h> #include <linux/range.h>
/* Check for already reserved areas */ /* Check for already reserved areas */
static bool __init check_with_memblock_reserved_size(u64 *addrp, u64 *sizep, u64 align) bool __init memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align)
{ {
struct memblock_region *r; struct memblock_region *r;
u64 addr = *addrp, last; u64 addr = *addrp, last;
@ -59,7 +59,7 @@ u64 __init memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align)
if (addr >= ei_last) if (addr >= ei_last)
continue; continue;
*sizep = ei_last - addr; *sizep = ei_last - addr;
while (check_with_memblock_reserved_size(&addr, sizep, align)) while (memblock_x86_check_reserved_size(&addr, sizep, align))
; ;
if (*sizep) if (*sizep)

View File

@ -310,14 +310,31 @@ void __init efi_reserve_boot_services(void)
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
efi_memory_desc_t *md = p; efi_memory_desc_t *md = p;
unsigned long long start = md->phys_addr; u64 start = md->phys_addr;
unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; u64 size = md->num_pages << EFI_PAGE_SHIFT;
if (md->type != EFI_BOOT_SERVICES_CODE && if (md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA) md->type != EFI_BOOT_SERVICES_DATA)
continue; continue;
/* Only reserve where possible:
memblock_x86_reserve_range(start, start + size, "EFI Boot"); * - Not within any already allocated areas
* - Not over any memory area (really needed, if above?)
* - Not within any part of the kernel
* - Not the bios reserved area
*/
if ((start+size >= virt_to_phys(_text)
&& start <= virt_to_phys(_end)) ||
!e820_all_mapped(start, start+size, E820_RAM) ||
memblock_x86_check_reserved_size(&start, &size,
1<<EFI_PAGE_SHIFT)) {
/* Could not reserve, skip it */
md->num_pages = 0;
memblock_dbg(PFX "Could not reserve boot range "
"[0x%010llx-0x%010llx]\n",
start, start+size-1);
} else
memblock_x86_reserve_range(start, start+size,
"EFI Boot");
} }
} }
@ -334,6 +351,10 @@ static void __init efi_free_boot_services(void)
md->type != EFI_BOOT_SERVICES_DATA) md->type != EFI_BOOT_SERVICES_DATA)
continue; continue;
/* Could not reserve boot area */
if (!size)
continue;
free_bootmem_late(start, size); free_bootmem_late(start, size);
} }
} }

View File

@ -1033,6 +1033,13 @@ static void xen_machine_halt(void)
xen_reboot(SHUTDOWN_poweroff); xen_reboot(SHUTDOWN_poweroff);
} }
static void xen_machine_power_off(void)
{
if (pm_power_off)
pm_power_off();
xen_reboot(SHUTDOWN_poweroff);
}
static void xen_crash_shutdown(struct pt_regs *regs) static void xen_crash_shutdown(struct pt_regs *regs)
{ {
xen_reboot(SHUTDOWN_crash); xen_reboot(SHUTDOWN_crash);
@ -1058,7 +1065,7 @@ int xen_panic_handler_init(void)
static const struct machine_ops xen_machine_ops __initconst = { static const struct machine_ops xen_machine_ops __initconst = {
.restart = xen_restart, .restart = xen_restart,
.halt = xen_machine_halt, .halt = xen_machine_halt,
.power_off = xen_machine_halt, .power_off = xen_machine_power_off,
.shutdown = xen_machine_halt, .shutdown = xen_machine_halt,
.crash_shutdown = xen_crash_shutdown, .crash_shutdown = xen_crash_shutdown,
.emergency_restart = xen_emergency_restart, .emergency_restart = xen_emergency_restart,

View File

@ -59,6 +59,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/init.h> #include <asm/init.h>
#include <asm/pat.h> #include <asm/pat.h>
#include <asm/smp.h>
#include <asm/xen/hypercall.h> #include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h> #include <asm/xen/hypervisor.h>
@ -1231,7 +1232,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
{ {
struct { struct {
struct mmuext_op op; struct mmuext_op op;
DECLARE_BITMAP(mask, NR_CPUS); DECLARE_BITMAP(mask, num_processors);
} *args; } *args;
struct multicall_space mcs; struct multicall_space mcs;
@ -1599,6 +1600,11 @@ static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) { for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
pte_t pte; pte_t pte;
#ifdef CONFIG_X86_32
if (pfn > max_pfn_mapped)
max_pfn_mapped = pfn;
#endif
if (!pte_none(pte_page[pteidx])) if (!pte_none(pte_page[pteidx]))
continue; continue;
@ -1766,7 +1772,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
initial_kernel_pmd = initial_kernel_pmd =
extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE); extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list)); max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
xen_start_info->nr_pt_frames * PAGE_SIZE +
512*1024);
kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd); kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD); memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);

View File

@ -227,11 +227,7 @@ char * __init xen_memory_setup(void)
memcpy(map_raw, map, sizeof(map)); memcpy(map_raw, map, sizeof(map));
e820.nr_map = 0; e820.nr_map = 0;
#ifdef CONFIG_X86_32
xen_extra_mem_start = mem_end; xen_extra_mem_start = mem_end;
#else
xen_extra_mem_start = max((1ULL << 32), mem_end);
#endif
for (i = 0; i < memmap.nr_entries; i++) { for (i = 0; i < memmap.nr_entries; i++) {
unsigned long long end; unsigned long long end;
@ -266,6 +262,12 @@ char * __init xen_memory_setup(void)
if (map[i].size > 0) if (map[i].size > 0)
e820_add_region(map[i].addr, map[i].size, map[i].type); e820_add_region(map[i].addr, map[i].size, map[i].type);
} }
/* Align the balloon area so that max_low_pfn does not get set
* to be at the _end_ of the PCI gap at the far end (fee01000).
* Note that xen_extra_mem_start gets set in the loop above to be
* past the last E820 region. */
if (xen_initial_domain() && (xen_extra_mem_start < (1ULL<<32)))
xen_extra_mem_start = (1ULL<<32);
/* /*
* In domU, the ISA region is normal, usable memory, but we * In domU, the ISA region is normal, usable memory, but we

View File

@ -205,11 +205,18 @@ static void __init xen_smp_prepare_boot_cpu(void)
static void __init xen_smp_prepare_cpus(unsigned int max_cpus) static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
{ {
unsigned cpu; unsigned cpu;
unsigned int i;
xen_init_lock_cpu(0); xen_init_lock_cpu(0);
smp_store_cpu_info(0); smp_store_cpu_info(0);
cpu_data(0).x86_max_cores = 1; cpu_data(0).x86_max_cores = 1;
for_each_possible_cpu(i) {
zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL);
}
set_cpu_sibling_map(0); set_cpu_sibling_map(0);
if (xen_smp_intr_init(0)) if (xen_smp_intr_init(0))

View File

@ -64,6 +64,8 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscfgcmd = result; priv->btmrvl_dev.hscfgcmd = result;
@ -108,6 +110,8 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.psmode = result; priv->btmrvl_dev.psmode = result;
@ -147,6 +151,8 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.pscmd = result; priv->btmrvl_dev.pscmd = result;
@ -191,6 +197,8 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 16, &result); ret = strict_strtol(buf, 16, &result);
if (ret)
return ret;
priv->btmrvl_dev.gpio_gap = result; priv->btmrvl_dev.gpio_gap = result;
@ -230,6 +238,8 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscmd = result; priv->btmrvl_dev.hscmd = result;
if (priv->btmrvl_dev.hscmd) { if (priv->btmrvl_dev.hscmd) {
@ -272,6 +282,8 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hsmode = result; priv->btmrvl_dev.hsmode = result;

View File

@ -298,11 +298,13 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
old_index = stat->last_index; old_index = stat->last_index;
new_index = freq_table_get_index(stat, freq->new); new_index = freq_table_get_index(stat, freq->new);
cpufreq_stats_update(freq->cpu); /* We can't do stat->time_in_state[-1]= .. */
if (old_index == new_index) if (old_index == -1 || new_index == -1)
return 0; return 0;
if (old_index == -1 || new_index == -1) cpufreq_stats_update(freq->cpu);
if (old_index == new_index)
return 0; return 0;
spin_lock(&cpufreq_stats_lock); spin_lock(&cpufreq_stats_lock);

View File

@ -1079,6 +1079,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
} }
res = transition_fid_vid(data, fid, vid); res = transition_fid_vid(data, fid, vid);
if (res)
return res;
freqs.new = find_khz_freq_from_fid(data->currfid); freqs.new = find_khz_freq_from_fid(data->currfid);
for_each_cpu(i, data->available_cores) { for_each_cpu(i, data->available_cores) {
@ -1101,7 +1104,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
/* get MSR index for hardware pstate transition */ /* get MSR index for hardware pstate transition */
pstate = index & HW_PSTATE_MASK; pstate = index & HW_PSTATE_MASK;
if (pstate > data->max_hw_pstate) if (pstate > data->max_hw_pstate)
return 0; return -EINVAL;
freqs.old = find_khz_freq_from_pstate(data->powernow_table, freqs.old = find_khz_freq_from_pstate(data->powernow_table,
data->currpstate); data->currpstate);
freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);

View File

@ -469,8 +469,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
+ OMAP24XX_GPIO_CLEARWKUENA); + OMAP24XX_GPIO_CLEARWKUENA);
} }
} }
/* This part needs to be executed always for OMAP34xx */ /* This part needs to be executed always for OMAP{34xx, 44xx} */
if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) { if (cpu_is_omap34xx() || cpu_is_omap44xx() ||
(bank->non_wakeup_gpios & gpio_bit)) {
/* /*
* Log the edge gpio and manually trigger the IRQ * Log the edge gpio and manually trigger the IRQ
* after resume if the input level changes * after resume if the input level changes

View File

@ -184,9 +184,9 @@ drm_edid_block_valid(u8 *raw_edid)
bad: bad:
if (raw_edid) { if (raw_edid) {
DRM_ERROR("Raw EDID:\n"); printk(KERN_ERR "Raw EDID:\n");
print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH); print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
printk("\n"); printk(KERN_ERR "\n");
} }
return 0; return 0;
} }
@ -258,6 +258,17 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
return ret == 2 ? 0 : -1; return ret == 2 ? 0 : -1;
} }
static bool drm_edid_is_zero(u8 *in_edid, int length)
{
int i;
u32 *raw_edid = (u32 *)in_edid;
for (i = 0; i < length / 4; i++)
if (*(raw_edid + i) != 0)
return false;
return true;
}
static u8 * static u8 *
drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
{ {
@ -273,6 +284,10 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
goto out; goto out;
if (drm_edid_block_valid(block)) if (drm_edid_block_valid(block))
break; break;
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
connector->null_edid_counter++;
goto carp;
}
} }
if (i == 4) if (i == 4)
goto carp; goto carp;

View File

@ -28,6 +28,7 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/ratelimit.h>
#include "drmP.h" #include "drmP.h"
#include "drm_core.h" #include "drm_core.h"
@ -253,8 +254,8 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
return -EFAULT; return -EFAULT;
m32.handle = (unsigned long)handle; m32.handle = (unsigned long)handle;
if (m32.handle != (unsigned long)handle && printk_ratelimit()) if (m32.handle != (unsigned long)handle)
printk(KERN_ERR "compat_drm_addmap truncated handle" printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle"
" %p for type %d offset %x\n", " %p for type %d offset %x\n",
handle, m32.type, m32.offset); handle, m32.type, m32.offset);

View File

@ -251,7 +251,7 @@ err:
} }
int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p) static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
{ {
if ((p->busnum >> 8) != drm_get_pci_domain(dev) || if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
(p->busnum & 0xff) != dev->pdev->bus->number || (p->busnum & 0xff) != dev->pdev->bus->number ||
@ -292,6 +292,7 @@ static struct drm_bus drm_pci_bus = {
.get_name = drm_pci_get_name, .get_name = drm_pci_get_name,
.set_busid = drm_pci_set_busid, .set_busid = drm_pci_set_busid,
.set_unique = drm_pci_set_unique, .set_unique = drm_pci_set_unique,
.irq_by_busid = drm_pci_irq_by_busid,
.agp_init = drm_pci_agp_init, .agp_init = drm_pci_agp_init,
}; };

View File

@ -1740,6 +1740,16 @@ void ironlake_irq_preinstall(struct drm_device *dev)
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
I915_WRITE(HWSTAM, 0xeffe); I915_WRITE(HWSTAM, 0xeffe);
if (IS_GEN6(dev)) {
/* Workaround stalls observed on Sandy Bridge GPUs by
* making the blitter command streamer generate a
* write to the Hardware Status Page for
* MI_USER_INTERRUPT. This appears to serialize the
* previous seqno write out before the interrupt
* happens.
*/
I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT);
}
/* XXX hotplug from PCH */ /* XXX hotplug from PCH */

View File

@ -401,7 +401,6 @@ int intel_setup_gmbus(struct drm_device *dev)
bus->reg0 = i | GMBUS_RATE_100KHZ; bus->reg0 = i | GMBUS_RATE_100KHZ;
/* XXX force bit banging until GMBUS is fully debugged */ /* XXX force bit banging until GMBUS is fully debugged */
if (IS_GEN2(dev))
bus->force_bit = intel_gpio_create(dev_priv, i); bus->force_bit = intel_gpio_create(dev_priv, i);
} }

View File

@ -262,7 +262,6 @@ static bool nouveau_dsm_detect(void)
vga_count++; vga_count++;
retval = nouveau_dsm_pci_probe(pdev); retval = nouveau_dsm_pci_probe(pdev);
printk("ret val is %d\n", retval);
if (retval & NOUVEAU_DSM_HAS_MUX) if (retval & NOUVEAU_DSM_HAS_MUX)
has_dsm |= 1; has_dsm |= 1;
if (retval & NOUVEAU_DSM_HAS_OPT) if (retval & NOUVEAU_DSM_HAS_OPT)

View File

@ -339,11 +339,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
int ret; int ret;
if (dev_priv->chipset < 0x84) { if (dev_priv->chipset < 0x84) {
ret = RING_SPACE(chan, 3); ret = RING_SPACE(chan, 4);
if (ret) if (ret)
return ret; return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2); BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 3);
OUT_RING (chan, NvSema);
OUT_RING (chan, sema->mem->start); OUT_RING (chan, sema->mem->start);
OUT_RING (chan, 1); OUT_RING (chan, 1);
} else } else
@ -351,10 +352,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
struct nouveau_vma *vma = &dev_priv->fence.bo->vma; struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
u64 offset = vma->offset + sema->mem->start; u64 offset = vma->offset + sema->mem->start;
ret = RING_SPACE(chan, 5); ret = RING_SPACE(chan, 7);
if (ret) if (ret)
return ret; return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
OUT_RING (chan, chan->vram_handle);
BEGIN_RING(chan, NvSubSw, 0x0010, 4); BEGIN_RING(chan, NvSubSw, 0x0010, 4);
OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, upper_32_bits(offset));
OUT_RING (chan, lower_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset));
@ -394,11 +397,12 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
int ret; int ret;
if (dev_priv->chipset < 0x84) { if (dev_priv->chipset < 0x84) {
ret = RING_SPACE(chan, 4); ret = RING_SPACE(chan, 5);
if (ret) if (ret)
return ret; return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1); BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 2);
OUT_RING (chan, NvSema);
OUT_RING (chan, sema->mem->start); OUT_RING (chan, sema->mem->start);
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1); BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1);
OUT_RING (chan, 1); OUT_RING (chan, 1);
@ -407,10 +411,12 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
struct nouveau_vma *vma = &dev_priv->fence.bo->vma; struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
u64 offset = vma->offset + sema->mem->start; u64 offset = vma->offset + sema->mem->start;
ret = RING_SPACE(chan, 5); ret = RING_SPACE(chan, 7);
if (ret) if (ret)
return ret; return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
OUT_RING (chan, chan->vram_handle);
BEGIN_RING(chan, NvSubSw, 0x0010, 4); BEGIN_RING(chan, NvSubSw, 0x0010, 4);
OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, upper_32_bits(offset));
OUT_RING (chan, lower_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset));
@ -504,22 +510,22 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
struct nouveau_gpuobj *obj = NULL; struct nouveau_gpuobj *obj = NULL;
int ret; int ret;
if (dev_priv->card_type >= NV_C0) if (dev_priv->card_type < NV_C0) {
goto out_initialised;
/* Create an NV_SW object for various sync purposes */ /* Create an NV_SW object for various sync purposes */
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
if (ret) if (ret)
return ret; return ret;
/* we leave subchannel empty for nvc0 */
ret = RING_SPACE(chan, 2); ret = RING_SPACE(chan, 2);
if (ret) if (ret)
return ret; return ret;
BEGIN_RING(chan, NvSubSw, 0, 1); BEGIN_RING(chan, NvSubSw, 0, 1);
OUT_RING (chan, NvSw); OUT_RING (chan, NvSw);
FIRE_RING (chan);
}
/* Create a DMA object for the shared cross-channel sync area. */ /* Setup area of memory shared between all channels for x-chan sync */
if (USE_SEMA(dev) && dev_priv->chipset < 0x84) { if (USE_SEMA(dev) && dev_priv->chipset < 0x84) {
struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem; struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem;
@ -534,23 +540,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan)
nouveau_gpuobj_ref(NULL, &obj); nouveau_gpuobj_ref(NULL, &obj);
if (ret) if (ret)
return ret; return ret;
ret = RING_SPACE(chan, 2);
if (ret)
return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
OUT_RING(chan, NvSema);
} else {
ret = RING_SPACE(chan, 2);
if (ret)
return ret;
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
OUT_RING (chan, chan->vram_handle); /* whole VM */
} }
FIRE_RING(chan);
out_initialised:
INIT_LIST_HEAD(&chan->fence.pending); INIT_LIST_HEAD(&chan->fence.pending);
spin_lock_init(&chan->fence.lock); spin_lock_init(&chan->fence.lock);
atomic_set(&chan->fence.last_sequence_irq, 0); atomic_set(&chan->fence.last_sequence_irq, 0);

View File

@ -182,6 +182,11 @@ nouveau_perf_init(struct drm_device *dev)
entries = perf[2]; entries = perf[2];
} }
if (entries > NOUVEAU_PM_MAX_LEVEL) {
NV_DEBUG(dev, "perf table has too many entries - buggy vbios?\n");
entries = NOUVEAU_PM_MAX_LEVEL;
}
entry = perf + headerlen; entry = perf + headerlen;
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];

View File

@ -881,8 +881,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
/* Put the card in BE mode if it's not */ /* Put the card in BE mode if it's not */
if (nv_rd32(dev, NV03_PMC_BOOT_1)) if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001); nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
DRM_MEMORYBARRIER(); DRM_MEMORYBARRIER();
#endif #endif

View File

@ -409,7 +409,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct nouveau_channel *evo = dispc->sync; struct nouveau_channel *evo = dispc->sync;
int ret; int ret;
ret = RING_SPACE(evo, 24); ret = RING_SPACE(evo, chan ? 25 : 27);
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
@ -458,8 +458,19 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
/* queue the flip on the crtc's "display sync" channel */ /* queue the flip on the crtc's "display sync" channel */
BEGIN_RING(evo, 0, 0x0100, 1); BEGIN_RING(evo, 0, 0x0100, 1);
OUT_RING (evo, 0xfffe0000); OUT_RING (evo, 0xfffe0000);
BEGIN_RING(evo, 0, 0x0084, 5); if (chan) {
OUT_RING (evo, chan ? 0x00000100 : 0x00000010); BEGIN_RING(evo, 0, 0x0084, 1);
OUT_RING (evo, 0x00000100);
} else {
BEGIN_RING(evo, 0, 0x0084, 1);
OUT_RING (evo, 0x00000010);
/* allows gamma somehow, PDISP will bitch at you if
* you don't wait for vblank before changing this..
*/
BEGIN_RING(evo, 0, 0x00e0, 1);
OUT_RING (evo, 0x40000000);
}
BEGIN_RING(evo, 0, 0x0088, 4);
OUT_RING (evo, dispc->sem.offset); OUT_RING (evo, dispc->sem.offset);
OUT_RING (evo, 0xf00d0000 | dispc->sem.value); OUT_RING (evo, 0xf00d0000 | dispc->sem.value);
OUT_RING (evo, 0x74b1e000); OUT_RING (evo, 0x74b1e000);

View File

@ -1200,6 +1200,7 @@ typedef struct _EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3
#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10 #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10
#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11 #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11
#define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12 #define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12
#define EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP 0x14
// ucConfig // ucConfig
#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03

View File

@ -671,6 +671,13 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
DISPPLL_CONFIG_DUAL_LINK; DISPPLL_CONFIG_DUAL_LINK;
} }
} }
if (radeon_encoder_is_dp_bridge(encoder)) {
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id;
} else
args.v3.sInput.ucExtTransmitterID = 0;
atom_execute_table(rdev->mode_info.atom_context, atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args); index, (uint32_t *)&args);
adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10; adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;

View File

@ -88,7 +88,8 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
/* get temperature in millidegrees */ /* get temperature in millidegrees */
int evergreen_get_temp(struct radeon_device *rdev) int evergreen_get_temp(struct radeon_device *rdev)
{ {
u32 temp, toffset, actual_temp = 0; u32 temp, toffset;
int actual_temp = 0;
if (rdev->family == CHIP_JUNIPER) { if (rdev->family == CHIP_JUNIPER) {
toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
@ -139,11 +140,17 @@ void evergreen_pm_misc(struct radeon_device *rdev)
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
if (voltage->type == VOLTAGE_SW) { if (voltage->type == VOLTAGE_SW) {
/* 0xff01 is a flag rather then an actual voltage */
if (voltage->voltage == 0xff01)
return;
if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
rdev->pm.current_vddc = voltage->voltage; rdev->pm.current_vddc = voltage->voltage;
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
} }
/* 0xff01 is a flag rather then an actual voltage */
if (voltage->vddci == 0xff01)
return;
if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
rdev->pm.current_vddci = voltage->vddci; rdev->pm.current_vddci = voltage->vddci;
@ -2694,28 +2701,25 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
int evergreen_irq_process(struct radeon_device *rdev) int evergreen_irq_process(struct radeon_device *rdev)
{ {
u32 wptr = evergreen_get_ih_wptr(rdev); u32 wptr;
u32 rptr = rdev->ih.rptr; u32 rptr;
u32 src_id, src_data; u32 src_id, src_data;
u32 ring_index; u32 ring_index;
unsigned long flags; unsigned long flags;
bool queue_hotplug = false; bool queue_hotplug = false;
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); if (!rdev->ih.enabled || rdev->shutdown)
if (!rdev->ih.enabled)
return IRQ_NONE; return IRQ_NONE;
spin_lock_irqsave(&rdev->ih.lock, flags); wptr = evergreen_get_ih_wptr(rdev);
rptr = rdev->ih.rptr;
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
spin_lock_irqsave(&rdev->ih.lock, flags);
if (rptr == wptr) { if (rptr == wptr) {
spin_unlock_irqrestore(&rdev->ih.lock, flags); spin_unlock_irqrestore(&rdev->ih.lock, flags);
return IRQ_NONE; return IRQ_NONE;
} }
if (rdev->shutdown) {
spin_unlock_irqrestore(&rdev->ih.lock, flags);
return IRQ_NONE;
}
restart_ih: restart_ih:
/* display interrupts */ /* display interrupts */
evergreen_irq_ack(rdev); evergreen_irq_ack(rdev);

View File

@ -590,6 +590,9 @@ void r600_pm_misc(struct radeon_device *rdev)
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
/* 0xff01 is a flag rather then an actual voltage */
if (voltage->voltage == 0xff01)
return;
if (voltage->voltage != rdev->pm.current_vddc) { if (voltage->voltage != rdev->pm.current_vddc) {
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
rdev->pm.current_vddc = voltage->voltage; rdev->pm.current_vddc = voltage->voltage;
@ -3294,27 +3297,26 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
int r600_irq_process(struct radeon_device *rdev) int r600_irq_process(struct radeon_device *rdev)
{ {
u32 wptr = r600_get_ih_wptr(rdev); u32 wptr;
u32 rptr = rdev->ih.rptr; u32 rptr;
u32 src_id, src_data; u32 src_id, src_data;
u32 ring_index; u32 ring_index;
unsigned long flags; unsigned long flags;
bool queue_hotplug = false; bool queue_hotplug = false;
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); if (!rdev->ih.enabled || rdev->shutdown)
if (!rdev->ih.enabled)
return IRQ_NONE; return IRQ_NONE;
wptr = r600_get_ih_wptr(rdev);
rptr = rdev->ih.rptr;
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
spin_lock_irqsave(&rdev->ih.lock, flags); spin_lock_irqsave(&rdev->ih.lock, flags);
if (rptr == wptr) { if (rptr == wptr) {
spin_unlock_irqrestore(&rdev->ih.lock, flags); spin_unlock_irqrestore(&rdev->ih.lock, flags);
return IRQ_NONE; return IRQ_NONE;
} }
if (rdev->shutdown) {
spin_unlock_irqrestore(&rdev->ih.lock, flags);
return IRQ_NONE;
}
restart_ih: restart_ih:
/* display interrupts */ /* display interrupts */

View File

@ -938,6 +938,13 @@ static struct radeon_asic cayman_asic = {
int radeon_asic_init(struct radeon_device *rdev) int radeon_asic_init(struct radeon_device *rdev)
{ {
radeon_register_accessor_init(rdev); radeon_register_accessor_init(rdev);
/* set the number of crtcs */
if (rdev->flags & RADEON_SINGLE_CRTC)
rdev->num_crtc = 1;
else
rdev->num_crtc = 2;
switch (rdev->family) { switch (rdev->family) {
case CHIP_R100: case CHIP_R100:
case CHIP_RV100: case CHIP_RV100:
@ -1017,6 +1024,11 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_JUNIPER: case CHIP_JUNIPER:
case CHIP_CYPRESS: case CHIP_CYPRESS:
case CHIP_HEMLOCK: case CHIP_HEMLOCK:
/* set num crtcs */
if (rdev->family == CHIP_CEDAR)
rdev->num_crtc = 4;
else
rdev->num_crtc = 6;
rdev->asic = &evergreen_asic; rdev->asic = &evergreen_asic;
break; break;
case CHIP_PALM: case CHIP_PALM:
@ -1027,10 +1039,17 @@ int radeon_asic_init(struct radeon_device *rdev)
case CHIP_BARTS: case CHIP_BARTS:
case CHIP_TURKS: case CHIP_TURKS:
case CHIP_CAICOS: case CHIP_CAICOS:
/* set num crtcs */
if (rdev->family == CHIP_CAICOS)
rdev->num_crtc = 4;
else
rdev->num_crtc = 6;
rdev->asic = &btc_asic; rdev->asic = &btc_asic;
break; break;
case CHIP_CAYMAN: case CHIP_CAYMAN:
rdev->asic = &cayman_asic; rdev->asic = &cayman_asic;
/* set num crtcs */
rdev->num_crtc = 6;
break; break;
default: default:
/* FIXME: not supported yet */ /* FIXME: not supported yet */
@ -1042,18 +1061,6 @@ int radeon_asic_init(struct radeon_device *rdev)
rdev->asic->set_memory_clock = NULL; rdev->asic->set_memory_clock = NULL;
} }
/* set the number of crtcs */
if (rdev->flags & RADEON_SINGLE_CRTC)
rdev->num_crtc = 1;
else {
if (ASIC_IS_DCE41(rdev))
rdev->num_crtc = 2;
else if (ASIC_IS_DCE4(rdev))
rdev->num_crtc = 6;
else
rdev->num_crtc = 2;
}
return 0; return 0;
} }

View File

@ -2607,6 +2607,10 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
return; return;
/* 0xff01 is a flag rather then an actual voltage */
if (voltage_level == 0xff01)
return;
switch (crev) { switch (crev) {
case 1: case 1:
args.v1.ucVoltageType = voltage_type; args.v1.ucVoltageType = voltage_type;

View File

@ -1553,9 +1553,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
(rdev->pdev->subsystem_device == 0x4a48)) { (rdev->pdev->subsystem_device == 0x4a48)) {
/* Mac X800 */ /* Mac X800 */
rdev->mode_info.connector_table = CT_MAC_X800; rdev->mode_info.connector_table = CT_MAC_X800;
} else if (of_machine_is_compatible("PowerMac7,2") || } else if ((of_machine_is_compatible("PowerMac7,2") ||
of_machine_is_compatible("PowerMac7,3")) { of_machine_is_compatible("PowerMac7,3")) &&
/* Mac G5 9600 */ (rdev->pdev->device == 0x4150) &&
(rdev->pdev->subsystem_vendor == 0x1002) &&
(rdev->pdev->subsystem_device == 0x4150)) {
/* Mac G5 tower 9600 */
rdev->mode_info.connector_table = CT_MAC_G5_9600; rdev->mode_info.connector_table = CT_MAC_G5_9600;
} else } else
#endif /* CONFIG_PPC_PMAC */ #endif /* CONFIG_PPC_PMAC */

View File

@ -44,6 +44,8 @@ extern void
radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
struct drm_connector *drm_connector); struct drm_connector *drm_connector);
bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
void radeon_connector_hotplug(struct drm_connector *connector) void radeon_connector_hotplug(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
@ -836,6 +838,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
if (!radeon_connector->edid) { if (!radeon_connector->edid) {
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
/* rs690 seems to have a problem with connectors not existing and always
* return a block of 0's. If we see this just stop polling on this output */
if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
ret = connector_status_disconnected;
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
radeon_connector->ddc_bus = NULL;
}
} else { } else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
@ -1063,10 +1072,11 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
int ret; int ret;
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
struct drm_encoder *encoder; (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_display_mode *mode; struct drm_display_mode *mode;
if (!radeon_dig_connector->edp_on) if (!radeon_dig_connector->edp_on)
@ -1078,7 +1088,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
ATOM_TRANSMITTER_ACTION_POWER_OFF); ATOM_TRANSMITTER_ACTION_POWER_OFF);
if (ret > 0) { if (ret > 0) {
encoder = radeon_best_single_encoder(connector);
if (encoder) { if (encoder) {
radeon_fixup_lvds_native_mode(encoder, connector); radeon_fixup_lvds_native_mode(encoder, connector);
/* add scaled modes */ /* add scaled modes */
@ -1102,8 +1111,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
/* add scaled modes */ /* add scaled modes */
radeon_add_common_modes(encoder, connector); radeon_add_common_modes(encoder, connector);
} }
} else } else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
ret = radeon_ddc_get_modes(radeon_connector); ret = radeon_ddc_get_modes(radeon_connector);
}
return ret; return ret;
} }
@ -1187,14 +1202,15 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected; enum drm_connector_status ret = connector_status_disconnected;
struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
if (radeon_connector->edid) { if (radeon_connector->edid) {
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
radeon_connector->edid = NULL; radeon_connector->edid = NULL;
} }
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
struct drm_encoder *encoder = radeon_best_single_encoder(connector); (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
if (encoder) { if (encoder) {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_display_mode *native_mode = &radeon_encoder->native_mode; struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
@ -1214,6 +1230,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
atombios_set_edp_panel_power(connector, atombios_set_edp_panel_power(connector,
ATOM_TRANSMITTER_ACTION_POWER_OFF); ATOM_TRANSMITTER_ACTION_POWER_OFF);
} else { } else {
/* need to setup ddc on the bridge */
if (radeon_connector_encoder_is_dp_bridge(connector)) {
if (encoder)
radeon_atom_ext_encoder_setup_ddc(encoder);
}
radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) { if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
ret = connector_status_connected; ret = connector_status_connected;
@ -1228,6 +1249,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
ret = connector_status_connected; ret = connector_status_connected;
} }
} }
if ((ret == connector_status_disconnected) &&
radeon_connector->dac_load_detect) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
struct drm_encoder_helper_funcs *encoder_funcs;
if (encoder) {
encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
}
}
} }
radeon_connector_update_scratch_regs(connector, ret); radeon_connector_update_scratch_regs(connector, ret);
@ -1242,7 +1273,8 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
/* XXX check mode bandwidth */ /* XXX check mode bandwidth */
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_encoder *encoder = radeon_best_single_encoder(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector);
if ((mode->hdisplay < 320) || (mode->vdisplay < 240)) if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
@ -1401,6 +1433,10 @@ radeon_add_atom_connector(struct drm_device *dev,
default: default:
connector->interlace_allowed = true; connector->interlace_allowed = true;
connector->doublescan_allowed = true; connector->doublescan_allowed = true;
radeon_connector->dac_load_detect = true;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
break; break;
case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVII:
case DRM_MODE_CONNECTOR_DVID: case DRM_MODE_CONNECTOR_DVID:
@ -1422,6 +1458,12 @@ radeon_add_atom_connector(struct drm_device *dev,
connector->doublescan_allowed = true; connector->doublescan_allowed = true;
else else
connector->doublescan_allowed = false; connector->doublescan_allowed = false;
if (connector_type == DRM_MODE_CONNECTOR_DVII) {
radeon_connector->dac_load_detect = true;
drm_connector_attach_property(&radeon_connector->base,
rdev->mode_info.load_detect_property,
1);
}
break; break;
case DRM_MODE_CONNECTOR_LVDS: case DRM_MODE_CONNECTOR_LVDS:
case DRM_MODE_CONNECTOR_eDP: case DRM_MODE_CONNECTOR_eDP:

View File

@ -215,6 +215,8 @@ int radeon_wb_init(struct radeon_device *rdev)
return r; return r;
} }
/* clear wb memory */
memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE);
/* disable event_write fences */ /* disable event_write fences */
rdev->wb.use_event = false; rdev->wb.use_event = false;
/* disabled via module param */ /* disabled via module param */

View File

@ -367,7 +367,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
} }
if (ASIC_IS_DCE3(rdev) && if (ASIC_IS_DCE3(rdev) &&
(radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) { ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
radeon_encoder_is_dp_bridge(encoder))) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
radeon_dp_set_link_config(connector, mode); radeon_dp_set_link_config(connector, mode);
} }
@ -660,21 +661,16 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
if (radeon_encoder_is_dp_bridge(encoder)) if (radeon_encoder_is_dp_bridge(encoder))
return ATOM_ENCODER_MODE_DP; return ATOM_ENCODER_MODE_DP;
/* DVO is always DVO */
if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO)
return ATOM_ENCODER_MODE_DVO;
connector = radeon_get_connector_for_encoder(encoder); connector = radeon_get_connector_for_encoder(encoder);
if (!connector) { /* if we don't have an active device yet, just use one of
switch (radeon_encoder->encoder_id) { * the connectors tied to the encoder.
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: */
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: if (!connector)
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: connector = radeon_get_connector_for_encoder_init(encoder);
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
return ATOM_ENCODER_MODE_DVI;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
default:
return ATOM_ENCODER_MODE_CRT;
}
}
radeon_connector = to_radeon_connector(connector); radeon_connector = to_radeon_connector(connector);
switch (connector->connector_type) { switch (connector->connector_type) {
@ -1094,9 +1090,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
break; break;
} }
if (is_dp) if (is_dp) {
args.v2.acConfig.fCoherentMode = 1; args.v2.acConfig.fCoherentMode = 1;
else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { args.v2.acConfig.fDPConnector = 1;
} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
if (dig->coherent_mode) if (dig->coherent_mode)
args.v2.acConfig.fCoherentMode = 1; args.v2.acConfig.fCoherentMode = 1;
if (radeon_encoder->pixel_clock > 165000) if (radeon_encoder->pixel_clock > 165000)
@ -1435,6 +1432,10 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
if (is_dig) { if (is_dig) {
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
/* some early dce3.2 boards have a bug in their transmitter control table */
if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
else
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
@ -1526,26 +1527,29 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
} }
if (ext_encoder) { if (ext_encoder) {
int action;
switch (mode) { switch (mode) {
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
default: default:
if (ASIC_IS_DCE41(rdev)) if (ASIC_IS_DCE41(rdev)) {
action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT; atombios_external_encoder_setup(encoder, ext_encoder,
else EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
action = ATOM_ENABLE; atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
} else
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
break; break;
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
if (ASIC_IS_DCE41(rdev)) if (ASIC_IS_DCE41(rdev)) {
action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT; atombios_external_encoder_setup(encoder, ext_encoder,
else EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
action = ATOM_DISABLE; atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
} else
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
break; break;
} }
atombios_external_encoder_setup(encoder, ext_encoder, action);
} }
radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false); radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
@ -2004,6 +2008,65 @@ radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connec
return connector_status_disconnected; return connector_status_disconnected;
} }
static enum drm_connector_status
radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
u32 bios_0_scratch;
if (!ASIC_IS_DCE4(rdev))
return connector_status_unknown;
if (!ext_encoder)
return connector_status_unknown;
if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)
return connector_status_unknown;
/* load detect on the dp bridge */
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);
bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
if (bios_0_scratch & ATOM_S0_CRT1_MASK)
return connector_status_connected;
}
if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
if (bios_0_scratch & ATOM_S0_CRT2_MASK)
return connector_status_connected;
}
if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
return connector_status_connected;
}
if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
return connector_status_connected; /* CTV */
else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
return connector_status_connected; /* STV */
}
return connector_status_disconnected;
}
void
radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)
{
struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
if (ext_encoder)
/* ddc_setup on the dp bridge */
atombios_external_encoder_setup(encoder, ext_encoder,
EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
}
static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
{ {
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
@ -2167,7 +2230,7 @@ static const struct drm_encoder_helper_funcs radeon_atom_dig_helper_funcs = {
.mode_set = radeon_atom_encoder_mode_set, .mode_set = radeon_atom_encoder_mode_set,
.commit = radeon_atom_encoder_commit, .commit = radeon_atom_encoder_commit,
.disable = radeon_atom_encoder_disable, .disable = radeon_atom_encoder_disable,
/* no detect for TMDS/LVDS yet */ .detect = radeon_atom_dig_detect,
}; };
static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = { static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {

View File

@ -40,6 +40,35 @@
#include "radeon.h" #include "radeon.h"
#include "radeon_trace.h" #include "radeon_trace.h"
static void radeon_fence_write(struct radeon_device *rdev, u32 seq)
{
if (rdev->wb.enabled) {
u32 scratch_index;
if (rdev->wb.use_event)
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
else
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);;
} else
WREG32(rdev->fence_drv.scratch_reg, seq);
}
static u32 radeon_fence_read(struct radeon_device *rdev)
{
u32 seq;
if (rdev->wb.enabled) {
u32 scratch_index;
if (rdev->wb.use_event)
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
else
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
} else
seq = RREG32(rdev->fence_drv.scratch_reg);
return seq;
}
int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
{ {
unsigned long irq_flags; unsigned long irq_flags;
@ -50,12 +79,12 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
return 0; return 0;
} }
fence->seq = atomic_add_return(1, &rdev->fence_drv.seq); fence->seq = atomic_add_return(1, &rdev->fence_drv.seq);
if (!rdev->cp.ready) { if (!rdev->cp.ready)
/* FIXME: cp is not running assume everythings is done right /* FIXME: cp is not running assume everythings is done right
* away * away
*/ */
WREG32(rdev->fence_drv.scratch_reg, fence->seq); radeon_fence_write(rdev, fence->seq);
} else else
radeon_fence_ring_emit(rdev, fence); radeon_fence_ring_emit(rdev, fence);
trace_radeon_fence_emit(rdev->ddev, fence->seq); trace_radeon_fence_emit(rdev->ddev, fence->seq);
@ -73,15 +102,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
bool wake = false; bool wake = false;
unsigned long cjiffies; unsigned long cjiffies;
if (rdev->wb.enabled) { seq = radeon_fence_read(rdev);
u32 scratch_index;
if (rdev->wb.use_event)
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
else
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
} else
seq = RREG32(rdev->fence_drv.scratch_reg);
if (seq != rdev->fence_drv.last_seq) { if (seq != rdev->fence_drv.last_seq) {
rdev->fence_drv.last_seq = seq; rdev->fence_drv.last_seq = seq;
rdev->fence_drv.last_jiffies = jiffies; rdev->fence_drv.last_jiffies = jiffies;
@ -251,7 +272,7 @@ retry:
r = radeon_gpu_reset(rdev); r = radeon_gpu_reset(rdev);
if (r) if (r)
return r; return r;
WREG32(rdev->fence_drv.scratch_reg, fence->seq); radeon_fence_write(rdev, fence->seq);
rdev->gpu_lockup = false; rdev->gpu_lockup = false;
} }
timeout = RADEON_FENCE_JIFFIES_TIMEOUT; timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
@ -351,7 +372,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev)
write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
return r; return r;
} }
WREG32(rdev->fence_drv.scratch_reg, 0); radeon_fence_write(rdev, 0);
atomic_set(&rdev->fence_drv.seq, 0); atomic_set(&rdev->fence_drv.seq, 0);
INIT_LIST_HEAD(&rdev->fence_drv.created); INIT_LIST_HEAD(&rdev->fence_drv.created);
INIT_LIST_HEAD(&rdev->fence_drv.emited); INIT_LIST_HEAD(&rdev->fence_drv.emited);
@ -391,7 +412,7 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data)
struct radeon_fence *fence; struct radeon_fence *fence;
seq_printf(m, "Last signaled fence 0x%08X\n", seq_printf(m, "Last signaled fence 0x%08X\n",
RREG32(rdev->fence_drv.scratch_reg)); radeon_fence_read(rdev));
if (!list_empty(&rdev->fence_drv.emited)) { if (!list_empty(&rdev->fence_drv.emited)) {
fence = list_entry(rdev->fence_drv.emited.prev, fence = list_entry(rdev->fence_drv.emited.prev,
struct radeon_fence, list); struct radeon_fence, list);

View File

@ -483,6 +483,8 @@ extern void radeon_atom_encoder_init(struct radeon_device *rdev);
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
int action, uint8_t lane_num, int action, uint8_t lane_num,
uint8_t lane_set); uint8_t lane_set);
extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
extern struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder);
extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
u8 write_byte, u8 *read_byte); u8 write_byte, u8 *read_byte);

View File

@ -105,6 +105,9 @@ void rv770_pm_misc(struct radeon_device *rdev)
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
/* 0xff01 is a flag rather then an actual voltage */
if (voltage->voltage == 0xff01)
return;
if (voltage->voltage != rdev->pm.current_vddc) { if (voltage->voltage != rdev->pm.current_vddc) {
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
rdev->pm.current_vddc = voltage->voltage; rdev->pm.current_vddc = voltage->voltage;

View File

@ -305,6 +305,7 @@ config HID_MULTITOUCH
- 3M PCT touch screens - 3M PCT touch screens
- ActionStar dual touch panels - ActionStar dual touch panels
- Cando dual touch panels - Cando dual touch panels
- Chunghwa panels
- CVTouch panels - CVTouch panels
- Cypress TrueTouch panels - Cypress TrueTouch panels
- Elo TouchSystems IntelliTouch Plus panels - Elo TouchSystems IntelliTouch Plus panels

View File

@ -1359,6 +1359,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },

View File

@ -173,6 +173,9 @@
#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
#define USB_VENDOR_ID_CHUNGHWAT 0x2247
#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
#define USB_VENDOR_ID_CIDC 0x1677 #define USB_VENDOR_ID_CIDC 0x1677
#define USB_VENDOR_ID_CMEDIA 0x0d8c #define USB_VENDOR_ID_CMEDIA 0x0d8c
@ -622,6 +625,7 @@
#define USB_VENDOR_ID_UCLOGIC 0x5543 #define USB_VENDOR_ID_UCLOGIC 0x5543
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60 0x0064
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005

View File

@ -501,17 +501,9 @@ static int magicmouse_probe(struct hid_device *hdev,
} }
report->size = 6; report->size = 6;
/*
* The device reponds with 'invalid report id' when feature
* report switching it into multitouch mode is sent to it.
*
* This results in -EIO from the _raw low-level transport callback,
* but there seems to be no other way of switching the mode.
* Thus the super-ugly hacky success check below.
*/
ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
HID_FEATURE_REPORT); HID_FEATURE_REPORT);
if (ret != -EIO) { if (ret != sizeof(feature)) {
hid_err(hdev, "unable to request touch data (%d)\n", ret); hid_err(hdev, "unable to request touch data (%d)\n", ret);
goto err_stop_hw; goto err_stop_hw;
} }

View File

@ -64,6 +64,7 @@ struct mt_device {
struct mt_class *mtclass; /* our mt device class */ struct mt_class *mtclass; /* our mt device class */
unsigned last_field_index; /* last field index of the report */ unsigned last_field_index; /* last field index of the report */
unsigned last_slot_field; /* the last field of a slot */ unsigned last_slot_field; /* the last field of a slot */
int last_mt_collection; /* last known mt-related collection */
__s8 inputmode; /* InputMode HID feature, -1 if non-existent */ __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
__u8 num_received; /* how many contacts we received */ __u8 num_received; /* how many contacts we received */
__u8 num_expected; /* expected last contact index */ __u8 num_expected; /* expected last contact index */
@ -225,8 +226,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
cls->sn_move); cls->sn_move);
/* touchscreen emulation */ /* touchscreen emulation */
set_abs(hi->input, ABS_X, field, cls->sn_move); set_abs(hi->input, ABS_X, field, cls->sn_move);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_GD_Y: case HID_GD_Y:
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@ -237,8 +240,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
cls->sn_move); cls->sn_move);
/* touchscreen emulation */ /* touchscreen emulation */
set_abs(hi->input, ABS_Y, field, cls->sn_move); set_abs(hi->input, ABS_Y, field, cls->sn_move);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
} }
return 0; return 0;
@ -246,31 +251,40 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case HID_UP_DIGITIZER: case HID_UP_DIGITIZER:
switch (usage->hid) { switch (usage->hid) {
case HID_DG_INRANGE: case HID_DG_INRANGE:
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_CONFIDENCE: case HID_DG_CONFIDENCE:
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_TIPSWITCH: case HID_DG_TIPSWITCH:
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
input_set_capability(hi->input, EV_KEY, BTN_TOUCH); input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_CONTACTID: case HID_DG_CONTACTID:
input_mt_init_slots(hi->input, td->maxcontacts); input_mt_init_slots(hi->input, td->maxcontacts);
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
td->last_mt_collection = usage->collection_index;
return 1; return 1;
case HID_DG_WIDTH: case HID_DG_WIDTH:
hid_map_usage(hi, usage, bit, max, hid_map_usage(hi, usage, bit, max,
EV_ABS, ABS_MT_TOUCH_MAJOR); EV_ABS, ABS_MT_TOUCH_MAJOR);
set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
cls->sn_width); cls->sn_width);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_HEIGHT: case HID_DG_HEIGHT:
hid_map_usage(hi, usage, bit, max, hid_map_usage(hi, usage, bit, max,
@ -279,8 +293,10 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
cls->sn_height); cls->sn_height);
input_set_abs_params(hi->input, input_set_abs_params(hi->input,
ABS_MT_ORIENTATION, 0, 1, 0, 0); ABS_MT_ORIENTATION, 0, 1, 0, 0);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_TIPPRESSURE: case HID_DG_TIPPRESSURE:
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP) if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@ -292,15 +308,19 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
/* touchscreen emulation */ /* touchscreen emulation */
set_abs(hi->input, ABS_PRESSURE, field, set_abs(hi->input, ABS_PRESSURE, field,
cls->sn_pressure); cls->sn_pressure);
if (td->last_mt_collection == usage->collection_index) {
td->last_slot_field = usage->hid; td->last_slot_field = usage->hid;
td->last_field_index = field->index; td->last_field_index = field->index;
}
return 1; return 1;
case HID_DG_CONTACTCOUNT: case HID_DG_CONTACTCOUNT:
if (td->last_mt_collection == usage->collection_index)
td->last_field_index = field->index; td->last_field_index = field->index;
return 1; return 1;
case HID_DG_CONTACTMAX: case HID_DG_CONTACTMAX:
/* we don't set td->last_slot_field as contactcount and /* we don't set td->last_slot_field as contactcount and
* contact max are global to the report */ * contact max are global to the report */
if (td->last_mt_collection == usage->collection_index)
td->last_field_index = field->index; td->last_field_index = field->index;
return -1; return -1;
} }
@ -516,6 +536,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
} }
td->mtclass = mtclass; td->mtclass = mtclass;
td->inputmode = -1; td->inputmode = -1;
td->last_mt_collection = -1;
hid_set_drvdata(hdev, td); hid_set_drvdata(hdev, td);
ret = hid_parse(hdev); ret = hid_parse(hdev);
@ -593,6 +614,11 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_CANDO, HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
/* Chunghwa Telecom touch panels */
{ .driver_data = MT_CLS_DEFAULT,
HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
/* CVTouch panels */ /* CVTouch panels */
{ .driver_data = MT_CLS_DEFAULT, { .driver_data = MT_CLS_DEFAULT,
HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,

View File

@ -74,6 +74,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },

View File

@ -248,12 +248,15 @@ static int hiddev_release(struct inode * inode, struct file * file)
usbhid_close(list->hiddev->hid); usbhid_close(list->hiddev->hid);
usbhid_put_power(list->hiddev->hid); usbhid_put_power(list->hiddev->hid);
} else { } else {
mutex_unlock(&list->hiddev->existancelock);
kfree(list->hiddev); kfree(list->hiddev);
kfree(list);
return 0;
} }
} }
kfree(list);
mutex_unlock(&list->hiddev->existancelock); mutex_unlock(&list->hiddev->existancelock);
kfree(list);
return 0; return 0;
} }
@ -923,10 +926,11 @@ void hiddev_disconnect(struct hid_device *hid)
usb_deregister_dev(usbhid->intf, &hiddev_class); usb_deregister_dev(usbhid->intf, &hiddev_class);
if (hiddev->open) { if (hiddev->open) {
mutex_unlock(&hiddev->existancelock);
usbhid_close(hiddev->hid); usbhid_close(hiddev->hid);
wake_up_interruptible(&hiddev->wait); wake_up_interruptible(&hiddev->wait);
} else { } else {
mutex_unlock(&hiddev->existancelock);
kfree(hiddev); kfree(hiddev);
} }
mutex_unlock(&hiddev->existancelock);
} }

View File

@ -268,6 +268,7 @@ static struct device_attribute atk_name_attr =
static void atk_init_attribute(struct device_attribute *attr, char *name, static void atk_init_attribute(struct device_attribute *attr, char *name,
sysfs_show_func show) sysfs_show_func show)
{ {
sysfs_attr_init(&attr->attr);
attr->attr.name = name; attr->attr.name = name;
attr->attr.mode = 0444; attr->attr.mode = 0444;
attr->show = show; attr->show = show;
@ -1188,19 +1189,15 @@ static int atk_create_files(struct atk_data *data)
int err; int err;
list_for_each_entry(s, &data->sensor_list, list) { list_for_each_entry(s, &data->sensor_list, list) {
sysfs_attr_init(&s->input_attr.attr);
err = device_create_file(data->hwmon_dev, &s->input_attr); err = device_create_file(data->hwmon_dev, &s->input_attr);
if (err) if (err)
return err; return err;
sysfs_attr_init(&s->label_attr.attr);
err = device_create_file(data->hwmon_dev, &s->label_attr); err = device_create_file(data->hwmon_dev, &s->label_attr);
if (err) if (err)
return err; return err;
sysfs_attr_init(&s->limit1_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit1_attr); err = device_create_file(data->hwmon_dev, &s->limit1_attr);
if (err) if (err)
return err; return err;
sysfs_attr_init(&s->limit2_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit2_attr); err = device_create_file(data->hwmon_dev, &s->limit2_attr);
if (err) if (err)
return err; return err;

View File

@ -97,9 +97,7 @@ struct platform_data {
struct pdev_entry { struct pdev_entry {
struct list_head list; struct list_head list;
struct platform_device *pdev; struct platform_device *pdev;
unsigned int cpu;
u16 phys_proc_id; u16 phys_proc_id;
u16 cpu_core_id;
}; };
static LIST_HEAD(pdev_list); static LIST_HEAD(pdev_list);
@ -653,9 +651,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
} }
pdev_entry->pdev = pdev; pdev_entry->pdev = pdev;
pdev_entry->cpu = cpu;
pdev_entry->phys_proc_id = TO_PHYS_ID(cpu); pdev_entry->phys_proc_id = TO_PHYS_ID(cpu);
pdev_entry->cpu_core_id = TO_CORE_ID(cpu);
list_add_tail(&pdev_entry->list, &pdev_list); list_add_tail(&pdev_entry->list, &pdev_list);
mutex_unlock(&pdev_list_mutex); mutex_unlock(&pdev_list_mutex);

View File

@ -947,6 +947,7 @@ static int aem_register_sensors(struct aem_data *data,
/* Set up read-only sensors */ /* Set up read-only sensors */
while (ro->label) { while (ro->label) {
sysfs_attr_init(&sensors->dev_attr.attr);
sensors->dev_attr.attr.name = ro->label; sensors->dev_attr.attr.name = ro->label;
sensors->dev_attr.attr.mode = S_IRUGO; sensors->dev_attr.attr.mode = S_IRUGO;
sensors->dev_attr.show = ro->show; sensors->dev_attr.show = ro->show;
@ -963,6 +964,7 @@ static int aem_register_sensors(struct aem_data *data,
/* Set up read-write sensors */ /* Set up read-write sensors */
while (rw->label) { while (rw->label) {
sysfs_attr_init(&sensors->dev_attr.attr);
sensors->dev_attr.attr.name = rw->label; sensors->dev_attr.attr.name = rw->label;
sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR; sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
sensors->dev_attr.show = rw->show; sensors->dev_attr.show = rw->show;

View File

@ -358,6 +358,7 @@ static int create_sensor(struct ibmpex_bmc_data *data, int type,
else if (type == POWER_SENSOR) else if (type == POWER_SENSOR)
sprintf(n, power_sensor_name_templates[func], "power", counter); sprintf(n, power_sensor_name_templates[func], "power", counter);
sysfs_attr_init(&data->sensors[sensor].attr[func].dev_attr.attr);
data->sensors[sensor].attr[func].dev_attr.attr.name = n; data->sensors[sensor].attr[func].dev_attr.attr.name = n;
data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO; data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO;
data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor; data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor;

View File

@ -232,6 +232,7 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr = &attrs->in; attr = &attrs->in;
attr->index = channel; attr->index = channel;
sysfs_attr_init(&attr->dev_attr.attr);
attr->dev_attr.attr.name = attrs->in_name; attr->dev_attr.attr.name = attrs->in_name;
attr->dev_attr.attr.mode = S_IRUGO; attr->dev_attr.attr.mode = S_IRUGO;
attr->dev_attr.show = s3c_hwmon_ch_show; attr->dev_attr.show = s3c_hwmon_ch_show;
@ -249,6 +250,7 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr = &attrs->label; attr = &attrs->label;
attr->index = channel; attr->index = channel;
sysfs_attr_init(&attr->dev_attr.attr);
attr->dev_attr.attr.name = attrs->label_name; attr->dev_attr.attr.name = attrs->label_name;
attr->dev_attr.attr.mode = S_IRUGO; attr->dev_attr.attr.mode = S_IRUGO;
attr->dev_attr.show = s3c_hwmon_label_show; attr->dev_attr.show = s3c_hwmon_label_show;

View File

@ -111,6 +111,7 @@ static void evdev_event(struct input_handle *handle,
rcu_read_unlock(); rcu_read_unlock();
if (type == EV_SYN && code == SYN_REPORT)
wake_up_interruptible(&evdev->wait); wake_up_interruptible(&evdev->wait);
} }

View File

@ -1756,7 +1756,7 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
} else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
clamp(mt_slots, 2, 32); mt_slots = clamp(mt_slots, 2, 32);
} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
mt_slots = 2; mt_slots = 2;
} else { } else {

View File

@ -209,6 +209,7 @@ static void omap_kp_tasklet(unsigned long data)
#endif #endif
} }
} }
input_sync(omap_kp_data->input);
memcpy(keypad_state, new_state, sizeof(keypad_state)); memcpy(keypad_state, new_state, sizeof(keypad_state));
if (key_down) { if (key_down) {

View File

@ -32,7 +32,7 @@ static const struct {
[SH_KEYSC_MODE_3] = { 2, 4, 7 }, [SH_KEYSC_MODE_3] = { 2, 4, 7 },
[SH_KEYSC_MODE_4] = { 3, 6, 6 }, [SH_KEYSC_MODE_4] = { 3, 6, 6 },
[SH_KEYSC_MODE_5] = { 4, 6, 7 }, [SH_KEYSC_MODE_5] = { 4, 6, 7 },
[SH_KEYSC_MODE_6] = { 5, 7, 7 }, [SH_KEYSC_MODE_6] = { 5, 8, 8 },
}; };
struct sh_keysc_priv { struct sh_keysc_priv {

View File

@ -187,7 +187,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
if (size == 0) if (size == 0)
size = xres ? : 1; size = xres ? : 1;
clamp(value, min, max); value = clamp(value, min, max);
mousedev->packet.x = ((value - min) * xres) / size; mousedev->packet.x = ((value - min) * xres) / size;
mousedev->packet.abs_event = 1; mousedev->packet.abs_event = 1;
@ -201,7 +201,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
if (size == 0) if (size == 0)
size = yres ? : 1; size = yres ? : 1;
clamp(value, min, max); value = clamp(value, min, max);
mousedev->packet.y = yres - ((value - min) * yres) / size; mousedev->packet.y = yres - ((value - min) * yres) / size;
mousedev->packet.abs_event = 1; mousedev->packet.abs_event = 1;

View File

@ -156,8 +156,10 @@ static int if_open(struct tty_struct *tty, struct file *filp)
if (!cs || !try_module_get(cs->driver->owner)) if (!cs || !try_module_get(cs->driver->owner))
return -ENODEV; return -ENODEV;
if (mutex_lock_interruptible(&cs->mutex)) if (mutex_lock_interruptible(&cs->mutex)) {
module_put(cs->driver->owner);
return -ERESTARTSYS; return -ERESTARTSYS;
}
tty->driver_data = cs; tty->driver_data = cs;
++cs->open_count; ++cs->open_count;

View File

@ -495,14 +495,14 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
} }
} }
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
if (atomic_dec_return(&queued_msg->use_count) == 0) { if (atomic_dec_return(&queued_msg->use_count) == 0) {
dev_kfree_skb(skb); dev_kfree_skb(skb);
kfree(queued_msg); kfree(queued_msg);
} }
dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len;
return NETDEV_TX_OK; return NETDEV_TX_OK;
} }

View File

@ -412,7 +412,7 @@ el2_open(struct net_device *dev)
outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
outb_p(0x00, E33G_IDCFR); outb_p(0x00, E33G_IDCFR);
msleep(1); msleep(1);
free_irq(*irqp, el2_probe_interrupt); free_irq(*irqp, &seen);
if (!seen) if (!seen)
continue; continue;
@ -422,6 +422,7 @@ el2_open(struct net_device *dev)
continue; continue;
if (retval < 0) if (retval < 0)
goto err_disable; goto err_disable;
break;
} while (*++irqp); } while (*++irqp);
if (*irqp == 0) { if (*irqp == 0) {

View File

@ -52,13 +52,13 @@ MODULE_DESCRIPTION(DRV_DESC);
MODULE_ALIAS("platform:bfin_mac"); MODULE_ALIAS("platform:bfin_mac");
#if defined(CONFIG_BFIN_MAC_USE_L1) #if defined(CONFIG_BFIN_MAC_USE_L1)
# define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size) # define bfin_mac_alloc(dma_handle, size, num) l1_data_sram_zalloc(size*num)
# define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr) # define bfin_mac_free(dma_handle, ptr, num) l1_data_sram_free(ptr)
#else #else
# define bfin_mac_alloc(dma_handle, size) \ # define bfin_mac_alloc(dma_handle, size, num) \
dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL) dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL)
# define bfin_mac_free(dma_handle, ptr) \ # define bfin_mac_free(dma_handle, ptr, num) \
dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle) dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle)
#endif #endif
#define PKT_BUF_SZ 1580 #define PKT_BUF_SZ 1580
@ -95,7 +95,7 @@ static void desc_list_free(void)
t = t->next; t = t->next;
} }
} }
bfin_mac_free(dma_handle, tx_desc); bfin_mac_free(dma_handle, tx_desc, CONFIG_BFIN_TX_DESC_NUM);
} }
if (rx_desc) { if (rx_desc) {
@ -109,7 +109,7 @@ static void desc_list_free(void)
r = r->next; r = r->next;
} }
} }
bfin_mac_free(dma_handle, rx_desc); bfin_mac_free(dma_handle, rx_desc, CONFIG_BFIN_RX_DESC_NUM);
} }
} }
@ -126,13 +126,13 @@ static int desc_list_init(void)
#endif #endif
tx_desc = bfin_mac_alloc(&dma_handle, tx_desc = bfin_mac_alloc(&dma_handle,
sizeof(struct net_dma_desc_tx) * sizeof(struct net_dma_desc_tx),
CONFIG_BFIN_TX_DESC_NUM); CONFIG_BFIN_TX_DESC_NUM);
if (tx_desc == NULL) if (tx_desc == NULL)
goto init_error; goto init_error;
rx_desc = bfin_mac_alloc(&dma_handle, rx_desc = bfin_mac_alloc(&dma_handle,
sizeof(struct net_dma_desc_rx) * sizeof(struct net_dma_desc_rx),
CONFIG_BFIN_RX_DESC_NUM); CONFIG_BFIN_RX_DESC_NUM);
if (rx_desc == NULL) if (rx_desc == NULL)
goto init_error; goto init_error;

View File

@ -1297,6 +1297,7 @@ static inline int slave_enable_netpoll(struct slave *slave)
goto out; goto out;
np->dev = slave->dev; np->dev = slave->dev;
strlcpy(np->dev_name, slave->dev->name, IFNAMSIZ);
err = __netpoll_setup(np); err = __netpoll_setup(np);
if (err) { if (err) {
kfree(np); kfree(np);

View File

@ -105,7 +105,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
goto out_ep; goto out_ep;
fep->fcc.mem = (void __iomem *)cpm2_immr; fep->fcc.mem = (void __iomem *)cpm2_immr;
fpi->dpram_offset = cpm_dpalloc(128, 8); fpi->dpram_offset = cpm_dpalloc(128, 32);
if (IS_ERR_VALUE(fpi->dpram_offset)) { if (IS_ERR_VALUE(fpi->dpram_offset)) {
ret = fpi->dpram_offset; ret = fpi->dpram_offset;
goto out_fcccp; goto out_fcccp;

View File

@ -1580,12 +1580,12 @@ static netdev_tx_t hp100_start_xmit_bm(struct sk_buff *skb,
hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */ hp100_outl(ringptr->pdl_paddr, TX_PDA_L); /* Low Prio. Queue */
lp->txrcommit++; lp->txrcommit++;
spin_unlock_irqrestore(&lp->lock, flags);
/* Update statistics */
dev->stats.tx_packets++; dev->stats.tx_packets++;
dev->stats.tx_bytes += skb->len; dev->stats.tx_bytes += skb->len;
spin_unlock_irqrestore(&lp->lock, flags);
return NETDEV_TX_OK; return NETDEV_TX_OK;
drop: drop:

View File

@ -135,7 +135,7 @@ static void __devexit hplance_remove_one(struct dio_dev *d)
} }
/* Initialise a single lance board at the given DIO device */ /* Initialise a single lance board at the given DIO device */
static void __init hplance_init(struct net_device *dev, struct dio_dev *d) static void __devinit hplance_init(struct net_device *dev, struct dio_dev *d)
{ {
unsigned long va = (d->resource.start + DIO_VIRADDRBASE); unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
struct hplance_private *lp; struct hplance_private *lp;

View File

@ -1965,11 +1965,11 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
netxen_tso_check(netdev, tx_ring, first_desc, skb); netxen_tso_check(netdev, tx_ring, first_desc, skb);
netxen_nic_update_cmd_producer(adapter, tx_ring);
adapter->stats.txbytes += skb->len; adapter->stats.txbytes += skb->len;
adapter->stats.xmitcalled++; adapter->stats.xmitcalled++;
netxen_nic_update_cmd_producer(adapter, tx_ring);
return NETDEV_TX_OK; return NETDEV_TX_OK;
drop_packet: drop_packet:

View File

@ -58,6 +58,7 @@ config BROADCOM_PHY
config BCM63XX_PHY config BCM63XX_PHY
tristate "Drivers for Broadcom 63xx SOCs internal PHY" tristate "Drivers for Broadcom 63xx SOCs internal PHY"
depends on BCM63XX
---help--- ---help---
Currently supports the 6348 and 6358 PHYs. Currently supports the 6348 and 6358 PHYs.

View File

@ -543,11 +543,20 @@ static void recalibrate(struct dp83640_clock *clock)
/* time stamping methods */ /* time stamping methods */
static void decode_evnt(struct dp83640_private *dp83640, static int decode_evnt(struct dp83640_private *dp83640,
struct phy_txts *phy_txts, u16 ests) void *data, u16 ests)
{ {
struct phy_txts *phy_txts;
struct ptp_clock_event event; struct ptp_clock_event event;
int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK; int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK;
u16 ext_status = 0;
if (ests & MULT_EVNT) {
ext_status = *(u16 *) data;
data += sizeof(ext_status);
}
phy_txts = data;
switch (words) { /* fall through in every case */ switch (words) { /* fall through in every case */
case 3: case 3:
@ -565,6 +574,9 @@ static void decode_evnt(struct dp83640_private *dp83640,
event.timestamp = phy2txts(&dp83640->edata); event.timestamp = phy2txts(&dp83640->edata);
ptp_clock_event(dp83640->clock->ptp_clock, &event); ptp_clock_event(dp83640->clock->ptp_clock, &event);
words = ext_status ? words + 2 : words + 1;
return words * sizeof(u16);
} }
static void decode_rxts(struct dp83640_private *dp83640, static void decode_rxts(struct dp83640_private *dp83640,
@ -643,9 +655,7 @@ static void decode_status_frame(struct dp83640_private *dp83640,
} else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) { } else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) {
phy_txts = (struct phy_txts *) ptr; size = decode_evnt(dp83640, ptr, ests);
decode_evnt(dp83640, phy_txts, ests);
size = sizeof(*phy_txts);
} else { } else {
size = 0; size = 0;
@ -1034,8 +1044,8 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
if (is_status_frame(skb, type)) { if (is_status_frame(skb, type)) {
decode_status_frame(dp83640, skb); decode_status_frame(dp83640, skb);
/* Let the stack drop this frame. */ kfree_skb(skb);
return false; return true;
} }
SKB_PTP_TYPE(skb) = type; SKB_PTP_TYPE(skb) = type;

View File

@ -523,7 +523,7 @@ static void ppp_async_process(unsigned long arg)
#define PUT_BYTE(ap, buf, c, islcp) do { \ #define PUT_BYTE(ap, buf, c, islcp) do { \
if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\ if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
*buf++ = PPP_ESCAPE; \ *buf++ = PPP_ESCAPE; \
*buf++ = c ^ 0x20; \ *buf++ = c ^ PPP_TRANS; \
} else \ } else \
*buf++ = c; \ *buf++ = c; \
} while (0) } while (0)
@ -896,7 +896,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
sp = skb_put(skb, n); sp = skb_put(skb, n);
memcpy(sp, buf, n); memcpy(sp, buf, n);
if (ap->state & SC_ESCAPE) { if (ap->state & SC_ESCAPE) {
sp[0] ^= 0x20; sp[0] ^= PPP_TRANS;
ap->state &= ~SC_ESCAPE; ap->state &= ~SC_ESCAPE;
} }
} }

View File

@ -1273,7 +1273,7 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
wmb(); wmb();
wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
stats->tx_bytes += skb->len; stats->tx_bytes += length;
stats->tx_packets++; stats->tx_packets++;
dev->trans_start = jiffies; dev->trans_start = jiffies;
if (pep->tx_ring_size - pep->tx_desc_count <= 1) { if (pep->tx_ring_size - pep->tx_desc_count <= 1) {

View File

@ -1621,7 +1621,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
* *
* (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
*/ */
static const struct { static const struct rtl_mac_info {
u32 mask; u32 mask;
u32 val; u32 val;
int mac_version; int mac_version;
@ -1689,7 +1689,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
/* Catch-all */ /* Catch-all */
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE } { 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
}, *p = mac_info; };
const struct rtl_mac_info *p = mac_info;
u32 reg; u32 reg;
reg = RTL_R32(TxConfig); reg = RTL_R32(TxConfig);
@ -3681,7 +3682,7 @@ static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
{ {
static const struct { static const struct rtl_cfg2_info {
u32 mac_version; u32 mac_version;
u32 clk; u32 clk;
u32 val; u32 val;
@ -3690,7 +3691,8 @@ static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
{ RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff }, { RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
{ RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe { RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
{ RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff } { RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
}, *p = cfg2_info; };
const struct rtl_cfg2_info *p = cfg2_info;
unsigned int i; unsigned int i;
u32 clk; u32 clk;

View File

@ -460,7 +460,23 @@ static u32 tun_net_fix_features(struct net_device *dev, u32 features)
return (features & tun->set_features) | (features & ~TUN_USER_FEATURES); return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
} }
#ifdef CONFIG_NET_POLL_CONTROLLER
static void tun_poll_controller(struct net_device *dev)
{
/*
* Tun only receives frames when:
* 1) the char device endpoint gets data from user space
* 2) the tun socket gets a sendmsg call from user space
* Since both of those are syncronous operations, we are guaranteed
* never to have pending data when we poll for it
* so theres nothing to do here but return.
* We need this though so netpoll recognizes us as an interface that
* supports polling, which enables bridge devices in virt setups to
* still use netconsole
*/
return;
}
#endif
static const struct net_device_ops tun_netdev_ops = { static const struct net_device_ops tun_netdev_ops = {
.ndo_uninit = tun_net_uninit, .ndo_uninit = tun_net_uninit,
.ndo_open = tun_net_open, .ndo_open = tun_net_open,
@ -468,6 +484,9 @@ static const struct net_device_ops tun_netdev_ops = {
.ndo_start_xmit = tun_net_xmit, .ndo_start_xmit = tun_net_xmit,
.ndo_change_mtu = tun_net_change_mtu, .ndo_change_mtu = tun_net_change_mtu,
.ndo_fix_features = tun_net_fix_features, .ndo_fix_features = tun_net_fix_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = tun_poll_controller,
#endif
}; };
static const struct net_device_ops tap_netdev_ops = { static const struct net_device_ops tap_netdev_ops = {
@ -480,6 +499,9 @@ static const struct net_device_ops tap_netdev_ops = {
.ndo_set_multicast_list = tun_net_mclist, .ndo_set_multicast_list = tun_net_mclist,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = tun_poll_controller,
#endif
}; };
/* Initialize net device. */ /* Initialize net device. */

View File

@ -385,6 +385,16 @@ config USB_NET_CX82310_ETH
router with USB ethernet port. This driver is for routers only, router with USB ethernet port. This driver is for routers only,
it will not work with ADSL modems (use cxacru driver instead). it will not work with ADSL modems (use cxacru driver instead).
config USB_NET_KALMIA
tristate "Samsung Kalmia based LTE USB modem"
depends on USB_USBNET
help
Choose this option if you have a Samsung Kalmia based USB modem
as Samsung GT-B3730.
To compile this driver as a module, choose M here: the
module will be called kalmia.
config USB_HSO config USB_HSO
tristate "Option USB High Speed Mobile Devices" tristate "Option USB High Speed Mobile Devices"
depends on USB && RFKILL depends on USB && RFKILL

View File

@ -23,6 +23,7 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
obj-$(CONFIG_USB_USBNET) += usbnet.o obj-$(CONFIG_USB_USBNET) += usbnet.o
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o
obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o
obj-$(CONFIG_USB_NET_KALMIA) += kalmia.o
obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o

384
drivers/net/usb/kalmia.c Normal file
View File

@ -0,0 +1,384 @@
/*
* USB network interface driver for Samsung Kalmia based LTE USB modem like the
* Samsung GT-B3730 and GT-B3710.
*
* Copyright (C) 2011 Marius Bjoernstad Kotsbak <marius@kotsbak.com>
*
* Sponsored by Quicklink Video Distribution Services Ltd.
*
* Based on the cdc_eem module.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ctype.h>
#include <linux/ethtool.h>
#include <linux/workqueue.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/crc32.h>
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
#include <linux/gfp.h>
/*
* The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control
* handled by the "option" module and an ethernet data port handled by this
* module.
*
* The stick must first be switched into modem mode by usb_modeswitch
* or similar tool. Then the modem gets sent two initialization packets by
* this module, which gives the MAC address of the device. User space can then
* connect the modem using AT commands through the ACM port and then use
* DHCP on the network interface exposed by this module. Network packets are
* sent to and from the modem in a proprietary format discovered after watching
* the behavior of the windows driver for the modem.
*
* More information about the use of the modem is available in usb_modeswitch
* forum and the project page:
*
* http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
* https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
*/
/* #define DEBUG */
/* #define VERBOSE */
#define KALMIA_HEADER_LENGTH 6
#define KALMIA_ALIGN_SIZE 4
#define KALMIA_USB_TIMEOUT 10000
/*-------------------------------------------------------------------------*/
static int
kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
u8 *buffer, u8 expected_len)
{
int act_len;
int status;
netdev_dbg(dev->net, "Sending init packet");
status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02),
init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT);
if (status != 0) {
netdev_err(dev->net,
"Error sending init packet. Status %i, length %i\n",
status, act_len);
return status;
}
else if (act_len != init_msg_len) {
netdev_err(dev->net,
"Did not send all of init packet. Bytes sent: %i",
act_len);
}
else {
netdev_dbg(dev->net, "Successfully sent init packet.");
}
status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81),
buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT);
if (status != 0)
netdev_err(dev->net,
"Error receiving init result. Status %i, length %i\n",
status, act_len);
else if (act_len != expected_len)
netdev_err(dev->net, "Unexpected init result length: %i\n",
act_len);
return status;
}
static int
kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
{
char init_msg_1[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00 };
char init_msg_2[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
0x00, 0x00 };
char receive_buf[28];
int status;
status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1)
/ sizeof(init_msg_1[0]), receive_buf, 24);
if (status != 0)
return status;
status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2)
/ sizeof(init_msg_2[0]), receive_buf, 28);
if (status != 0)
return status;
memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN);
return status;
}
static int
kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
{
u8 status;
u8 ethernet_addr[ETH_ALEN];
/* Don't bind to AT command interface */
if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
return -EINVAL;
dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK);
dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK);
dev->status = NULL;
dev->net->hard_header_len += KALMIA_HEADER_LENGTH;
dev->hard_mtu = 1400;
dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing
status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
if (status < 0) {
usb_set_intfdata(intf, NULL);
usb_driver_release_interface(driver_of(intf), intf);
return status;
}
memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN);
return status;
}
static struct sk_buff *
kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb2 = NULL;
u16 content_len;
unsigned char *header_start;
unsigned char ether_type_1, ether_type_2;
u8 remainder, padlen = 0;
if (!skb_cloned(skb)) {
int headroom = skb_headroom(skb);
int tailroom = skb_tailroom(skb);
if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom
>= KALMIA_HEADER_LENGTH))
goto done;
if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH
+ KALMIA_ALIGN_SIZE)) {
skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH,
skb->data, skb->len);
skb_set_tail_pointer(skb, skb->len);
goto done;
}
}
skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH,
KALMIA_ALIGN_SIZE, flags);
if (!skb2)
return NULL;
dev_kfree_skb_any(skb);
skb = skb2;
done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1,
ether_type_2);
/* According to empiric data for data packages */
header_start[0] = 0x57;
header_start[1] = 0x44;
content_len = skb->len - KALMIA_HEADER_LENGTH;
header_start[2] = (content_len & 0xff); /* low byte */
header_start[3] = (content_len >> 8); /* high byte */
header_start[4] = ether_type_1;
header_start[5] = ether_type_2;
/* Align to 4 bytes by padding with zeros */
remainder = skb->len % KALMIA_ALIGN_SIZE;
if (remainder > 0) {
padlen = KALMIA_ALIGN_SIZE - remainder;
memset(skb_put(skb, padlen), 0, padlen);
}
netdev_dbg(
dev->net,
"Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.",
content_len, padlen, header_start[0], header_start[1],
header_start[2], header_start[3], header_start[4],
header_start[5]);
return skb;
}
static int
kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
/*
* Our task here is to strip off framing, leaving skb with one
* data frame for the usbnet framework code to process.
*/
const u8 HEADER_END_OF_USB_PACKET[] =
{ 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
const u8 EXPECTED_UNKNOWN_HEADER_1[] =
{ 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
const u8 EXPECTED_UNKNOWN_HEADER_2[] =
{ 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
u8 i = 0;
/* incomplete header? */
if (skb->len < KALMIA_HEADER_LENGTH)
return 0;
do {
struct sk_buff *skb2 = NULL;
u8 *header_start;
u16 usb_packet_length, ether_packet_length;
int is_last;
header_start = skb->data;
if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) {
if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1,
sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp(
header_start, EXPECTED_UNKNOWN_HEADER_2,
sizeof(EXPECTED_UNKNOWN_HEADER_2))) {
netdev_dbg(
dev->net,
"Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
header_start[0], header_start[1],
header_start[2], header_start[3],
header_start[4], header_start[5],
skb->len - KALMIA_HEADER_LENGTH);
}
else {
netdev_err(
dev->net,
"Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
header_start[0], header_start[1],
header_start[2], header_start[3],
header_start[4], header_start[5],
skb->len - KALMIA_HEADER_LENGTH);
return 0;
}
}
else
netdev_dbg(
dev->net,
"Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
header_start[0], header_start[1], header_start[2],
header_start[3], header_start[4], header_start[5],
skb->len - KALMIA_HEADER_LENGTH);
/* subtract start header and end header */
usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
ether_packet_length = header_start[2] + (header_start[3] << 8);
skb_pull(skb, KALMIA_HEADER_LENGTH);
/* Some small packets misses end marker */
if (usb_packet_length < ether_packet_length) {
ether_packet_length = usb_packet_length
+ KALMIA_HEADER_LENGTH;
is_last = true;
}
else {
netdev_dbg(dev->net, "Correct package length #%i", i
+ 1);
is_last = (memcmp(skb->data + ether_packet_length,
HEADER_END_OF_USB_PACKET,
sizeof(HEADER_END_OF_USB_PACKET)) == 0);
if (!is_last) {
header_start = skb->data + ether_packet_length;
netdev_dbg(
dev->net,
"End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
header_start[0], header_start[1],
header_start[2], header_start[3],
header_start[4], header_start[5],
skb->len - KALMIA_HEADER_LENGTH);
}
}
if (is_last) {
skb2 = skb;
}
else {
skb2 = skb_clone(skb, GFP_ATOMIC);
if (unlikely(!skb2))
return 0;
}
skb_trim(skb2, ether_packet_length);
if (is_last) {
return 1;
}
else {
usbnet_skb_return(dev, skb2);
skb_pull(skb, ether_packet_length);
}
i++;
}
while (skb->len);
return 1;
}
static const struct driver_info kalmia_info = {
.description = "Samsung Kalmia LTE USB dongle",
.flags = FLAG_WWAN,
.bind = kalmia_bind,
.rx_fixup = kalmia_rx_fixup,
.tx_fixup = kalmia_tx_fixup
};
/*-------------------------------------------------------------------------*/
static const struct usb_device_id products[] = {
/* The unswitched USB ID, to get the module auto loaded: */
{ USB_DEVICE(0x04e8, 0x689a) },
/* The stick swithed into modem (by e.g. usb_modeswitch): */
{ USB_DEVICE(0x04e8, 0x6889),
.driver_info = (unsigned long) &kalmia_info, },
{ /* EMPTY == end of list */} };
MODULE_DEVICE_TABLE( usb, products);
static struct usb_driver kalmia_driver = {
.name = "kalmia",
.id_table = products,
.probe = usbnet_probe,
.disconnect = usbnet_disconnect,
.suspend = usbnet_suspend,
.resume = usbnet_resume
};
static int __init kalmia_init(void)
{
return usb_register(&kalmia_driver);
}
module_init( kalmia_init);
static void __exit kalmia_exit(void)
{
usb_deregister(&kalmia_driver);
}
module_exit( kalmia_exit);
MODULE_AUTHOR("Marius Bjoernstad Kotsbak <marius@kotsbak.com>");
MODULE_DESCRIPTION("Samsung Kalmia USB network driver");
MODULE_LICENSE("GPL");

View File

@ -2203,9 +2203,11 @@ fst_open(struct net_device *dev)
if (port->mode != FST_RAW) { if (port->mode != FST_RAW) {
err = hdlc_open(dev); err = hdlc_open(dev);
if (err) if (err) {
module_put(THIS_MODULE);
return err; return err;
} }
}
fst_openport(port); fst_openport(port);
netif_wake_queue(dev); netif_wake_queue(dev);

View File

@ -1288,6 +1288,8 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
*(unsigned long *) wdev_priv = (unsigned long) priv; *(unsigned long *) wdev_priv = (unsigned long) priv;
set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev);
ret = wiphy_register(wdev->wiphy); ret = wiphy_register(wdev->wiphy);
if (ret < 0) { if (ret < 0) {
dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n", dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",

View File

@ -2474,6 +2474,7 @@ struct mwl8k_cmd_set_hw_spec {
* faster client. * faster client.
*/ */
#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400 #define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY 0x00000400
#define MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR 0x00000200
#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 #define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010 #define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
@ -2510,7 +2511,8 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT | cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON | MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON |
MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY); MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY |
MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR);
cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);

View File

@ -11,6 +11,7 @@
* *
*/ */
#include <linux/gpio.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>

View File

@ -681,13 +681,14 @@ static void bfin_spi_pump_transfers(unsigned long data)
drv_data->cs_change = transfer->cs_change; drv_data->cs_change = transfer->cs_change;
/* Bits per word setup */ /* Bits per word setup */
bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; bits_per_word = transfer->bits_per_word ? :
if ((bits_per_word > 0) && (bits_per_word % 16 == 0)) { message->spi->bits_per_word ? : 8;
if (bits_per_word % 16 == 0) {
drv_data->n_bytes = bits_per_word/8; drv_data->n_bytes = bits_per_word/8;
drv_data->len = (transfer->len) >> 1; drv_data->len = (transfer->len) >> 1;
cr_width = BIT_CTL_WORDSIZE; cr_width = BIT_CTL_WORDSIZE;
drv_data->ops = &bfin_bfin_spi_transfer_ops_u16; drv_data->ops = &bfin_bfin_spi_transfer_ops_u16;
} else if ((bits_per_word > 0) && (bits_per_word % 8 == 0)) { } else if (bits_per_word % 8 == 0) {
drv_data->n_bytes = bits_per_word/8; drv_data->n_bytes = bits_per_word/8;
drv_data->len = transfer->len; drv_data->len = transfer->len;
cr_width = 0; cr_width = 0;

View File

@ -81,7 +81,6 @@ struct adis16201_state {
int adis16201_set_irq(struct iio_dev *indio_dev, bool enable); int adis16201_set_irq(struct iio_dev *indio_dev, bool enable);
#ifdef CONFIG_IIO_RING_BUFFER
enum adis16201_scan { enum adis16201_scan {
ADIS16201_SCAN_SUPPLY, ADIS16201_SCAN_SUPPLY,
ADIS16201_SCAN_ACC_X, ADIS16201_SCAN_ACC_X,
@ -92,6 +91,7 @@ enum adis16201_scan {
ADIS16201_SCAN_INCLI_Y, ADIS16201_SCAN_INCLI_Y,
}; };
#ifdef CONFIG_IIO_RING_BUFFER
void adis16201_remove_trigger(struct iio_dev *indio_dev); void adis16201_remove_trigger(struct iio_dev *indio_dev);
int adis16201_probe_trigger(struct iio_dev *indio_dev); int adis16201_probe_trigger(struct iio_dev *indio_dev);

View File

@ -76,7 +76,6 @@ struct adis16203_state {
int adis16203_set_irq(struct iio_dev *indio_dev, bool enable); int adis16203_set_irq(struct iio_dev *indio_dev, bool enable);
#ifdef CONFIG_IIO_RING_BUFFER
enum adis16203_scan { enum adis16203_scan {
ADIS16203_SCAN_SUPPLY, ADIS16203_SCAN_SUPPLY,
ADIS16203_SCAN_AUX_ADC, ADIS16203_SCAN_AUX_ADC,
@ -85,6 +84,7 @@ enum adis16203_scan {
ADIS16203_SCAN_INCLI_Y, ADIS16203_SCAN_INCLI_Y,
}; };
#ifdef CONFIG_IIO_RING_BUFFER
void adis16203_remove_trigger(struct iio_dev *indio_dev); void adis16203_remove_trigger(struct iio_dev *indio_dev);
int adis16203_probe_trigger(struct iio_dev *indio_dev); int adis16203_probe_trigger(struct iio_dev *indio_dev);

View File

@ -248,10 +248,6 @@ static int atyfb_sync(struct fb_info *info);
static int aty_init(struct fb_info *info); static int aty_init(struct fb_info *info);
#ifdef CONFIG_ATARI
static int store_video_par(char *videopar, unsigned char m64_num);
#endif
static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc); static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc); static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
@ -2268,11 +2264,13 @@ error:
return; return;
} }
#ifdef CONFIG_PCI
static void aty_bl_exit(struct backlight_device *bd) static void aty_bl_exit(struct backlight_device *bd)
{ {
backlight_device_unregister(bd); backlight_device_unregister(bd);
printk("aty: Backlight unloaded\n"); printk("aty: Backlight unloaded\n");
} }
#endif /* CONFIG_PCI */
#endif /* CONFIG_FB_ATY_BACKLIGHT */ #endif /* CONFIG_FB_ATY_BACKLIGHT */
@ -2789,7 +2787,7 @@ aty_init_exit:
return ret; return ret;
} }
#ifdef CONFIG_ATARI #if defined(CONFIG_ATARI) && !defined(MODULE)
static int __devinit store_video_par(char *video_str, unsigned char m64_num) static int __devinit store_video_par(char *video_str, unsigned char m64_num)
{ {
char *p; char *p;
@ -2818,7 +2816,7 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num)
phys_vmembase[m64_num] = 0; phys_vmembase[m64_num] = 0;
return -1; return -1;
} }
#endif /* CONFIG_ATARI */ #endif /* CONFIG_ATARI && !MODULE */
/* /*
* Blank the display. * Blank the display.

View File

@ -541,7 +541,7 @@ static int __init efifb_init(void)
*/ */
ret = platform_driver_probe(&efifb_driver, efifb_probe); ret = platform_driver_probe(&efifb_driver, efifb_probe);
if (ret) { if (ret) {
platform_device_unregister(&efifb_driver); platform_device_unregister(&efifb_device);
return ret; return ret;
} }

View File

@ -235,13 +235,12 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *info) struct fb_info *info)
{ {
struct s3c_fb_win *win = info->par; struct s3c_fb_win *win = info->par;
struct s3c_fb_pd_win *windata = win->windata;
struct s3c_fb *sfb = win->parent; struct s3c_fb *sfb = win->parent;
dev_dbg(sfb->dev, "checking parameters\n"); dev_dbg(sfb->dev, "checking parameters\n");
var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres); var->xres_virtual = max(var->xres_virtual, var->xres);
var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres); var->yres_virtual = max(var->yres_virtual, var->yres);
if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) { if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) {
dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n", dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n",
@ -558,6 +557,13 @@ static int s3c_fb_set_par(struct fb_info *info)
vidosd_set_alpha(win, alpha); vidosd_set_alpha(win, alpha);
vidosd_set_size(win, data); vidosd_set_size(win, data);
/* Enable DMA channel for this window */
if (sfb->variant.has_shadowcon) {
data = readl(sfb->regs + SHADOWCON);
data |= SHADOWCON_CHx_ENABLE(win_no);
writel(data, sfb->regs + SHADOWCON);
}
data = WINCONx_ENWIN; data = WINCONx_ENWIN;
/* note, since we have to round up the bits-per-pixel, we end up /* note, since we have to round up the bits-per-pixel, we end up
@ -637,13 +643,6 @@ static int s3c_fb_set_par(struct fb_info *info)
writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(data, regs + sfb->variant.wincon + (win_no * 4));
writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4));
/* Enable DMA channel for this window */
if (sfb->variant.has_shadowcon) {
data = readl(sfb->regs + SHADOWCON);
data |= SHADOWCON_CHx_ENABLE(win_no);
writel(data, sfb->regs + SHADOWCON);
}
shadow_protect_win(win, 0); shadow_protect_win(win, 0);
return 0; return 0;
@ -1487,11 +1486,10 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
kfree(sfb);
pm_runtime_put_sync(sfb->dev); pm_runtime_put_sync(sfb->dev);
pm_runtime_disable(sfb->dev); pm_runtime_disable(sfb->dev);
kfree(sfb);
return 0; return 0;
} }

View File

@ -1127,23 +1127,16 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
struct fb_info *info = hdmi->info; struct fb_info *info = hdmi->info;
unsigned long parent_rate = 0, hdmi_rate; unsigned long parent_rate = 0, hdmi_rate;
/* A device has been plugged in */
pm_runtime_get_sync(hdmi->dev);
ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate); ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
if (ret < 0) { if (ret < 0)
pm_runtime_put(hdmi->dev);
goto out; goto out;
}
hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE; hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
/* Reconfigure the clock */ /* Reconfigure the clock */
ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate); ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
if (ret < 0) { if (ret < 0)
pm_runtime_put(hdmi->dev);
goto out; goto out;
}
msleep(10); msleep(10);
sh_hdmi_configure(hdmi); sh_hdmi_configure(hdmi);
@ -1191,7 +1184,6 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
fb_set_suspend(hdmi->info, 1); fb_set_suspend(hdmi->info, 1);
console_unlock(); console_unlock();
pm_runtime_put(hdmi->dev);
} }
out: out:
@ -1312,7 +1304,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn); INIT_DELAYED_WORK(&hdmi->edid_work, sh_hdmi_edid_work_fn);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev); pm_runtime_get_sync(&pdev->dev);
/* Product and revision IDs are 0 in sh-mobile version */ /* Product and revision IDs are 0 in sh-mobile version */
dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n", dev_info(&pdev->dev, "Detected HDMI controller 0x%x:0x%x\n",
@ -1340,7 +1332,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
ecodec: ecodec:
free_irq(irq, hdmi); free_irq(irq, hdmi);
ereqirq: ereqirq:
pm_runtime_suspend(&pdev->dev); pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
iounmap(hdmi->base); iounmap(hdmi->base);
emap: emap:
@ -1377,7 +1369,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
free_irq(irq, hdmi); free_irq(irq, hdmi);
/* Wait for already scheduled work */ /* Wait for already scheduled work */
cancel_delayed_work_sync(&hdmi->edid_work); cancel_delayed_work_sync(&hdmi->edid_work);
pm_runtime_suspend(&pdev->dev); pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
clk_disable(hdmi->hdmi_clk); clk_disable(hdmi->hdmi_clk);
clk_put(hdmi->hdmi_clk); clk_put(hdmi->hdmi_clk);

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