Merge branch 'sh/stable-updates' into sh-latest
This commit is contained in:
commit
9dd056e9eb
|
@ -843,6 +843,7 @@ Provides counts of softirq handlers serviced since boot time, for each cpu.
|
|||
TASKLET: 0 0 0 290
|
||||
SCHED: 27035 26983 26971 26746
|
||||
HRTIMER: 0 0 0 0
|
||||
RCU: 1678 1769 2178 2250
|
||||
|
||||
|
||||
1.3 IDE devices in /proc/ide
|
||||
|
|
12
MAINTAINERS
12
MAINTAINERS
|
@ -2291,8 +2291,7 @@ F: drivers/scsi/eata_pio.*
|
|||
|
||||
EBTABLES
|
||||
M: Bart De Schuymer <bart.de.schuymer@pandora.be>
|
||||
L: ebtables-user@lists.sourceforge.net
|
||||
L: ebtables-devel@lists.sourceforge.net
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
W: http://ebtables.sourceforge.net/
|
||||
S: Maintained
|
||||
F: include/linux/netfilter_bridge/ebt_*.h
|
||||
|
@ -6463,7 +6462,7 @@ M: Jiri Kosina <jkosina@suse.cz>
|
|||
L: linux-usb@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
|
||||
S: Maintained
|
||||
F: Documentation/usb/hiddev.txt
|
||||
F: Documentation/hid/hiddev.txt
|
||||
F: drivers/hid/usbhid/
|
||||
|
||||
USB ISP116X DRIVER
|
||||
|
@ -7007,6 +7006,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
|
|||
S: Maintained
|
||||
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
|
||||
M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
|
||||
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
|
|
5
Makefile
5
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 0
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Sneaky Weasel
|
||||
|
||||
# *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
|
||||
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
|
||||
# clean it up only when building all modules
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <linux/io.h>
|
||||
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <mach/cpu.h>
|
||||
|
||||
|
@ -55,10 +57,12 @@ enum timer_location {
|
|||
#if defined(CONFIG_ARCH_QSD8X50)
|
||||
#define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
|
||||
#define MSM_DGT_SHIFT (0)
|
||||
#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \
|
||||
defined(CONFIG_ARCH_MSM8960)
|
||||
#elif defined(CONFIG_ARCH_MSM7X30)
|
||||
#define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
|
||||
#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
|
||||
#define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
|
||||
#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);
|
||||
|
||||
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)
|
||||
|
|
|
@ -4,14 +4,14 @@
|
|||
|
||||
# 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 += 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_32K_TIMER) += timer32k.o
|
||||
|
||||
# Power Management
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
|
||||
obj-$(CONFIG_PM) += pm.o sleep.o
|
||||
|
||||
# DSP
|
||||
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
|
||||
|
|
|
@ -56,9 +56,13 @@ static struct dev_power_domain default_power_domain = {
|
|||
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 = {
|
||||
.pwr_domain = &default_power_domain,
|
||||
.pwr_domain = OMAP1_PWR_DOMAIN,
|
||||
.con_ids = { "ick", "fck", NULL, },
|
||||
};
|
||||
|
||||
|
@ -72,4 +76,4 @@ static int __init omap1_pm_runtime_init(void)
|
|||
return 0;
|
||||
}
|
||||
core_initcall(omap1_pm_runtime_init);
|
||||
#endif /* CONFIG_PM_RUNTIME */
|
||||
|
||||
|
|
|
@ -84,7 +84,8 @@ static struct mtd_partition omap3pandora_nand_partitions[] = {
|
|||
|
||||
static struct omap_nand_platform_data pandora_nand_data = {
|
||||
.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,
|
||||
.nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
|
||||
};
|
||||
|
|
|
@ -189,7 +189,7 @@ static struct dentry *pm_dbg_dir;
|
|||
|
||||
static int pm_dbg_init_done;
|
||||
|
||||
static int __init pm_dbg_init(void);
|
||||
static int pm_dbg_init(void);
|
||||
|
||||
enum {
|
||||
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");
|
||||
|
||||
static int __init pm_dbg_init(void)
|
||||
static int pm_dbg_init(void)
|
||||
{
|
||||
int i;
|
||||
struct dentry *d;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/apm-emulation.h>
|
||||
|
|
|
@ -382,10 +382,8 @@ void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
|
|||
}
|
||||
|
||||
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_caps = MMC_CAP_NONREMOVABLE,
|
||||
.tmio_caps = MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
|
||||
.tmio_ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
|
||||
.set_pwr = ag5evm_sdhi1_set_pwr,
|
||||
};
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
* ------+--------------------+--------------------+-------
|
||||
* IRQ0 | ICR1A.IRQ0SA=0010 | SDHI2 card detect | Low
|
||||
* 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
|
||||
* IRQ9 | ICR2A.IRQ9SA=0010 | KEY(TCA6408) | Low
|
||||
* IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345) | High
|
||||
|
@ -165,10 +165,10 @@
|
|||
* USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
|
||||
* But don't select both drivers in same time.
|
||||
* 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.
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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[] = {
|
||||
[0] = {
|
||||
.name = "USBHS",
|
||||
.start = 0xE68B0000,
|
||||
.end = 0xE68B00E6 - 1,
|
||||
.name = "USBHS1",
|
||||
.start = 0xe68b0000,
|
||||
.end = 0xe68b00e6 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
|
@ -602,37 +716,14 @@ static struct platform_device usb1_host_device = {
|
|||
.resource = usb1_host_resources,
|
||||
};
|
||||
|
||||
/* USB1 (Function) */
|
||||
/* USBHS1 USB Function support via renesas_usbhs */
|
||||
|
||||
#define USB_PHY_MODE (1 << 4)
|
||||
#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
|
||||
#define USB_PHY_ON (1 << 1)
|
||||
#define USB_PHY_OFF (1 << 0)
|
||||
#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)
|
||||
{
|
||||
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);
|
||||
int ret;
|
||||
|
||||
irq_set_irq_type(priv->irq, IRQ_TYPE_LEVEL_HIGH);
|
||||
|
||||
/* clear interrupt status */
|
||||
__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);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request_irq err\n");
|
||||
|
@ -679,15 +768,12 @@ static void usbhs1_hardware_exit(struct platform_device *pdev)
|
|||
/* clear interrupt status */
|
||||
__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);
|
||||
|
||||
/* init phy */
|
||||
__raw_writew(0x8a0a, priv->usbcrcaddr);
|
||||
return USBHS_GADGET;
|
||||
}
|
||||
|
||||
static u32 usbhs1_pipe_cfg[] = {
|
||||
|
@ -710,16 +796,15 @@ static u32 usbhs1_pipe_cfg[] = {
|
|||
};
|
||||
|
||||
static struct usbhs_private usbhs1_private = {
|
||||
.irq = evt2irq(0x0300), /* IRQ8 */
|
||||
.usbphyaddr = 0xE60581E2, /* USBPHY1INTAP */
|
||||
.usbcrcaddr = 0xE6058130, /* USBCR4 */
|
||||
.usbphyaddr = 0xe60581e2, /* USBPHY1INTAP */
|
||||
.usbcrcaddr = 0xe6058130, /* USBCR4 */
|
||||
.info = {
|
||||
.platform_callback = {
|
||||
.hardware_init = usbhs1_hardware_init,
|
||||
.hardware_exit = usbhs1_hardware_exit,
|
||||
.phy_reset = usbhs1_phy_reset,
|
||||
.get_id = usbhs1_get_id,
|
||||
.get_vbus = usbhs1_get_vbus,
|
||||
.phy_reset = usbhs_phy_reset,
|
||||
.get_vbus = usbhs_get_vbus,
|
||||
},
|
||||
.driver_param = {
|
||||
.buswait_bwait = 4,
|
||||
|
@ -731,9 +816,9 @@ static struct usbhs_private usbhs1_private = {
|
|||
|
||||
static struct resource usbhs1_resources[] = {
|
||||
[0] = {
|
||||
.name = "USBHS",
|
||||
.start = 0xE68B0000,
|
||||
.end = 0xE68B00E6 - 1,
|
||||
.name = "USBHS1",
|
||||
.start = 0xe68b0000,
|
||||
.end = 0xe68b00e6 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
|
@ -752,7 +837,6 @@ static struct platform_device usbhs1_device = {
|
|||
.resource = usbhs1_resources,
|
||||
};
|
||||
|
||||
|
||||
/* LED */
|
||||
static struct gpio_led mackerel_leds[] = {
|
||||
{
|
||||
|
@ -1203,6 +1287,7 @@ static struct platform_device *mackerel_devices[] __initdata = {
|
|||
&nor_flash_device,
|
||||
&smc911x_device,
|
||||
&lcdc_device,
|
||||
&usbhs0_device,
|
||||
&usb1_host_device,
|
||||
&usbhs1_device,
|
||||
&leds_device,
|
||||
|
@ -1301,6 +1386,7 @@ static void __init mackerel_map_io(void)
|
|||
|
||||
#define GPIO_PORT9CR 0xE6051009
|
||||
#define GPIO_PORT10CR 0xE605100A
|
||||
#define GPIO_PORT167CR 0xE60520A7
|
||||
#define GPIO_PORT168CR 0xE60520A8
|
||||
#define SRCR4 0xe61580bc
|
||||
#define USCCR1 0xE6058144
|
||||
|
@ -1354,17 +1440,17 @@ static void __init mackerel_init(void)
|
|||
gpio_request(GPIO_PORT151, NULL); /* LCDDON */
|
||||
gpio_direction_output(GPIO_PORT151, 1);
|
||||
|
||||
/* USB enable */
|
||||
gpio_request(GPIO_FN_VBUS0_1, NULL);
|
||||
gpio_request(GPIO_FN_IDIN_1_18, NULL);
|
||||
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);
|
||||
/* USBHS0 */
|
||||
gpio_request(GPIO_FN_VBUS0_0, NULL);
|
||||
gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
|
||||
|
||||
/* setup USB phy */
|
||||
__raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
|
||||
/* USBHS1 */
|
||||
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) */
|
||||
gpio_request(GPIO_FN_FSIAIBT, NULL);
|
||||
|
|
|
@ -250,6 +250,11 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
|
|||
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 __iomem *gic_dist_base = __io(0xf0001000);
|
||||
|
@ -257,6 +262,7 @@ void __init sh73a0_init_irq(void)
|
|||
void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
|
||||
|
||||
gic_init(0, 29, gic_dist_base, gic_cpu_base);
|
||||
gic_arch_extn.irq_set_wake = sh73a0_set_wake;
|
||||
|
||||
register_intc_controller(&intcs_desc);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ static struct plat_sci_port scif0_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc00), evt2irq(0xc00),
|
||||
evt2irq(0xc00), evt2irq(0xc00) },
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ static struct plat_sci_port scif1_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc20), evt2irq(0xc20),
|
||||
evt2irq(0xc20), evt2irq(0xc20) },
|
||||
};
|
||||
|
@ -76,7 +76,7 @@ static struct plat_sci_port scif2_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc40), evt2irq(0xc40),
|
||||
evt2irq(0xc40), evt2irq(0xc40) },
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ static struct plat_sci_port scif3_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xc60), evt2irq(0xc60),
|
||||
evt2irq(0xc60), evt2irq(0xc60) },
|
||||
};
|
||||
|
@ -114,7 +114,7 @@ static struct plat_sci_port scif4_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xd20), evt2irq(0xd20),
|
||||
evt2irq(0xd20), evt2irq(0xd20) },
|
||||
};
|
||||
|
@ -133,7 +133,7 @@ static struct plat_sci_port scif5_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFA,
|
||||
.irqs = { evt2irq(0xd40), evt2irq(0xd40),
|
||||
evt2irq(0xd40), evt2irq(0xd40) },
|
||||
};
|
||||
|
@ -152,7 +152,7 @@ static struct plat_sci_port scif6_platform_data = {
|
|||
.flags = UPF_BOOT_AUTOCONF,
|
||||
.scscr = SCSCR_RE | SCSCR_TE,
|
||||
.scbrr_algo_id = SCBRR_ALGO_4,
|
||||
.type = PORT_SCIF,
|
||||
.type = PORT_SCIFB,
|
||||
.irqs = { evt2irq(0xd60), evt2irq(0xd60),
|
||||
evt2irq(0xd60), evt2irq(0xd60) },
|
||||
};
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <plat/omap_device.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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 = {
|
||||
.ops = {
|
||||
.runtime_suspend = _od_runtime_suspend,
|
||||
.runtime_idle = _od_runtime_idle,
|
||||
.runtime_resume = _od_runtime_resume,
|
||||
USE_PLATFORM_PM_SLEEP_OPS
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ CONFIG_TASK_XACCT=y
|
|||
CONFIG_TASK_IO_ACCOUNTING=y
|
||||
CONFIG_LOG_BUF_SHIFT=14
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
# CONFIG_SYSCTL_SYSCALL is not set
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_SLAB=y
|
||||
|
@ -39,8 +38,6 @@ CONFIG_IPV6=y
|
|||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
# CONFIG_FW_LOADER is not set
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_CONCAT=y
|
||||
CONFIG_MTD_PARTITIONS=y
|
||||
CONFIG_MTD_CHAR=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
CONFIG_MTD_M25P80=y
|
||||
|
@ -56,18 +53,19 @@ CONFIG_SH_ETH=y
|
|||
# CONFIG_KEYBOARD_ATKBD is not set
|
||||
# CONFIG_MOUSE_PS2 is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_SH_SCI=y
|
||||
CONFIG_SERIAL_SH_SCI_NR_UARTS=3
|
||||
CONFIG_SERIAL_SH_SCI_CONSOLE=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_SH=y
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_MFD_SH_MOBILE_SDHI=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_SH=y
|
||||
CONFIG_USB_OHCI_HCD=y
|
||||
CONFIG_USB_OHCI_SH=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHI=y
|
||||
|
|
|
@ -659,6 +659,54 @@ static struct platform_device spi0_device = {
|
|||
.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 = {
|
||||
&scif2_device,
|
||||
&scif3_device,
|
||||
|
@ -670,6 +718,8 @@ static struct platform_device *sh7757_devices[] __initdata = {
|
|||
&dma2_device,
|
||||
&dma3_device,
|
||||
&spi0_device,
|
||||
&usb_ehci_device,
|
||||
&usb_ohci_device,
|
||||
};
|
||||
|
||||
static int __init sh7757_devices_setup(void)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#define ARCH_DISCARD_MEMBLOCK
|
||||
|
||||
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_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_free_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
|
||||
|
|
|
@ -22,6 +22,8 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
|
|||
u64 product;
|
||||
#ifdef __i386__
|
||||
u32 tmp1, tmp2;
|
||||
#else
|
||||
ulong tmp;
|
||||
#endif
|
||||
|
||||
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) );
|
||||
#elif defined(__x86_64__)
|
||||
__asm__ (
|
||||
"mul %%rdx ; shrd $32,%%rdx,%%rax"
|
||||
: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
|
||||
"mul %[mul_frac] ; shrd $32, %[hi], %[lo]"
|
||||
: [lo]"=a"(product),
|
||||
[hi]"=d"(tmp)
|
||||
: "0"(delta),
|
||||
[mul_frac]"rm"((u64)mul_frac));
|
||||
#else
|
||||
#error implement me!
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -121,7 +121,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
|
|||
gva_t addr, u32 access)
|
||||
{
|
||||
pt_element_t pte;
|
||||
pt_element_t __user *ptep_user;
|
||||
pt_element_t __user *uninitialized_var(ptep_user);
|
||||
gfn_t table_gfn;
|
||||
unsigned index, pt_access, uninitialized_var(pte_access);
|
||||
gpa_t pte_gpa;
|
||||
|
|
|
@ -2047,7 +2047,8 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
|
|||
unsigned long cr0,
|
||||
struct kvm_vcpu *vcpu)
|
||||
{
|
||||
vmx_decache_cr3(vcpu);
|
||||
if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail))
|
||||
vmx_decache_cr3(vcpu);
|
||||
if (!(cr0 & X86_CR0_PG)) {
|
||||
/* From paging/starting to nonpaging */
|
||||
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <linux/range.h>
|
||||
|
||||
/* 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;
|
||||
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)
|
||||
continue;
|
||||
*sizep = ei_last - addr;
|
||||
while (check_with_memblock_reserved_size(&addr, sizep, align))
|
||||
while (memblock_x86_check_reserved_size(&addr, sizep, align))
|
||||
;
|
||||
|
||||
if (*sizep)
|
||||
|
|
|
@ -310,14 +310,31 @@ void __init efi_reserve_boot_services(void)
|
|||
|
||||
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
|
||||
efi_memory_desc_t *md = p;
|
||||
unsigned long long start = md->phys_addr;
|
||||
unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
u64 start = md->phys_addr;
|
||||
u64 size = md->num_pages << EFI_PAGE_SHIFT;
|
||||
|
||||
if (md->type != EFI_BOOT_SERVICES_CODE &&
|
||||
md->type != EFI_BOOT_SERVICES_DATA)
|
||||
continue;
|
||||
|
||||
memblock_x86_reserve_range(start, start + size, "EFI Boot");
|
||||
/* Only reserve where possible:
|
||||
* - 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)
|
||||
continue;
|
||||
|
||||
/* Could not reserve boot area */
|
||||
if (!size)
|
||||
continue;
|
||||
|
||||
free_bootmem_late(start, size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1033,6 +1033,13 @@ static void xen_machine_halt(void)
|
|||
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)
|
||||
{
|
||||
xen_reboot(SHUTDOWN_crash);
|
||||
|
@ -1058,7 +1065,7 @@ int xen_panic_handler_init(void)
|
|||
static const struct machine_ops xen_machine_ops __initconst = {
|
||||
.restart = xen_restart,
|
||||
.halt = xen_machine_halt,
|
||||
.power_off = xen_machine_halt,
|
||||
.power_off = xen_machine_power_off,
|
||||
.shutdown = xen_machine_halt,
|
||||
.crash_shutdown = xen_crash_shutdown,
|
||||
.emergency_restart = xen_emergency_restart,
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/init.h>
|
||||
#include <asm/pat.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#include <asm/xen/hypercall.h>
|
||||
#include <asm/xen/hypervisor.h>
|
||||
|
@ -1231,7 +1232,7 @@ static void xen_flush_tlb_others(const struct cpumask *cpus,
|
|||
{
|
||||
struct {
|
||||
struct mmuext_op op;
|
||||
DECLARE_BITMAP(mask, NR_CPUS);
|
||||
DECLARE_BITMAP(mask, num_processors);
|
||||
} *args;
|
||||
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++) {
|
||||
pte_t pte;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (pfn > max_pfn_mapped)
|
||||
max_pfn_mapped = pfn;
|
||||
#endif
|
||||
|
||||
if (!pte_none(pte_page[pteidx]))
|
||||
continue;
|
||||
|
||||
|
@ -1766,7 +1772,9 @@ pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
|
|||
initial_kernel_pmd =
|
||||
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);
|
||||
memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
|
||||
|
|
|
@ -227,11 +227,7 @@ char * __init xen_memory_setup(void)
|
|||
|
||||
memcpy(map_raw, map, sizeof(map));
|
||||
e820.nr_map = 0;
|
||||
#ifdef CONFIG_X86_32
|
||||
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++) {
|
||||
unsigned long long end;
|
||||
|
||||
|
@ -266,6 +262,12 @@ char * __init xen_memory_setup(void)
|
|||
if (map[i].size > 0)
|
||||
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
|
||||
|
|
|
@ -205,11 +205,18 @@ static void __init xen_smp_prepare_boot_cpu(void)
|
|||
static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
unsigned cpu;
|
||||
unsigned int i;
|
||||
|
||||
xen_init_lock_cpu(0);
|
||||
|
||||
smp_store_cpu_info(0);
|
||||
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);
|
||||
|
||||
if (xen_smp_intr_init(0))
|
||||
|
|
|
@ -64,6 +64,8 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file,
|
|||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->btmrvl_dev.hscfgcmd = result;
|
||||
|
||||
|
@ -108,6 +110,8 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
|
|||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->btmrvl_dev.psmode = result;
|
||||
|
||||
|
@ -147,6 +151,8 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
|
|||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->btmrvl_dev.pscmd = result;
|
||||
|
||||
|
@ -191,6 +197,8 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
|
|||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 16, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->btmrvl_dev.hscmd = result;
|
||||
if (priv->btmrvl_dev.hscmd) {
|
||||
|
@ -272,6 +282,8 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
|
|||
return -EFAULT;
|
||||
|
||||
ret = strict_strtol(buf, 10, &result);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->btmrvl_dev.hsmode = result;
|
||||
|
||||
|
|
|
@ -298,11 +298,13 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
|
|||
old_index = stat->last_index;
|
||||
new_index = freq_table_get_index(stat, freq->new);
|
||||
|
||||
cpufreq_stats_update(freq->cpu);
|
||||
if (old_index == new_index)
|
||||
/* We can't do stat->time_in_state[-1]= .. */
|
||||
if (old_index == -1 || new_index == -1)
|
||||
return 0;
|
||||
|
||||
if (old_index == -1 || new_index == -1)
|
||||
cpufreq_stats_update(freq->cpu);
|
||||
|
||||
if (old_index == new_index)
|
||||
return 0;
|
||||
|
||||
spin_lock(&cpufreq_stats_lock);
|
||||
|
|
|
@ -1079,6 +1079,9 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
|
|||
}
|
||||
|
||||
res = transition_fid_vid(data, fid, vid);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
freqs.new = find_khz_freq_from_fid(data->currfid);
|
||||
|
||||
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 */
|
||||
pstate = index & HW_PSTATE_MASK;
|
||||
if (pstate > data->max_hw_pstate)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
|
||||
freqs.old = find_khz_freq_from_pstate(data->powernow_table,
|
||||
data->currpstate);
|
||||
freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
|
||||
|
|
|
@ -469,8 +469,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
|
|||
+ OMAP24XX_GPIO_CLEARWKUENA);
|
||||
}
|
||||
}
|
||||
/* This part needs to be executed always for OMAP34xx */
|
||||
if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) {
|
||||
/* This part needs to be executed always for OMAP{34xx, 44xx} */
|
||||
if (cpu_is_omap34xx() || cpu_is_omap44xx() ||
|
||||
(bank->non_wakeup_gpios & gpio_bit)) {
|
||||
/*
|
||||
* Log the edge gpio and manually trigger the IRQ
|
||||
* after resume if the input level changes
|
||||
|
|
|
@ -184,9 +184,9 @@ drm_edid_block_valid(u8 *raw_edid)
|
|||
|
||||
bad:
|
||||
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);
|
||||
printk("\n");
|
||||
printk(KERN_ERR "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,6 +258,17 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
|
|||
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 *
|
||||
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;
|
||||
if (drm_edid_block_valid(block))
|
||||
break;
|
||||
if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
|
||||
connector->null_edid_counter++;
|
||||
goto carp;
|
||||
}
|
||||
}
|
||||
if (i == 4)
|
||||
goto carp;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* IN THE SOFTWARE.
|
||||
*/
|
||||
#include <linux/compat.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm_core.h"
|
||||
|
@ -253,10 +254,10 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd,
|
|||
return -EFAULT;
|
||||
|
||||
m32.handle = (unsigned long)handle;
|
||||
if (m32.handle != (unsigned long)handle && printk_ratelimit())
|
||||
printk(KERN_ERR "compat_drm_addmap truncated handle"
|
||||
" %p for type %d offset %x\n",
|
||||
handle, m32.type, m32.offset);
|
||||
if (m32.handle != (unsigned long)handle)
|
||||
printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle"
|
||||
" %p for type %d offset %x\n",
|
||||
handle, m32.type, m32.offset);
|
||||
|
||||
if (copy_to_user(argp, &m32, sizeof(m32)))
|
||||
return -EFAULT;
|
||||
|
|
|
@ -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) ||
|
||||
(p->busnum & 0xff) != dev->pdev->bus->number ||
|
||||
|
@ -292,6 +292,7 @@ static struct drm_bus drm_pci_bus = {
|
|||
.get_name = drm_pci_get_name,
|
||||
.set_busid = drm_pci_set_busid,
|
||||
.set_unique = drm_pci_set_unique,
|
||||
.irq_by_busid = drm_pci_irq_by_busid,
|
||||
.agp_init = drm_pci_agp_init,
|
||||
};
|
||||
|
||||
|
|
|
@ -1740,6 +1740,16 @@ void ironlake_irq_preinstall(struct drm_device *dev)
|
|||
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
|
||||
|
||||
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 */
|
||||
|
||||
|
|
|
@ -401,8 +401,7 @@ int intel_setup_gmbus(struct drm_device *dev)
|
|||
bus->reg0 = i | GMBUS_RATE_100KHZ;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
intel_i2c_reset(dev_priv->dev);
|
||||
|
|
|
@ -262,7 +262,6 @@ static bool nouveau_dsm_detect(void)
|
|||
vga_count++;
|
||||
|
||||
retval = nouveau_dsm_pci_probe(pdev);
|
||||
printk("ret val is %d\n", retval);
|
||||
if (retval & NOUVEAU_DSM_HAS_MUX)
|
||||
has_dsm |= 1;
|
||||
if (retval & NOUVEAU_DSM_HAS_OPT)
|
||||
|
|
|
@ -339,11 +339,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
int ret;
|
||||
|
||||
if (dev_priv->chipset < 0x84) {
|
||||
ret = RING_SPACE(chan, 3);
|
||||
ret = RING_SPACE(chan, 4);
|
||||
if (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, 1);
|
||||
} else
|
||||
|
@ -351,10 +352,12 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
|
|||
struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
|
||||
u64 offset = vma->offset + sema->mem->start;
|
||||
|
||||
ret = RING_SPACE(chan, 5);
|
||||
ret = RING_SPACE(chan, 7);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING (chan, chan->vram_handle);
|
||||
BEGIN_RING(chan, NvSubSw, 0x0010, 4);
|
||||
OUT_RING (chan, upper_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;
|
||||
|
||||
if (dev_priv->chipset < 0x84) {
|
||||
ret = RING_SPACE(chan, 4);
|
||||
ret = RING_SPACE(chan, 5);
|
||||
if (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);
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 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;
|
||||
u64 offset = vma->offset + sema->mem->start;
|
||||
|
||||
ret = RING_SPACE(chan, 5);
|
||||
ret = RING_SPACE(chan, 7);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
|
||||
OUT_RING (chan, chan->vram_handle);
|
||||
BEGIN_RING(chan, NvSubSw, 0x0010, 4);
|
||||
OUT_RING (chan, upper_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;
|
||||
int ret;
|
||||
|
||||
if (dev_priv->card_type >= NV_C0)
|
||||
goto out_initialised;
|
||||
if (dev_priv->card_type < NV_C0) {
|
||||
/* Create an NV_SW object for various sync purposes */
|
||||
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Create an NV_SW object for various sync purposes */
|
||||
ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* we leave subchannel empty for nvc0 */
|
||||
ret = RING_SPACE(chan, 2);
|
||||
if (ret)
|
||||
return ret;
|
||||
BEGIN_RING(chan, NvSubSw, 0, 1);
|
||||
OUT_RING(chan, NvSw);
|
||||
BEGIN_RING(chan, NvSubSw, 0, 1);
|
||||
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) {
|
||||
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);
|
||||
if (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);
|
||||
spin_lock_init(&chan->fence.lock);
|
||||
atomic_set(&chan->fence.last_sequence_irq, 0);
|
||||
|
|
|
@ -182,6 +182,11 @@ nouveau_perf_init(struct drm_device *dev)
|
|||
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;
|
||||
for (i = 0; i < entries; i++) {
|
||||
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
|
||||
|
|
|
@ -881,8 +881,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
|
|||
|
||||
#ifdef __BIG_ENDIAN
|
||||
/* Put the card in BE mode if it's not */
|
||||
if (nv_rd32(dev, NV03_PMC_BOOT_1))
|
||||
nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
|
||||
if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
|
||||
nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
|
||||
|
||||
DRM_MEMORYBARRIER();
|
||||
#endif
|
||||
|
|
|
@ -409,7 +409,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
|||
struct nouveau_channel *evo = dispc->sync;
|
||||
int ret;
|
||||
|
||||
ret = RING_SPACE(evo, 24);
|
||||
ret = RING_SPACE(evo, chan ? 25 : 27);
|
||||
if (unlikely(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 */
|
||||
BEGIN_RING(evo, 0, 0x0100, 1);
|
||||
OUT_RING (evo, 0xfffe0000);
|
||||
BEGIN_RING(evo, 0, 0x0084, 5);
|
||||
OUT_RING (evo, chan ? 0x00000100 : 0x00000010);
|
||||
if (chan) {
|
||||
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, 0xf00d0000 | dispc->sem.value);
|
||||
OUT_RING (evo, 0x74b1e000);
|
||||
|
|
|
@ -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 0x11
|
||||
#define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12
|
||||
#define EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP 0x14
|
||||
|
||||
// ucConfig
|
||||
#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03
|
||||
|
|
|
@ -671,6 +671,13 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
|||
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,
|
||||
index, (uint32_t *)&args);
|
||||
adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
|
||||
|
|
|
@ -88,7 +88,8 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
|
|||
/* get temperature in millidegrees */
|
||||
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) {
|
||||
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;
|
||||
|
||||
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)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = 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)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_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)
|
||||
{
|
||||
u32 wptr = evergreen_get_ih_wptr(rdev);
|
||||
u32 rptr = rdev->ih.rptr;
|
||||
u32 wptr;
|
||||
u32 rptr;
|
||||
u32 src_id, src_data;
|
||||
u32 ring_index;
|
||||
unsigned long flags;
|
||||
bool queue_hotplug = false;
|
||||
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
if (!rdev->ih.enabled)
|
||||
if (!rdev->ih.enabled || rdev->shutdown)
|
||||
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) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (rdev->shutdown) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
restart_ih:
|
||||
/* display interrupts */
|
||||
evergreen_irq_ack(rdev);
|
||||
|
|
|
@ -590,6 +590,9 @@ void r600_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].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) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
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)
|
||||
{
|
||||
u32 wptr = r600_get_ih_wptr(rdev);
|
||||
u32 rptr = rdev->ih.rptr;
|
||||
u32 wptr;
|
||||
u32 rptr;
|
||||
u32 src_id, src_data;
|
||||
u32 ring_index;
|
||||
unsigned long flags;
|
||||
bool queue_hotplug = false;
|
||||
|
||||
DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
|
||||
if (!rdev->ih.enabled)
|
||||
if (!rdev->ih.enabled || rdev->shutdown)
|
||||
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);
|
||||
|
||||
if (rptr == wptr) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (rdev->shutdown) {
|
||||
spin_unlock_irqrestore(&rdev->ih.lock, flags);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
restart_ih:
|
||||
/* display interrupts */
|
||||
|
|
|
@ -938,6 +938,13 @@ static struct radeon_asic cayman_asic = {
|
|||
int radeon_asic_init(struct radeon_device *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) {
|
||||
case CHIP_R100:
|
||||
case CHIP_RV100:
|
||||
|
@ -1017,6 +1024,11 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
case CHIP_JUNIPER:
|
||||
case CHIP_CYPRESS:
|
||||
case CHIP_HEMLOCK:
|
||||
/* set num crtcs */
|
||||
if (rdev->family == CHIP_CEDAR)
|
||||
rdev->num_crtc = 4;
|
||||
else
|
||||
rdev->num_crtc = 6;
|
||||
rdev->asic = &evergreen_asic;
|
||||
break;
|
||||
case CHIP_PALM:
|
||||
|
@ -1027,10 +1039,17 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
case CHIP_BARTS:
|
||||
case CHIP_TURKS:
|
||||
case CHIP_CAICOS:
|
||||
/* set num crtcs */
|
||||
if (rdev->family == CHIP_CAICOS)
|
||||
rdev->num_crtc = 4;
|
||||
else
|
||||
rdev->num_crtc = 6;
|
||||
rdev->asic = &btc_asic;
|
||||
break;
|
||||
case CHIP_CAYMAN:
|
||||
rdev->asic = &cayman_asic;
|
||||
/* set num crtcs */
|
||||
rdev->num_crtc = 6;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: not supported yet */
|
||||
|
@ -1042,18 +1061,6 @@ int radeon_asic_init(struct radeon_device *rdev)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
return;
|
||||
|
||||
/* 0xff01 is a flag rather then an actual voltage */
|
||||
if (voltage_level == 0xff01)
|
||||
return;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
args.v1.ucVoltageType = voltage_type;
|
||||
|
|
|
@ -1553,9 +1553,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
|
|||
(rdev->pdev->subsystem_device == 0x4a48)) {
|
||||
/* Mac X800 */
|
||||
rdev->mode_info.connector_table = CT_MAC_X800;
|
||||
} else if (of_machine_is_compatible("PowerMac7,2") ||
|
||||
of_machine_is_compatible("PowerMac7,3")) {
|
||||
/* Mac G5 9600 */
|
||||
} else if ((of_machine_is_compatible("PowerMac7,2") ||
|
||||
of_machine_is_compatible("PowerMac7,3")) &&
|
||||
(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;
|
||||
} else
|
||||
#endif /* CONFIG_PPC_PMAC */
|
||||
|
|
|
@ -44,6 +44,8 @@ extern void
|
|||
radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
|
||||
struct drm_connector *drm_connector);
|
||||
|
||||
bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
|
||||
|
||||
void radeon_connector_hotplug(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
|
@ -836,6 +838,13 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
if (!radeon_connector->edid) {
|
||||
DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
|
||||
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 {
|
||||
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_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
|
||||
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
||||
int ret;
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
struct drm_encoder *encoder;
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
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);
|
||||
|
||||
if (ret > 0) {
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (encoder) {
|
||||
radeon_fixup_lvds_native_mode(encoder, connector);
|
||||
/* add scaled modes */
|
||||
|
@ -1102,8 +1111,14 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
|
|||
/* add scaled modes */
|
||||
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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1187,14 +1202,15 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
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) {
|
||||
kfree(radeon_connector->edid);
|
||||
radeon_connector->edid = NULL;
|
||||
}
|
||||
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
|
||||
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
|
||||
if (encoder) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
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,
|
||||
ATOM_TRANSMITTER_ACTION_POWER_OFF);
|
||||
} 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);
|
||||
if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||
ret = connector_status_connected;
|
||||
|
@ -1228,6 +1249,16 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||
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);
|
||||
|
@ -1242,7 +1273,8 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
|
|||
|
||||
/* 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);
|
||||
|
||||
if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
|
||||
|
@ -1252,7 +1284,7 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
|
|||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
|
||||
|
||||
/* AVIVO hardware supports downscaling modes larger than the panel
|
||||
/* AVIVO hardware supports downscaling modes larger than the panel
|
||||
* to the panel size, but I'm not sure this is desirable.
|
||||
*/
|
||||
if ((mode->hdisplay > native_mode->hdisplay) ||
|
||||
|
@ -1401,6 +1433,10 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
default:
|
||||
connector->interlace_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;
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
|
@ -1422,6 +1458,12 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
connector->doublescan_allowed = true;
|
||||
else
|
||||
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;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
case DRM_MODE_CONNECTOR_eDP:
|
||||
|
|
|
@ -215,6 +215,8 @@ int radeon_wb_init(struct radeon_device *rdev)
|
|||
return r;
|
||||
}
|
||||
|
||||
/* clear wb memory */
|
||||
memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE);
|
||||
/* disable event_write fences */
|
||||
rdev->wb.use_event = false;
|
||||
/* disabled via module param */
|
||||
|
|
|
@ -367,7 +367,8 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder,
|
|||
}
|
||||
|
||||
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);
|
||||
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))
|
||||
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);
|
||||
if (!connector) {
|
||||
switch (radeon_encoder->encoder_id) {
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
|
||||
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* if we don't have an active device yet, just use one of
|
||||
* the connectors tied to the encoder.
|
||||
*/
|
||||
if (!connector)
|
||||
connector = radeon_get_connector_for_encoder_init(encoder);
|
||||
radeon_connector = to_radeon_connector(connector);
|
||||
|
||||
switch (connector->connector_type) {
|
||||
|
@ -1094,9 +1090,10 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
|
|||
break;
|
||||
}
|
||||
|
||||
if (is_dp)
|
||||
if (is_dp) {
|
||||
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)
|
||||
args.v2.acConfig.fCoherentMode = 1;
|
||||
if (radeon_encoder->pixel_clock > 165000)
|
||||
|
@ -1435,7 +1432,11 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||
if (is_dig) {
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
|
||||
/* 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);
|
||||
if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) {
|
||||
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) {
|
||||
int action;
|
||||
|
||||
switch (mode) {
|
||||
case DRM_MODE_DPMS_ON:
|
||||
default:
|
||||
if (ASIC_IS_DCE41(rdev))
|
||||
action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT;
|
||||
else
|
||||
action = ATOM_ENABLE;
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
|
||||
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;
|
||||
case DRM_MODE_DPMS_STANDBY:
|
||||
case DRM_MODE_DPMS_SUSPEND:
|
||||
case DRM_MODE_DPMS_OFF:
|
||||
if (ASIC_IS_DCE41(rdev))
|
||||
action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT;
|
||||
else
|
||||
action = ATOM_DISABLE;
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
|
||||
atombios_external_encoder_setup(encoder, ext_encoder,
|
||||
EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
|
||||
} else
|
||||
atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
|
||||
break;
|
||||
}
|
||||
atombios_external_encoder_setup(encoder, ext_encoder, action);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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,
|
||||
.commit = radeon_atom_encoder_commit,
|
||||
.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 = {
|
||||
|
|
|
@ -40,6 +40,35 @@
|
|||
#include "radeon.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)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
|
@ -50,12 +79,12 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
|
|||
return 0;
|
||||
}
|
||||
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
|
||||
* away
|
||||
*/
|
||||
WREG32(rdev->fence_drv.scratch_reg, fence->seq);
|
||||
} else
|
||||
radeon_fence_write(rdev, fence->seq);
|
||||
else
|
||||
radeon_fence_ring_emit(rdev, fence);
|
||||
|
||||
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;
|
||||
unsigned long cjiffies;
|
||||
|
||||
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);
|
||||
seq = radeon_fence_read(rdev);
|
||||
if (seq != rdev->fence_drv.last_seq) {
|
||||
rdev->fence_drv.last_seq = seq;
|
||||
rdev->fence_drv.last_jiffies = jiffies;
|
||||
|
@ -251,7 +272,7 @@ retry:
|
|||
r = radeon_gpu_reset(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
WREG32(rdev->fence_drv.scratch_reg, fence->seq);
|
||||
radeon_fence_write(rdev, fence->seq);
|
||||
rdev->gpu_lockup = false;
|
||||
}
|
||||
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);
|
||||
return r;
|
||||
}
|
||||
WREG32(rdev->fence_drv.scratch_reg, 0);
|
||||
radeon_fence_write(rdev, 0);
|
||||
atomic_set(&rdev->fence_drv.seq, 0);
|
||||
INIT_LIST_HEAD(&rdev->fence_drv.created);
|
||||
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;
|
||||
|
||||
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)) {
|
||||
fence = list_entry(rdev->fence_drv.emited.prev,
|
||||
struct radeon_fence, list);
|
||||
|
|
|
@ -483,6 +483,8 @@ extern void radeon_atom_encoder_init(struct radeon_device *rdev);
|
|||
extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
|
||||
int action, uint8_t lane_num,
|
||||
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,
|
||||
u8 write_byte, u8 *read_byte);
|
||||
|
||||
|
|
|
@ -105,6 +105,9 @@ void rv770_pm_misc(struct radeon_device *rdev)
|
|||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].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) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
|
|
|
@ -305,6 +305,7 @@ config HID_MULTITOUCH
|
|||
- 3M PCT touch screens
|
||||
- ActionStar dual touch panels
|
||||
- Cando dual touch panels
|
||||
- Chunghwa panels
|
||||
- CVTouch panels
|
||||
- Cypress TrueTouch panels
|
||||
- Elo TouchSystems IntelliTouch Plus panels
|
||||
|
|
|
@ -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_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_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
|
||||
{ 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_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
|
||||
|
|
|
@ -173,6 +173,9 @@
|
|||
#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
|
||||
#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_CMEDIA 0x0d8c
|
||||
|
@ -622,6 +625,7 @@
|
|||
#define USB_VENDOR_ID_UCLOGIC 0x5543
|
||||
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
|
||||
#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_WP5540U 0x0004
|
||||
#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
|
||||
|
|
|
@ -501,17 +501,9 @@ static int magicmouse_probe(struct hid_device *hdev,
|
|||
}
|
||||
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),
|
||||
HID_FEATURE_REPORT);
|
||||
if (ret != -EIO) {
|
||||
if (ret != sizeof(feature)) {
|
||||
hid_err(hdev, "unable to request touch data (%d)\n", ret);
|
||||
goto err_stop_hw;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ struct mt_device {
|
|||
struct mt_class *mtclass; /* our mt device class */
|
||||
unsigned last_field_index; /* last field index of the report */
|
||||
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 */
|
||||
__u8 num_received; /* how many contacts we received */
|
||||
__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);
|
||||
/* touchscreen emulation */
|
||||
set_abs(hi->input, ABS_X, field, cls->sn_move);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_GD_Y:
|
||||
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);
|
||||
/* touchscreen emulation */
|
||||
set_abs(hi->input, ABS_Y, field, cls->sn_move);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -246,31 +251,40 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
|||
case HID_UP_DIGITIZER:
|
||||
switch (usage->hid) {
|
||||
case HID_DG_INRANGE:
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_CONFIDENCE:
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_TIPSWITCH:
|
||||
hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
|
||||
input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_CONTACTID:
|
||||
input_mt_init_slots(hi->input, td->maxcontacts);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
td->last_mt_collection = usage->collection_index;
|
||||
return 1;
|
||||
case HID_DG_WIDTH:
|
||||
hid_map_usage(hi, usage, bit, max,
|
||||
EV_ABS, ABS_MT_TOUCH_MAJOR);
|
||||
set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
|
||||
cls->sn_width);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_HEIGHT:
|
||||
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);
|
||||
input_set_abs_params(hi->input,
|
||||
ABS_MT_ORIENTATION, 0, 1, 0, 0);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_TIPPRESSURE:
|
||||
if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
|
||||
|
@ -292,16 +308,20 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
|
|||
/* touchscreen emulation */
|
||||
set_abs(hi->input, ABS_PRESSURE, field,
|
||||
cls->sn_pressure);
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index) {
|
||||
td->last_slot_field = usage->hid;
|
||||
td->last_field_index = field->index;
|
||||
}
|
||||
return 1;
|
||||
case HID_DG_CONTACTCOUNT:
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index)
|
||||
td->last_field_index = field->index;
|
||||
return 1;
|
||||
case HID_DG_CONTACTMAX:
|
||||
/* we don't set td->last_slot_field as contactcount and
|
||||
* contact max are global to the report */
|
||||
td->last_field_index = field->index;
|
||||
if (td->last_mt_collection == usage->collection_index)
|
||||
td->last_field_index = field->index;
|
||||
return -1;
|
||||
}
|
||||
/* let hid-input decide for the others */
|
||||
|
@ -516,6 +536,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
}
|
||||
td->mtclass = mtclass;
|
||||
td->inputmode = -1;
|
||||
td->last_mt_collection = -1;
|
||||
hid_set_drvdata(hdev, td);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
|
@ -593,6 +614,11 @@ static const struct hid_device_id mt_devices[] = {
|
|||
HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
|
||||
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 */
|
||||
{ .driver_data = MT_CLS_DEFAULT,
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
|
||||
|
|
|
@ -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_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_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_WP8060U, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
|
||||
|
|
|
@ -248,12 +248,15 @@ static int hiddev_release(struct inode * inode, struct file * file)
|
|||
usbhid_close(list->hiddev->hid);
|
||||
usbhid_put_power(list->hiddev->hid);
|
||||
} else {
|
||||
mutex_unlock(&list->hiddev->existancelock);
|
||||
kfree(list->hiddev);
|
||||
kfree(list);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(list);
|
||||
mutex_unlock(&list->hiddev->existancelock);
|
||||
kfree(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -923,10 +926,11 @@ void hiddev_disconnect(struct hid_device *hid)
|
|||
usb_deregister_dev(usbhid->intf, &hiddev_class);
|
||||
|
||||
if (hiddev->open) {
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
usbhid_close(hiddev->hid);
|
||||
wake_up_interruptible(&hiddev->wait);
|
||||
} else {
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
kfree(hiddev);
|
||||
}
|
||||
mutex_unlock(&hiddev->existancelock);
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ static struct device_attribute atk_name_attr =
|
|||
static void atk_init_attribute(struct device_attribute *attr, char *name,
|
||||
sysfs_show_func show)
|
||||
{
|
||||
sysfs_attr_init(&attr->attr);
|
||||
attr->attr.name = name;
|
||||
attr->attr.mode = 0444;
|
||||
attr->show = show;
|
||||
|
@ -1188,19 +1189,15 @@ static int atk_create_files(struct atk_data *data)
|
|||
int err;
|
||||
|
||||
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);
|
||||
if (err)
|
||||
return err;
|
||||
sysfs_attr_init(&s->label_attr.attr);
|
||||
err = device_create_file(data->hwmon_dev, &s->label_attr);
|
||||
if (err)
|
||||
return err;
|
||||
sysfs_attr_init(&s->limit1_attr.attr);
|
||||
err = device_create_file(data->hwmon_dev, &s->limit1_attr);
|
||||
if (err)
|
||||
return err;
|
||||
sysfs_attr_init(&s->limit2_attr.attr);
|
||||
err = device_create_file(data->hwmon_dev, &s->limit2_attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -97,9 +97,7 @@ struct platform_data {
|
|||
struct pdev_entry {
|
||||
struct list_head list;
|
||||
struct platform_device *pdev;
|
||||
unsigned int cpu;
|
||||
u16 phys_proc_id;
|
||||
u16 cpu_core_id;
|
||||
};
|
||||
|
||||
static LIST_HEAD(pdev_list);
|
||||
|
@ -653,9 +651,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
|
|||
}
|
||||
|
||||
pdev_entry->pdev = pdev;
|
||||
pdev_entry->cpu = 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);
|
||||
mutex_unlock(&pdev_list_mutex);
|
||||
|
|
|
@ -947,6 +947,7 @@ static int aem_register_sensors(struct aem_data *data,
|
|||
|
||||
/* Set up read-only sensors */
|
||||
while (ro->label) {
|
||||
sysfs_attr_init(&sensors->dev_attr.attr);
|
||||
sensors->dev_attr.attr.name = ro->label;
|
||||
sensors->dev_attr.attr.mode = S_IRUGO;
|
||||
sensors->dev_attr.show = ro->show;
|
||||
|
@ -963,6 +964,7 @@ static int aem_register_sensors(struct aem_data *data,
|
|||
|
||||
/* Set up read-write sensors */
|
||||
while (rw->label) {
|
||||
sysfs_attr_init(&sensors->dev_attr.attr);
|
||||
sensors->dev_attr.attr.name = rw->label;
|
||||
sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
|
||||
sensors->dev_attr.show = rw->show;
|
||||
|
|
|
@ -358,6 +358,7 @@ static int create_sensor(struct ibmpex_bmc_data *data, int type,
|
|||
else if (type == POWER_SENSOR)
|
||||
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.mode = S_IRUGO;
|
||||
data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor;
|
||||
|
|
|
@ -232,6 +232,7 @@ static int s3c_hwmon_create_attr(struct device *dev,
|
|||
|
||||
attr = &attrs->in;
|
||||
attr->index = channel;
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.name = attrs->in_name;
|
||||
attr->dev_attr.attr.mode = S_IRUGO;
|
||||
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->index = channel;
|
||||
sysfs_attr_init(&attr->dev_attr.attr);
|
||||
attr->dev_attr.attr.name = attrs->label_name;
|
||||
attr->dev_attr.attr.mode = S_IRUGO;
|
||||
attr->dev_attr.show = s3c_hwmon_label_show;
|
||||
|
|
|
@ -111,7 +111,8 @@ static void evdev_event(struct input_handle *handle,
|
|||
|
||||
rcu_read_unlock();
|
||||
|
||||
wake_up_interruptible(&evdev->wait);
|
||||
if (type == EV_SYN && code == SYN_REPORT)
|
||||
wake_up_interruptible(&evdev->wait);
|
||||
}
|
||||
|
||||
static int evdev_fasync(int fd, struct file *file, int on)
|
||||
|
|
|
@ -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)) {
|
||||
mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
|
||||
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)) {
|
||||
mt_slots = 2;
|
||||
} else {
|
||||
|
|
|
@ -209,6 +209,7 @@ static void omap_kp_tasklet(unsigned long data)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
input_sync(omap_kp_data->input);
|
||||
memcpy(keypad_state, new_state, sizeof(keypad_state));
|
||||
|
||||
if (key_down) {
|
||||
|
|
|
@ -32,7 +32,7 @@ static const struct {
|
|||
[SH_KEYSC_MODE_3] = { 2, 4, 7 },
|
||||
[SH_KEYSC_MODE_4] = { 3, 6, 6 },
|
||||
[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 {
|
||||
|
|
|
@ -187,7 +187,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
|
|||
if (size == 0)
|
||||
size = xres ? : 1;
|
||||
|
||||
clamp(value, min, max);
|
||||
value = clamp(value, min, max);
|
||||
|
||||
mousedev->packet.x = ((value - min) * xres) / size;
|
||||
mousedev->packet.abs_event = 1;
|
||||
|
@ -201,7 +201,7 @@ static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev,
|
|||
if (size == 0)
|
||||
size = yres ? : 1;
|
||||
|
||||
clamp(value, min, max);
|
||||
value = clamp(value, min, max);
|
||||
|
||||
mousedev->packet.y = yres - ((value - min) * yres) / size;
|
||||
mousedev->packet.abs_event = 1;
|
||||
|
|
|
@ -156,8 +156,10 @@ static int if_open(struct tty_struct *tty, struct file *filp)
|
|||
if (!cs || !try_module_get(cs->driver->owner))
|
||||
return -ENODEV;
|
||||
|
||||
if (mutex_lock_interruptible(&cs->mutex))
|
||||
if (mutex_lock_interruptible(&cs->mutex)) {
|
||||
module_put(cs->driver->owner);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
tty->driver_data = cs;
|
||||
|
||||
++cs->open_count;
|
||||
|
|
|
@ -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) {
|
||||
dev_kfree_skb(skb);
|
||||
kfree(queued_msg);
|
||||
}
|
||||
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -412,7 +412,7 @@ el2_open(struct net_device *dev)
|
|||
outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
|
||||
outb_p(0x00, E33G_IDCFR);
|
||||
msleep(1);
|
||||
free_irq(*irqp, el2_probe_interrupt);
|
||||
free_irq(*irqp, &seen);
|
||||
if (!seen)
|
||||
continue;
|
||||
|
||||
|
@ -422,6 +422,7 @@ el2_open(struct net_device *dev)
|
|||
continue;
|
||||
if (retval < 0)
|
||||
goto err_disable;
|
||||
break;
|
||||
} while (*++irqp);
|
||||
|
||||
if (*irqp == 0) {
|
||||
|
|
|
@ -52,13 +52,13 @@ MODULE_DESCRIPTION(DRV_DESC);
|
|||
MODULE_ALIAS("platform:bfin_mac");
|
||||
|
||||
#if defined(CONFIG_BFIN_MAC_USE_L1)
|
||||
# define bfin_mac_alloc(dma_handle, size) l1_data_sram_zalloc(size)
|
||||
# define bfin_mac_free(dma_handle, ptr) l1_data_sram_free(ptr)
|
||||
# define bfin_mac_alloc(dma_handle, size, num) l1_data_sram_zalloc(size*num)
|
||||
# define bfin_mac_free(dma_handle, ptr, num) l1_data_sram_free(ptr)
|
||||
#else
|
||||
# define bfin_mac_alloc(dma_handle, size) \
|
||||
dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
|
||||
# define bfin_mac_free(dma_handle, ptr) \
|
||||
dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
|
||||
# define bfin_mac_alloc(dma_handle, size, num) \
|
||||
dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL)
|
||||
# define bfin_mac_free(dma_handle, ptr, num) \
|
||||
dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle)
|
||||
#endif
|
||||
|
||||
#define PKT_BUF_SZ 1580
|
||||
|
@ -95,7 +95,7 @@ static void desc_list_free(void)
|
|||
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) {
|
||||
|
@ -109,7 +109,7 @@ static void desc_list_free(void)
|
|||
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
|
||||
|
||||
tx_desc = bfin_mac_alloc(&dma_handle,
|
||||
sizeof(struct net_dma_desc_tx) *
|
||||
sizeof(struct net_dma_desc_tx),
|
||||
CONFIG_BFIN_TX_DESC_NUM);
|
||||
if (tx_desc == NULL)
|
||||
goto init_error;
|
||||
|
||||
rx_desc = bfin_mac_alloc(&dma_handle,
|
||||
sizeof(struct net_dma_desc_rx) *
|
||||
sizeof(struct net_dma_desc_rx),
|
||||
CONFIG_BFIN_RX_DESC_NUM);
|
||||
if (rx_desc == NULL)
|
||||
goto init_error;
|
||||
|
|
|
@ -1297,6 +1297,7 @@ static inline int slave_enable_netpoll(struct slave *slave)
|
|||
goto out;
|
||||
|
||||
np->dev = slave->dev;
|
||||
strlcpy(np->dev_name, slave->dev->name, IFNAMSIZ);
|
||||
err = __netpoll_setup(np);
|
||||
if (err) {
|
||||
kfree(np);
|
||||
|
|
|
@ -105,7 +105,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
|||
goto out_ep;
|
||||
|
||||
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)) {
|
||||
ret = fpi->dpram_offset;
|
||||
goto out_fcccp;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
lp->txrcommit++;
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
|
||||
/* Update statistics */
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
drop:
|
||||
|
|
|
@ -135,7 +135,7 @@ static void __devexit hplance_remove_one(struct dio_dev *d)
|
|||
}
|
||||
|
||||
/* 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);
|
||||
struct hplance_private *lp;
|
||||
|
|
|
@ -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_nic_update_cmd_producer(adapter, tx_ring);
|
||||
|
||||
adapter->stats.txbytes += skb->len;
|
||||
adapter->stats.xmitcalled++;
|
||||
|
||||
netxen_nic_update_cmd_producer(adapter, tx_ring);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
drop_packet:
|
||||
|
|
|
@ -58,6 +58,7 @@ config BROADCOM_PHY
|
|||
|
||||
config BCM63XX_PHY
|
||||
tristate "Drivers for Broadcom 63xx SOCs internal PHY"
|
||||
depends on BCM63XX
|
||||
---help---
|
||||
Currently supports the 6348 and 6358 PHYs.
|
||||
|
||||
|
|
|
@ -543,11 +543,20 @@ static void recalibrate(struct dp83640_clock *clock)
|
|||
|
||||
/* time stamping methods */
|
||||
|
||||
static void decode_evnt(struct dp83640_private *dp83640,
|
||||
struct phy_txts *phy_txts, u16 ests)
|
||||
static int decode_evnt(struct dp83640_private *dp83640,
|
||||
void *data, u16 ests)
|
||||
{
|
||||
struct phy_txts *phy_txts;
|
||||
struct ptp_clock_event event;
|
||||
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 */
|
||||
case 3:
|
||||
|
@ -565,6 +574,9 @@ static void decode_evnt(struct dp83640_private *dp83640,
|
|||
event.timestamp = phy2txts(&dp83640->edata);
|
||||
|
||||
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,
|
||||
|
@ -643,9 +655,7 @@ static void decode_status_frame(struct dp83640_private *dp83640,
|
|||
|
||||
} else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) {
|
||||
|
||||
phy_txts = (struct phy_txts *) ptr;
|
||||
decode_evnt(dp83640, phy_txts, ests);
|
||||
size = sizeof(*phy_txts);
|
||||
size = decode_evnt(dp83640, ptr, ests);
|
||||
|
||||
} else {
|
||||
size = 0;
|
||||
|
@ -1034,8 +1044,8 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
|
|||
|
||||
if (is_status_frame(skb, type)) {
|
||||
decode_status_frame(dp83640, skb);
|
||||
/* Let the stack drop this frame. */
|
||||
return false;
|
||||
kfree_skb(skb);
|
||||
return true;
|
||||
}
|
||||
|
||||
SKB_PTP_TYPE(skb) = type;
|
||||
|
|
|
@ -523,7 +523,7 @@ static void ppp_async_process(unsigned long arg)
|
|||
#define PUT_BYTE(ap, buf, c, islcp) do { \
|
||||
if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
|
||||
*buf++ = PPP_ESCAPE; \
|
||||
*buf++ = c ^ 0x20; \
|
||||
*buf++ = c ^ PPP_TRANS; \
|
||||
} else \
|
||||
*buf++ = c; \
|
||||
} while (0)
|
||||
|
@ -896,7 +896,7 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
|
|||
sp = skb_put(skb, n);
|
||||
memcpy(sp, buf, n);
|
||||
if (ap->state & SC_ESCAPE) {
|
||||
sp[0] ^= 0x20;
|
||||
sp[0] ^= PPP_TRANS;
|
||||
ap->state &= ~SC_ESCAPE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1273,7 +1273,7 @@ static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
wmb();
|
||||
wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
|
||||
|
||||
stats->tx_bytes += skb->len;
|
||||
stats->tx_bytes += length;
|
||||
stats->tx_packets++;
|
||||
dev->trans_start = jiffies;
|
||||
if (pep->tx_ring_size - pep->tx_desc_count <= 1) {
|
||||
|
|
|
@ -1621,7 +1621,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
|
|||
*
|
||||
* (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
|
||||
*/
|
||||
static const struct {
|
||||
static const struct rtl_mac_info {
|
||||
u32 mask;
|
||||
u32 val;
|
||||
int mac_version;
|
||||
|
@ -1689,7 +1689,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
|
|||
|
||||
/* Catch-all */
|
||||
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
|
||||
}, *p = mac_info;
|
||||
};
|
||||
const struct rtl_mac_info *p = mac_info;
|
||||
u32 reg;
|
||||
|
||||
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 const struct {
|
||||
static const struct rtl_cfg2_info {
|
||||
u32 mac_version;
|
||||
u32 clk;
|
||||
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_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
|
||||
{ RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
|
||||
}, *p = cfg2_info;
|
||||
};
|
||||
const struct rtl_cfg2_info *p = cfg2_info;
|
||||
unsigned int i;
|
||||
u32 clk;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
#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 = {
|
||||
.ndo_uninit = tun_net_uninit,
|
||||
.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_change_mtu = tun_net_change_mtu,
|
||||
.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 = {
|
||||
|
@ -480,6 +499,9 @@ static const struct net_device_ops tap_netdev_ops = {
|
|||
.ndo_set_multicast_list = tun_net_mclist,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = tun_poll_controller,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Initialize net device. */
|
||||
|
|
|
@ -385,6 +385,16 @@ config USB_NET_CX82310_ETH
|
|||
router with USB ethernet port. This driver is for routers only,
|
||||
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
|
||||
tristate "Option USB High Speed Mobile Devices"
|
||||
depends on USB && RFKILL
|
||||
|
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_USB_NET_MCS7830) += mcs7830.o
|
|||
obj-$(CONFIG_USB_USBNET) += usbnet.o
|
||||
obj-$(CONFIG_USB_NET_INT51X1) += int51x1.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_SIERRA_NET) += sierra_net.o
|
||||
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
|
||||
|
|
384
drivers/net/usb/kalmia.c
Normal file
384
drivers/net/usb/kalmia.c
Normal 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");
|
|
@ -2203,8 +2203,10 @@ fst_open(struct net_device *dev)
|
|||
|
||||
if (port->mode != FST_RAW) {
|
||||
err = hdlc_open(dev);
|
||||
if (err)
|
||||
if (err) {
|
||||
module_put(THIS_MODULE);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
fst_openport(port);
|
||||
|
|
|
@ -1288,6 +1288,8 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
|
|||
|
||||
*(unsigned long *) wdev_priv = (unsigned long) priv;
|
||||
|
||||
set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev);
|
||||
|
||||
ret = wiphy_register(wdev->wiphy);
|
||||
if (ret < 0) {
|
||||
dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
|
||||
|
|
|
@ -2474,6 +2474,7 @@ struct mwl8k_cmd_set_hw_spec {
|
|||
* faster client.
|
||||
*/
|
||||
#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_HOSTFORM_PROBERESP 0x00000020
|
||||
#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 |
|
||||
MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
|
||||
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->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
|
|
|
@ -681,13 +681,14 @@ static void bfin_spi_pump_transfers(unsigned long data)
|
|||
drv_data->cs_change = transfer->cs_change;
|
||||
|
||||
/* Bits per word setup */
|
||||
bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word;
|
||||
if ((bits_per_word > 0) && (bits_per_word % 16 == 0)) {
|
||||
bits_per_word = transfer->bits_per_word ? :
|
||||
message->spi->bits_per_word ? : 8;
|
||||
if (bits_per_word % 16 == 0) {
|
||||
drv_data->n_bytes = bits_per_word/8;
|
||||
drv_data->len = (transfer->len) >> 1;
|
||||
cr_width = BIT_CTL_WORDSIZE;
|
||||
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->len = transfer->len;
|
||||
cr_width = 0;
|
||||
|
|
|
@ -81,7 +81,6 @@ struct adis16201_state {
|
|||
|
||||
int adis16201_set_irq(struct iio_dev *indio_dev, bool enable);
|
||||
|
||||
#ifdef CONFIG_IIO_RING_BUFFER
|
||||
enum adis16201_scan {
|
||||
ADIS16201_SCAN_SUPPLY,
|
||||
ADIS16201_SCAN_ACC_X,
|
||||
|
@ -92,6 +91,7 @@ enum adis16201_scan {
|
|||
ADIS16201_SCAN_INCLI_Y,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IIO_RING_BUFFER
|
||||
void adis16201_remove_trigger(struct iio_dev *indio_dev);
|
||||
int adis16201_probe_trigger(struct iio_dev *indio_dev);
|
||||
|
||||
|
|
|
@ -76,7 +76,6 @@ struct adis16203_state {
|
|||
|
||||
int adis16203_set_irq(struct iio_dev *indio_dev, bool enable);
|
||||
|
||||
#ifdef CONFIG_IIO_RING_BUFFER
|
||||
enum adis16203_scan {
|
||||
ADIS16203_SCAN_SUPPLY,
|
||||
ADIS16203_SCAN_AUX_ADC,
|
||||
|
@ -85,6 +84,7 @@ enum adis16203_scan {
|
|||
ADIS16203_SCAN_INCLI_Y,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IIO_RING_BUFFER
|
||||
void adis16203_remove_trigger(struct iio_dev *indio_dev);
|
||||
int adis16203_probe_trigger(struct iio_dev *indio_dev);
|
||||
|
||||
|
|
|
@ -248,10 +248,6 @@ static int atyfb_sync(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_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
|
||||
|
@ -2268,11 +2264,13 @@ error:
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static void aty_bl_exit(struct backlight_device *bd)
|
||||
{
|
||||
backlight_device_unregister(bd);
|
||||
printk("aty: Backlight unloaded\n");
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#endif /* CONFIG_FB_ATY_BACKLIGHT */
|
||||
|
||||
|
@ -2789,7 +2787,7 @@ aty_init_exit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATARI
|
||||
#if defined(CONFIG_ATARI) && !defined(MODULE)
|
||||
static int __devinit store_video_par(char *video_str, unsigned char m64_num)
|
||||
{
|
||||
char *p;
|
||||
|
@ -2818,7 +2816,7 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num)
|
|||
phys_vmembase[m64_num] = 0;
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_ATARI */
|
||||
#endif /* CONFIG_ATARI && !MODULE */
|
||||
|
||||
/*
|
||||
* Blank the display.
|
||||
|
|
|
@ -541,7 +541,7 @@ static int __init efifb_init(void)
|
|||
*/
|
||||
ret = platform_driver_probe(&efifb_driver, efifb_probe);
|
||||
if (ret) {
|
||||
platform_device_unregister(&efifb_driver);
|
||||
platform_device_unregister(&efifb_device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -235,13 +235,12 @@ static int s3c_fb_check_var(struct fb_var_screeninfo *var,
|
|||
struct fb_info *info)
|
||||
{
|
||||
struct s3c_fb_win *win = info->par;
|
||||
struct s3c_fb_pd_win *windata = win->windata;
|
||||
struct s3c_fb *sfb = win->parent;
|
||||
|
||||
dev_dbg(sfb->dev, "checking parameters\n");
|
||||
|
||||
var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres);
|
||||
var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres);
|
||||
var->xres_virtual = max(var->xres_virtual, var->xres);
|
||||
var->yres_virtual = max(var->yres_virtual, var->yres);
|
||||
|
||||
if (!s3c_fb_validate_win_bpp(win, var->bits_per_pixel)) {
|
||||
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_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;
|
||||
|
||||
/* 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(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);
|
||||
|
||||
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));
|
||||
|
||||
kfree(sfb);
|
||||
|
||||
pm_runtime_put_sync(sfb->dev);
|
||||
pm_runtime_disable(sfb->dev);
|
||||
|
||||
kfree(sfb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1127,23 +1127,16 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
|
|||
struct fb_info *info = hdmi->info;
|
||||
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);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put(hdmi->dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
|
||||
|
||||
/* Reconfigure the clock */
|
||||
ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
|
||||
if (ret < 0) {
|
||||
pm_runtime_put(hdmi->dev);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
msleep(10);
|
||||
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);
|
||||
|
||||
console_unlock();
|
||||
pm_runtime_put(hdmi->dev);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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 */
|
||||
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:
|
||||
free_irq(irq, hdmi);
|
||||
ereqirq:
|
||||
pm_runtime_suspend(&pdev->dev);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
iounmap(hdmi->base);
|
||||
emap:
|
||||
|
@ -1377,7 +1369,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
|
|||
free_irq(irq, hdmi);
|
||||
/* Wait for already scheduled work */
|
||||
cancel_delayed_work_sync(&hdmi->edid_work);
|
||||
pm_runtime_suspend(&pdev->dev);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
clk_disable(hdmi->hdmi_clk);
|
||||
clk_put(hdmi->hdmi_clk);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue