Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6

Conflicts:

	drivers/macintosh/adbhid.c
This commit is contained in:
Dmitry Torokhov 2007-10-12 21:27:47 -04:00
commit b981d8b3f5
7628 changed files with 537060 additions and 239341 deletions

View file

@ -130,6 +130,7 @@ config ROCKETPORT
config CYCLADES
tristate "Cyclades async mux support"
depends on SERIAL_NONSTANDARD && (PCI || ISA)
select FW_LOADER
---help---
This driver supports Cyclades Z and Y multiserial boards.
You would need something like this to connect more than two modems to
@ -185,7 +186,7 @@ config ESPSERIAL
config MOXA_INTELLIO
tristate "Moxa Intellio support"
depends on SERIAL_NONSTANDARD
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
help
Say Y here if you have a Moxa Intellio multiport serial card.
@ -241,7 +242,7 @@ config SYNCLINK
config SYNCLINKMP
tristate "SyncLink Multiport support"
depends on SERIAL_NONSTANDARD
depends on SERIAL_NONSTANDARD && PCI
help
Enable support for the SyncLink Multiport (2 or 4 ports)
serial adapter, running asynchronous and HDLC communications up
@ -372,39 +373,6 @@ config ISTALLION
To compile this driver as a module, choose M here: the
module will be called istallion.
config SERIAL_DEC
bool "DECstation serial support"
depends on MACH_DECSTATION
default y
help
This selects whether you want to be asked about drivers for
DECstation serial ports.
Note that the answer to this question won't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about DECstation serial ports.
config SERIAL_DEC_CONSOLE
bool "Support for console on a DECstation serial port"
depends on SERIAL_DEC
default y
help
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). Note that the firmware uses ttyS0 as the serial console on
the Maxine and ttyS2 on the others.
If unsure, say Y.
config ZS
bool "Z85C30 Serial Support"
depends on SERIAL_DEC
default y
help
Documentation on the Zilog 85C350 serial communications controller
is downloadable at <http://www.zilog.com/pdfs/serial/z85c30.pdf>
config A2232
tristate "Commodore A2232 serial support (EXPERIMENTAL)"
depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
@ -637,6 +605,14 @@ config HVC_BEAT
help
Toshiba's Cell Reference Set Beat Console device driver
config HVC_XEN
bool "Xen Hypervisor Console support"
depends on XEN
select HVC_DRIVER
default y
help
Xen virtual console device driver
config HVCS
tristate "IBM Hypervisor Virtual Console Server support"
depends on PPC_PSERIES
@ -751,7 +727,7 @@ config NVRAM
config RTC
tristate "Enhanced Real Time Clock Support"
depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH && !S390
depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
@ -775,6 +751,28 @@ config RTC
To compile this driver as a module, choose M here: the
module will be called rtc.
config JS_RTC
tristate "Enhanced Real Time Clock Support"
depends on SPARC32 && PCI
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
will get access to the real time clock (or hardware clock) built
into your computer.
Every PC has such a clock built in. It can be used to generate
signals from as low as 1Hz up to 8192Hz, and can also be used
as a 24 hour alarm. It reports status information via the file
/proc/driver/rtc and its behaviour is set by various ioctls on
/dev/rtc.
If you think you have a use for such a device (such as periodic data
sampling), then say Y here, and read <file:Documentation/rtc.txt>
for details.
To compile this driver as a module, choose M here: the
module will be called js-rtc.
config SGI_DS1286
tristate "SGI DS1286 RTC support"
depends on SGI_IP22

View file

@ -42,12 +42,14 @@ obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o
obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_LGUEST_GUEST) += hvc_lguest.o
obj-$(CONFIG_RIO) += rio/ generic_serial.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
obj-$(CONFIG_HVC_XEN) += hvc_xen.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
obj-$(CONFIG_MSPEC) += mspec.o
@ -95,7 +97,6 @@ obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_GPIO_TB0219) += tb0219.o
obj-$(CONFIG_TELCLOCK) += tlclk.o
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_MWAVE) += mwave/
obj-$(CONFIG_AGP) += agp/
obj-$(CONFIG_DRM) += drm/
@ -105,6 +106,11 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/
obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
obj-$(CONFIG_TCG_TPM) += tpm/
obj-$(CONFIG_PS3_FLASH) += ps3flash.o
obj-$(CONFIG_JS_RTC) += js-rtc.o
js-rtc-y = rtc.o
# Files generated that shall be removed upon make clean
clean-files := consolemap_deftbl.c defkeymap.c
@ -123,7 +129,7 @@ $(obj)/defkeymap.o: $(obj)/defkeymap.c
ifdef GENERATE_KEYMAP
$(obj)/defkeymap.c $(obj)/%.c: $(src)/%.map
$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
loadkeys --mktable $< > $@.tmp
sed -e 's/^static *//' $@.tmp > $@
rm $@.tmp

View file

@ -50,7 +50,7 @@ config AGP_ATI
config AGP_AMD
tristate "AMD Irongate, 761, and 762 chipset support"
depends on AGP && X86_32
depends on AGP && (X86_32 || ALPHA)
help
This option gives you AGP support for the GLX component of
X on AMD Irongate, 761, and 762 chipsets.

View file

@ -176,7 +176,7 @@ struct agp_bridge_data {
#define I830_GMCH_MEM_MASK 0x1
#define I830_GMCH_MEM_64M 0x1
#define I830_GMCH_MEM_128M 0
#define I830_GMCH_GMS_MASK 0xF0
#define I830_GMCH_GMS_MASK 0x70
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
@ -190,6 +190,7 @@ struct agp_bridge_data {
#define INTEL_I830_ERRSTS 0x92
/* Intel 855GM/852GM registers */
#define I855_GMCH_GMS_MASK 0xF0
#define I855_GMCH_GMS_STOLEN_0M 0x0
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)

View file

@ -223,6 +223,8 @@ static int amd_irongate_configure(void)
pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
if (!amd_irongate_private.registers)
return -ENOMEM;
/* Write out the address of the gatt table */
writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);

View file

@ -123,21 +123,16 @@ static int ati_create_gatt_pages(int nr_tables)
for (i = 0; i < nr_tables; i++) {
entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL);
tables[i] = entry;
if (entry == NULL) {
while (i > 0) {
kfree(tables[i-1]);
i--;
}
kfree(tables);
retval = -ENOMEM;
break;
}
tables[i] = entry;
retval = ati_create_page_map(entry);
if (retval != 0)
break;
}
ati_generic_private.num_tables = nr_tables;
ati_generic_private.num_tables = i;
ati_generic_private.gatt_pages = tables;
if (retval != 0)
@ -218,6 +213,9 @@ static int ati_configure(void)
temp = (temp & 0xfffff000);
ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
if (!ati_generic_private.registers)
return -ENOMEM;
if (is_r200())
pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000);
else

View file

@ -28,6 +28,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/agpgart.h>
#include <asm/uaccess.h>
#include "agp.h"

View file

@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
if (!r->start && r->end) {
if (pci_assign_resource(pdev, 0)) {
printk(KERN_ERR PFX "could not assign resource 0\n");
agp_put_bridge(bridge);
return -ENODEV;
}
}
@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
*/
if (pci_enable_device(pdev)) {
printk(KERN_ERR PFX "Unable to Enable PCI device\n");
agp_put_bridge(bridge);
return -ENODEV;
}

View file

@ -37,6 +37,7 @@
#include <linux/agpgart.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>

View file

@ -1170,7 +1170,6 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge)
map_page_into_agp(page);
get_page(page);
SetPageLocked(page);
atomic_inc(&agp_bridge->current_memory_agp);
return page_address(page);
}
@ -1187,7 +1186,6 @@ void agp_generic_destroy_page(void *addr)
page = virt_to_page(addr);
unmap_page_from_agp(page);
put_page(page);
unlock_page(page);
free_page((unsigned long)addr);
atomic_dec(&agp_bridge->current_memory_agp);
}

View file

@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa)
if (cap != PCI_CAP_ID_AGP) {
printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
cap, hp->lba_cap_offset);
iounmap(hp->lba_regs);
return -ENODEV;
}

View file

@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge)
num_entries = A_SIZE_8(temp)->num_entries;
i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order);
if (!i460.gatt) {
printk(KERN_ERR PFX "ioremap failed\n");
return -ENOMEM;
}
/* These are no good, the should be removed from the agp_bridge strucure... */
agp_bridge->gatt_table_real = NULL;

View file

@ -20,7 +20,9 @@
#define PCI_DEVICE_ID_INTEL_82965G_IG 0x29A2
#define PCI_DEVICE_ID_INTEL_82965GM_HB 0x2A00
#define PCI_DEVICE_ID_INTEL_82965GM_IG 0x2A02
#define PCI_DEVICE_ID_INTEL_82965GME_HB 0x2A10
#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
@ -33,7 +35,8 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
@ -213,7 +216,6 @@ static void *i8xx_alloc_pages(void)
}
global_flush_tlb();
get_page(page);
SetPageLocked(page);
atomic_inc(&agp_bridge->current_memory_agp);
return page_address(page);
}
@ -229,7 +231,6 @@ static void i8xx_destroy_pages(void *addr)
change_page_attr(page, 4, PAGE_KERNEL);
global_flush_tlb();
put_page(page);
unlock_page(page);
__free_pages(page, 2);
atomic_dec(&agp_bridge->current_memory_agp);
}
@ -505,7 +506,7 @@ static void intel_i830_init_gtt_entries(void)
break;
}
} else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
switch (gmch_ctrl & I855_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
gtt_entries = MB(1) - KB(size);
break;
@ -527,6 +528,7 @@ static void intel_i830_init_gtt_entries(void)
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
IS_I965 || IS_G33)
gtt_entries = MB(48) - KB(size);
else
@ -538,6 +540,7 @@ static void intel_i830_init_gtt_entries(void)
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GM_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945GME_HB ||
IS_I965 || IS_G33)
gtt_entries = MB(64) - KB(size);
else
@ -911,6 +914,7 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
struct aper_size_info_fixed *size;
int num_entries;
u32 temp, temp2;
int gtt_map_size = 256 * 1024;
size = agp_bridge->current_size;
page_order = size->page_order;
@ -920,15 +924,19 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge)
pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
pci_read_config_dword(intel_private.pcidev, I915_PTEADDR,&temp2);
intel_private.gtt = ioremap(temp2, 256 * 1024);
if (IS_G33)
gtt_map_size = 1024 * 1024; /* 1M on G33 */
intel_private.gtt = ioremap(temp2, gtt_map_size);
if (!intel_private.gtt)
return -ENOMEM;
temp &= 0xfff80000;
intel_private.registers = ioremap(temp,128 * 4096);
if (!intel_private.registers)
if (!intel_private.registers) {
iounmap(intel_private.gtt);
return -ENOMEM;
}
temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
@ -982,13 +990,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
temp &= 0xfff00000;
intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024);
if (!intel_private.gtt)
return -ENOMEM;
if (!intel_private.gtt)
return -ENOMEM;
intel_private.registers = ioremap(temp,128 * 4096);
if (!intel_private.registers)
return -ENOMEM;
if (!intel_private.registers) {
iounmap(intel_private.gtt);
return -ENOMEM;
}
temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush(); /* FIXME: ? */
@ -1848,9 +1858,9 @@ static const struct intel_driver_description {
NULL, &intel_915_driver },
{ PCI_DEVICE_ID_INTEL_82945G_HB, PCI_DEVICE_ID_INTEL_82945G_IG, 0, "945G",
NULL, &intel_915_driver },
{ PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 1, "945GM",
{ PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GM_IG, 0, "945GM",
NULL, &intel_915_driver },
{ PCI_DEVICE_ID_INTEL_82945GM_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
{ PCI_DEVICE_ID_INTEL_82945GME_HB, PCI_DEVICE_ID_INTEL_82945GME_IG, 0, "945GME",
NULL, &intel_915_driver },
{ PCI_DEVICE_ID_INTEL_82946GZ_HB, PCI_DEVICE_ID_INTEL_82946GZ_IG, 0, "946GZ",
NULL, &intel_i965_driver },
@ -1860,9 +1870,9 @@ static const struct intel_driver_description {
NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_82965G_HB, PCI_DEVICE_ID_INTEL_82965G_IG, 0, "965G",
NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 1, "965GM",
{ PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GM_IG, 0, "965GM",
NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_82965GM_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
{ PCI_DEVICE_ID_INTEL_82965GME_HB, PCI_DEVICE_ID_INTEL_82965GME_IG, 0, "965GME/GLE",
NULL, &intel_i965_driver },
{ PCI_DEVICE_ID_INTEL_7505_0, 0, 0, "E7505", &intel_7505_driver, NULL },
{ PCI_DEVICE_ID_INTEL_7205_0, 0, 0, "E7205", &intel_7505_driver, NULL },
@ -2051,11 +2061,13 @@ static struct pci_device_id agp_intel_pci_table[] = {
ID(PCI_DEVICE_ID_INTEL_82915GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945G_HB),
ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
ID(PCI_DEVICE_ID_INTEL_82965G_HB),
ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
ID(PCI_DEVICE_ID_INTEL_82965GME_HB),
ID(PCI_DEVICE_ID_INTEL_G33_HB),
ID(PCI_DEVICE_ID_INTEL_Q35_HB),
ID(PCI_DEVICE_ID_INTEL_Q33_HB),

View file

@ -157,6 +157,9 @@ static int nvidia_configure(void)
nvidia_private.aperture =
(volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE);
if (!nvidia_private.aperture)
return -ENOMEM;
return 0;
}

View file

@ -51,7 +51,6 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge)
return NULL;
get_page(page);
SetPageLocked(page);
atomic_inc(&agp_bridge->current_memory_agp);
return page_address(page);
}

View file

@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
.device_id = PCI_DEVICE_ID_VIA_P4M890,
.chipset_name = "P4M890",
},
/* P4M900 */
{
.device_id = PCI_DEVICE_ID_VIA_VT3364,
.chipset_name = "P4M900",
},
{ }, /* dummy final entry, always present */
};

View file

@ -1721,12 +1721,11 @@ static int get_async_struct(int line, struct async_struct **ret_info)
*ret_info = sstate->info;
return 0;
}
info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
info = kzalloc(sizeof(struct async_struct), GFP_KERNEL);
if (!info) {
sstate->count--;
return -ENOMEM;
}
memset(info, 0, sizeof(struct async_struct));
#ifdef DECLARE_WAITQUEUE
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);

View file

@ -1,67 +0,0 @@
/*
* sercons.c
* choose the right serial device at boot time
*
* triemer 6-SEP-1998
* sercons.c is designed to allow the three different kinds
* of serial devices under the decstation world to co-exist
* in the same kernel. The idea here is to abstract
* the pieces of the drivers that are common to this file
* so that they do not clash at compile time and runtime.
*
* HK 16-SEP-1998 v0.002
* removed the PROM console as this is not a real serial
* device. Added support for PROM console in drivers/char/tty_io.c
* instead. Although it may work to enable more than one
* console device I strongly recommend to use only one.
*/
#include <linux/init.h>
#include <asm/dec/machtype.h>
#ifdef CONFIG_ZS
extern int zs_init(void);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_ZS
extern void zs_serial_console_init(void);
#endif
#endif
/* rs_init - starts up the serial interface -
handle normal case of starting up the serial interface */
#ifdef CONFIG_SERIAL
int __init rs_init(void)
{
#ifdef CONFIG_ZS
if (IOASIC)
return zs_init();
#endif
return -ENXIO;
}
__initcall(rs_init);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
/* serial_console_init handles the special case of starting
* up the console on the serial port
*/
static int __init decserial_console_init(void)
{
#ifdef CONFIG_ZS
if (IOASIC)
zs_serial_console_init();
#endif
return 0;
}
console_initcall(decserial_console_init);
#endif

View file

@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
MTRR_TYPE_WRCOMB, 1);
}
}
if (map->type == _DRM_REGISTERS)
if (map->type == _DRM_REGISTERS) {
map->handle = ioremap(map->offset, map->size);
if (!map->handle) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -ENOMEM;
}
}
break;
case _DRM_SHM:
list = drm_find_matching_map(dev, map);
@ -479,11 +485,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
return -EINVAL;
}
if (!map) {
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
/* Register and framebuffer maps are permanent */
if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
mutex_unlock(&dev->struct_mutex);

View file

@ -184,6 +184,8 @@ static int i915_initialize(struct drm_device * dev,
* private backbuffer/depthbuffer usage.
*/
dev_priv->use_mi_batchbuffer_start = 0;
if (IS_I965G(dev)) /* 965 doesn't support older method */
dev_priv->use_mi_batchbuffer_start = 1;
/* Allow hardware batchbuffers unless told otherwise.
*/
@ -517,8 +519,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
if (dev_priv->use_mi_batchbuffer_start) {
BEGIN_LP_RING(2);
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
OUT_RING(batch->start | MI_BATCH_NON_SECURE);
if (IS_I965G(dev)) {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
OUT_RING(batch->start);
} else {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
OUT_RING(batch->start | MI_BATCH_NON_SECURE);
}
ADVANCE_LP_RING();
} else {
BEGIN_LP_RING(4);
@ -735,7 +742,8 @@ static int i915_setparam(DRM_IOCTL_ARGS)
switch (param.param) {
case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
dev_priv->use_mi_batchbuffer_start = param.value;
if (!IS_I965G(dev))
dev_priv->use_mi_batchbuffer_start = param.value;
break;
case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
dev_priv->tex_lru_log_granularity = param.value;

View file

@ -210,6 +210,12 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915REG_INT_MASK_R 0x020a8
#define I915REG_INT_ENABLE_R 0x020a0
#define I915REG_PIPEASTAT 0x70024
#define I915REG_PIPEBSTAT 0x71024
#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
#define I915_VBLANK_CLEAR (1UL<<1)
#define SRX_INDEX 0x3c4
#define SRX_DATA 0x3c5
#define SR01 1
@ -282,6 +288,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define MI_BATCH_BUFFER_START (0x31<<23)
#define MI_BATCH_BUFFER_END (0xA<<23)
#define MI_BATCH_NON_SECURE (1)
#define MI_BATCH_NON_SECURE_I965 (1<<8)
#define MI_WAIT_FOR_EVENT ((0x3<<23))
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)

View file

@ -214,6 +214,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u16 temp;
u32 pipea_stats, pipeb_stats;
pipea_stats = I915_READ(I915REG_PIPEASTAT);
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
@ -225,6 +229,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_NONE;
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ16(I915REG_INT_IDENTITY_R);
DRM_READMEMORYBARRIER();
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
@ -252,6 +258,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
I915_WRITE(I915REG_PIPEASTAT,
pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
I915_VBLANK_CLEAR);
I915_WRITE(I915REG_PIPEBSTAT,
pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
I915_VBLANK_CLEAR);
}
return IRQ_HANDLED;

View file

@ -273,10 +273,9 @@ via_alloc_desc_pages(drm_via_sg_info_t *vsg)
vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
vsg->descriptors_per_page;
if (NULL == (vsg->desc_pages = kmalloc(sizeof(void *) * vsg->num_desc_pages, GFP_KERNEL)))
if (NULL == (vsg->desc_pages = kcalloc(vsg->num_desc_pages, sizeof(void *), GFP_KERNEL)))
return DRM_ERR(ENOMEM);
memset(vsg->desc_pages, 0, sizeof(void *) * vsg->num_desc_pages);
vsg->state = dr_via_desc_pages_alloc;
for (i=0; i<vsg->num_desc_pages; ++i) {
if (NULL == (vsg->desc_pages[i] =
@ -561,7 +560,7 @@ via_init_dmablit(struct drm_device *dev)
blitq->head = 0;
blitq->cur = 0;
blitq->serviced = 0;
blitq->num_free = VIA_NUM_BLIT_SLOTS;
blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
blitq->num_outstanding = 0;
blitq->is_active = 0;
blitq->aborting = 0;

View file

@ -513,7 +513,7 @@ static int __init dsp56k_init_driver(void)
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k");
printk(banner);
goto out;
@ -527,7 +527,7 @@ module_init(dsp56k_init_driver);
static void __exit dsp56k_cleanup_driver(void)
{
class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
class_destroy(dsp56k_class);
unregister_chrdev(DSP56K_MAJOR, "dsp56k");
}

View file

@ -2459,7 +2459,7 @@ static int __init espserial_init(void)
return 1;
}
info = kmalloc(sizeof(struct esp_struct), GFP_KERNEL);
info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
if (!info)
{
@ -2469,7 +2469,6 @@ static int __init espserial_init(void)
return 1;
}
memset((void *)info, 0, sizeof(struct esp_struct));
spin_lock_init(&info->lock);
/* rx_trigger, tx_trigger are needed by autoconfig */
info->config.rx_trigger = rx_trigger;
@ -2527,7 +2526,7 @@ static int __init espserial_init(void)
if (!dma)
info->stat_flags |= ESP_STAT_NEVER_DMA;
info = kmalloc(sizeof(struct esp_struct), GFP_KERNEL);
info = kzalloc(sizeof(struct esp_struct), GFP_KERNEL);
if (!info)
{
printk(KERN_ERR "Couldn't allocate memory for esp serial device information\n");
@ -2536,7 +2535,6 @@ static int __init espserial_init(void)
return 0;
}
memset((void *)info, 0, sizeof(struct esp_struct));
/* rx_trigger, tx_trigger are needed by autoconfig */
info->config.rx_trigger = rx_trigger;
info->config.tx_trigger = tx_trigger;

View file

@ -29,6 +29,7 @@
#include <linux/bcd.h>
#include <linux/seq_file.h>
#include <linux/bitops.h>
#include <linux/clocksource.h>
#include <asm/current.h>
#include <asm/uaccess.h>
@ -51,8 +52,37 @@
#define HPET_RANGE_SIZE 1024 /* from HPET spec */
#if BITS_PER_LONG == 64
#define write_counter(V, MC) writeq(V, MC)
#define read_counter(MC) readq(MC)
#else
#define write_counter(V, MC) writel(V, MC)
#define read_counter(MC) readl(MC)
#endif
static u32 hpet_nhpet, hpet_max_freq = HPET_USER_FREQ;
/* This clocksource driver currently only works on ia64 */
#ifdef CONFIG_IA64
static void __iomem *hpet_mctr;
static cycle_t read_hpet(void)
{
return (cycle_t)read_counter((void __iomem *)hpet_mctr);
}
static struct clocksource clocksource_hpet = {
.name = "hpet",
.rating = 250,
.read = read_hpet,
.mask = CLOCKSOURCE_MASK(64),
.mult = 0, /*to be caluclated*/
.shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static struct clocksource *hpet_clocksource;
#endif
/* A lock for concurrent access by app and isr hpet activity. */
static DEFINE_SPINLOCK(hpet_lock);
/* A lock for concurrent intermodule access to hpet and isr hpet activity. */
@ -79,7 +109,7 @@ struct hpets {
struct hpets *hp_next;
struct hpet __iomem *hp_hpet;
unsigned long hp_hpet_phys;
struct time_interpolator *hp_interpolator;
struct clocksource *hp_clocksource;
unsigned long long hp_tick_freq;
unsigned long hp_delta;
unsigned int hp_ntimer;
@ -94,13 +124,6 @@ static struct hpets *hpets;
#define HPET_PERIODIC 0x0004
#define HPET_SHARED_IRQ 0x0008
#if BITS_PER_LONG == 64
#define write_counter(V, MC) writeq(V, MC)
#define read_counter(MC) readq(MC)
#else
#define write_counter(V, MC) writel(V, MC)
#define read_counter(MC) readl(MC)
#endif
#ifndef readq
static inline unsigned long long readq(void __iomem *addr)
@ -737,27 +760,6 @@ static ctl_table dev_root[] = {
static struct ctl_table_header *sysctl_header;
static void hpet_register_interpolator(struct hpets *hpetp)
{
#ifdef CONFIG_TIME_INTERPOLATION
struct time_interpolator *ti;
ti = kzalloc(sizeof(*ti), GFP_KERNEL);
if (!ti)
return;
ti->source = TIME_SOURCE_MMIO64;
ti->shift = 10;
ti->addr = &hpetp->hp_hpet->hpet_mc;
ti->frequency = hpetp->hp_tick_freq;
ti->drift = HPET_DRIFT;
ti->mask = -1;
hpetp->hp_interpolator = ti;
register_time_interpolator(ti);
#endif
}
/*
* Adjustment for when arming the timer with
* initial conditions. That is, main counter
@ -909,7 +911,19 @@ int hpet_alloc(struct hpet_data *hdp)
}
hpetp->hp_delta = hpet_calibrate(hpetp);
hpet_register_interpolator(hpetp);
/* This clocksource driver currently only works on ia64 */
#ifdef CONFIG_IA64
if (!hpet_clocksource) {
hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr);
clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq,
clocksource_hpet.shift);
clocksource_register(&clocksource_hpet);
hpetp->hp_clocksource = &clocksource_hpet;
hpet_clocksource = &clocksource_hpet;
}
#endif
return 0;
}
@ -932,14 +946,14 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
printk(KERN_DEBUG "%s: 0x%lx is busy\n",
__FUNCTION__, hdp->hd_phys_address);
iounmap(hdp->hd_address);
return -EBUSY;
return AE_ALREADY_EXISTS;
}
} else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
struct acpi_resource_fixed_memory32 *fixmem32;
fixmem32 = &res->data.fixed_memory32;
if (!fixmem32)
return -EINVAL;
return AE_NO_MEMORY;
hdp->hd_phys_address = fixmem32->address;
hdp->hd_address = ioremap(fixmem32->address,
@ -949,7 +963,7 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
printk(KERN_DEBUG "%s: 0x%lx is busy\n",
__FUNCTION__, hdp->hd_phys_address);
iounmap(hdp->hd_address);
return -EBUSY;
return AE_ALREADY_EXISTS;
}
} else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
struct acpi_resource_extended_irq *irqp;
@ -995,13 +1009,19 @@ static int hpet_acpi_add(struct acpi_device *device)
static int hpet_acpi_remove(struct acpi_device *device, int type)
{
/* XXX need to unregister interpolator, dealloc mem, etc */
/* XXX need to unregister clocksource, dealloc mem, etc */
return -EINVAL;
}
static const struct acpi_device_id hpet_device_ids[] = {
{"PNP0103", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, hpet_device_ids);
static struct acpi_driver hpet_acpi_driver = {
.name = "hpet",
.ids = "PNP0103",
.ids = hpet_device_ids,
.ops = {
.add = hpet_acpi_add,
.remove = hpet_acpi_remove,

View file

@ -97,7 +97,7 @@ static int hvc_beat_config(char *p)
return 0;
}
static int hvc_beat_console_init(void)
static int __init hvc_beat_console_init(void)
{
if (hvc_beat_useit && machine_is_compatible("Beat")) {
hvc_instantiate(0, 0, &hvc_beat_get_put_ops);
@ -106,7 +106,7 @@ static int hvc_beat_console_init(void)
}
/* temp */
static int hvc_beat_init(void)
static int __init hvc_beat_init(void)
{
struct hvc_struct *hp;

View file

@ -472,7 +472,7 @@ static void hvc_handle_event(struct HvLpEvent *event)
}
}
static int send_open(HvLpIndex remoteLp, void *sem)
static int __init send_open(HvLpIndex remoteLp, void *sem)
{
return HvCallEvent_signalLpEventFast(remoteLp,
HvLpEvent_Type_VirtualIo,
@ -484,7 +484,7 @@ static int send_open(HvLpIndex remoteLp, void *sem)
0, 0, 0, 0);
}
static int hvc_vio_init(void)
static int __init hvc_vio_init(void)
{
atomic_t wait_flag;
int rc;
@ -552,14 +552,14 @@ static int hvc_vio_init(void)
}
module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */
static void hvc_vio_exit(void)
static void __exit hvc_vio_exit(void)
{
vio_unregister_driver(&hvc_vio_driver);
}
module_exit(hvc_vio_exit);
/* the device tree order defines our numbering */
static int hvc_find_vtys(void)
static int __init hvc_find_vtys(void)
{
struct device_node *vty;
int num_found = 0;

177
drivers/char/hvc_lguest.c Normal file
View file

@ -0,0 +1,177 @@
/*D:300
* The Guest console driver
*
* This is a trivial console driver: we use lguest's DMA mechanism to send
* bytes out, and register a DMA buffer to receive bytes in. It is assumed to
* be present and available from the very beginning of boot.
*
* Writing console drivers is one of the few remaining Dark Arts in Linux.
* Fortunately for us, the path of virtual consoles has been well-trodden by
* the PowerPC folks, who wrote "hvc_console.c" to generically support any
* virtual console. We use that infrastructure which only requires us to write
* the basic put_chars and get_chars functions and call the right register
* functions.
:*/
/*M:002 The console can be flooded: while the Guest is processing input the
* Host can send more. Buffering in the Host could alleviate this, but it is a
* difficult problem in general. :*/
/* Copyright (C) 2006 Rusty Russell, IBM Corporation
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/lguest_bus.h>
#include <asm/paravirt.h>
#include "hvc_console.h"
/*D:340 This is our single console input buffer, with associated "struct
* lguest_dma" referring to it. Note the 0-terminated length array, and the
* use of physical address for the buffer itself. */
static char inbuf[256];
static struct lguest_dma cons_input = { .used_len = 0,
.addr[0] = __pa(inbuf),
.len[0] = sizeof(inbuf),
.len[1] = 0 };
/*D:310 The put_chars() callback is pretty straightforward.
*
* First we put the pointer and length in a "struct lguest_dma": we only have
* one pointer, so we set the second length to 0. Then we use SEND_DMA to send
* the data to (Host) buffers attached to the console key. Usually a device's
* key is a physical address within the device's memory, but because the
* console device doesn't have any associated physical memory, we use the
* LGUEST_CONSOLE_DMA_KEY constant (aka 0). */
static int put_chars(u32 vtermno, const char *buf, int count)
{
struct lguest_dma dma;
/* FIXME: DMA buffers in a "struct lguest_dma" are not allowed
* to go over page boundaries. This never seems to happen,
* but if it did we'd need to fix this code. */
dma.len[0] = count;
dma.len[1] = 0;
dma.addr[0] = __pa(buf);
lguest_send_dma(LGUEST_CONSOLE_DMA_KEY, &dma);
/* We're expected to return the amount of data we wrote: all of it. */
return count;
}
/*D:350 get_chars() is the callback from the hvc_console infrastructure when
* an interrupt is received.
*
* Firstly we see if our buffer has been filled: if not, we return. The rest
* of the code deals with the fact that the hvc_console() infrastructure only
* asks us for 16 bytes at a time. We keep a "cons_offset" variable for
* partially-read buffers. */
static int get_chars(u32 vtermno, char *buf, int count)
{
static int cons_offset;
/* Nothing left to see here... */
if (!cons_input.used_len)
return 0;
/* You want more than we have to give? Well, try wanting less! */
if (cons_input.used_len - cons_offset < count)
count = cons_input.used_len - cons_offset;
/* Copy across to their buffer and increment offset. */
memcpy(buf, inbuf + cons_offset, count);
cons_offset += count;
/* Finished? Zero offset, and reset cons_input so Host will use it
* again. */
if (cons_offset == cons_input.used_len) {
cons_offset = 0;
cons_input.used_len = 0;
}
return count;
}
/*:*/
static struct hv_ops lguest_cons = {
.get_chars = get_chars,
.put_chars = put_chars,
};
/*D:320 Console drivers are initialized very early so boot messages can go
* out. At this stage, the console is output-only. Our driver checks we're a
* Guest, and if so hands hvc_instantiate() the console number (0), priority
* (0), and the struct hv_ops containing the put_chars() function. */
static int __init cons_init(void)
{
if (strcmp(paravirt_ops.name, "lguest") != 0)
return 0;
return hvc_instantiate(0, 0, &lguest_cons);
}
console_initcall(cons_init);
/*D:370 To set up and manage our virtual console, we call hvc_alloc() and
* stash the result in the private pointer of the "struct lguest_device".
* Since we never remove the console device we never need this pointer again,
* but using ->private is considered good form, and you never know who's going
* to copy your driver.
*
* Once the console is set up, we bind our input buffer ready for input. */
static int lguestcons_probe(struct lguest_device *lgdev)
{
int err;
/* The first argument of hvc_alloc() is the virtual console number, so
* we use zero. The second argument is the interrupt number.
*
* The third argument is a "struct hv_ops" containing the put_chars()
* and get_chars() pointers. The final argument is the output buffer
* size: we use 256 and expect the Host to have room for us to send
* that much. */
lgdev->private = hvc_alloc(0, lgdev_irq(lgdev), &lguest_cons, 256);
if (IS_ERR(lgdev->private))
return PTR_ERR(lgdev->private);
/* We bind a single DMA buffer at key LGUEST_CONSOLE_DMA_KEY.
* "cons_input" is that statically-initialized global DMA buffer we saw
* above, and we also give the interrupt we want. */
err = lguest_bind_dma(LGUEST_CONSOLE_DMA_KEY, &cons_input, 1,
lgdev_irq(lgdev));
if (err)
printk("lguest console: failed to bind buffer.\n");
return err;
}
/* Note the use of lgdev_irq() for the interrupt number. We tell hvc_alloc()
* to expect input when this interrupt is triggered, and then tell
* lguest_bind_dma() that is the interrupt to send us when input comes in. */
/*D:360 From now on the console driver follows standard Guest driver form:
* register_lguest_driver() registers the device type and probe function, and
* the probe function sets up the device.
*
* The standard "struct lguest_driver": */
static struct lguest_driver lguestcons_drv = {
.name = "lguestcons",
.owner = THIS_MODULE,
.device_type = LGUEST_DEVICE_T_CONSOLE,
.probe = lguestcons_probe,
};
/* The standard init function */
static int __init hvc_lguest_init(void)
{
return register_lguest_driver(&lguestcons_drv);
}
module_init(hvc_lguest_init);

View file

@ -115,7 +115,7 @@ static void __exit hvc_rtas_exit(void)
module_exit(hvc_rtas_exit);
/* This will happen prior to module init. There is no tty at this time? */
static int hvc_rtas_console_init(void)
static int __init hvc_rtas_console_init(void)
{
rtascons_put_char_token = rtas_token("put-term-char");
if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)

159
drivers/char/hvc_xen.c Normal file
View file

@ -0,0 +1,159 @@
/*
* xen console driver interface to hvc_console.c
*
* (c) 2007 Gerd Hoffmann <kraxel@suse.de>
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/types.h>
#include <asm/xen/hypervisor.h>
#include <xen/page.h>
#include <xen/events.h>
#include <xen/interface/io/console.h>
#include <xen/hvc-console.h>
#include "hvc_console.h"
#define HVC_COOKIE 0x58656e /* "Xen" in hex */
static struct hvc_struct *hvc;
static int xencons_irq;
/* ------------------------------------------------------------------ */
static inline struct xencons_interface *xencons_interface(void)
{
return mfn_to_virt(xen_start_info->console.domU.mfn);
}
static inline void notify_daemon(void)
{
/* Use evtchn: this is called early, before irq is set up. */
notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
}
static int write_console(uint32_t vtermno, const char *data, int len)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
int sent = 0;
cons = intf->out_cons;
prod = intf->out_prod;
mb(); /* update queue values before going on */
BUG_ON((prod - cons) > sizeof(intf->out));
while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
wmb(); /* write ring before updating pointer */
intf->out_prod = prod;
notify_daemon();
return sent;
}
static int read_console(uint32_t vtermno, char *buf, int len)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
int recv = 0;
cons = intf->in_cons;
prod = intf->in_prod;
mb(); /* get pointers before reading ring */
BUG_ON((prod - cons) > sizeof(intf->in));
while (cons != prod && recv < len)
buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
mb(); /* read ring before consuming */
intf->in_cons = cons;
notify_daemon();
return recv;
}
static struct hv_ops hvc_ops = {
.get_chars = read_console,
.put_chars = write_console,
};
static int __init xen_init(void)
{
struct hvc_struct *hp;
if (!is_running_on_xen())
return 0;
xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
if (xencons_irq < 0)
xencons_irq = 0 /* NO_IRQ */;
hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
if (IS_ERR(hp))
return PTR_ERR(hp);
hvc = hp;
return 0;
}
static void __exit xen_fini(void)
{
if (hvc)
hvc_remove(hvc);
}
static int xen_cons_init(void)
{
if (!is_running_on_xen())
return 0;
hvc_instantiate(HVC_COOKIE, 0, &hvc_ops);
return 0;
}
module_init(xen_init);
module_exit(xen_fini);
console_initcall(xen_cons_init);
static void xenboot_write_console(struct console *console, const char *string,
unsigned len)
{
unsigned int linelen, off = 0;
const char *pos;
while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
linelen = pos-string+off;
if (off + linelen > len)
break;
write_console(0, string+off, linelen);
write_console(0, "\r\n", 2);
off += linelen + 1;
}
if (off < len)
write_console(0, string+off, len-off);
}
struct console xenboot_console = {
.name = "xenboot",
.write = xenboot_write_console,
.flags = CON_PRINTBUFFER | CON_BOOT,
};

View file

@ -210,9 +210,9 @@ static struct ktermios hvcs_tty_termios = {
static int hvcs_parm_num_devs = -1;
module_param(hvcs_parm_num_devs, int, 0);
char hvcs_driver_name[] = "hvcs";
char hvcs_device_node[] = "hvcs";
char hvcs_driver_string[]
static const char hvcs_driver_name[] = "hvcs";
static const char hvcs_device_node[] = "hvcs";
static const char hvcs_driver_string[]
= "IBM hvcs (Hypervisor Virtual Console Server) Driver";
/* Status of partner info rescan triggered via sysfs. */
@ -784,12 +784,10 @@ static int __devinit hvcs_probe(
return -EFAULT;
}
hvcsd = kmalloc(sizeof(*hvcsd), GFP_KERNEL);
hvcsd = kzalloc(sizeof(*hvcsd), GFP_KERNEL);
if (!hvcsd)
return -ENODEV;
/* hvcsd->tty is zeroed out with the memset */
memset(hvcsd, 0x00, sizeof(*hvcsd));
spin_lock_init(&hvcsd->lock);
/* Automatically incs the refcount the first time */
@ -1094,7 +1092,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
* NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when
* calling this function or you will get deadlock.
*/
struct hvcs_struct *hvcs_get_by_index(int index)
static struct hvcs_struct *hvcs_get_by_index(int index)
{
struct hvcs_struct *hvcsd = NULL;
unsigned long flags;

View file

@ -41,7 +41,7 @@ config HW_RANDOM_AMD
config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on HW_RANDOM && X86 && PCI
depends on HW_RANDOM && X86_32 && PCI
default HW_RANDOM
---help---
This driver provides kernel-side support for the Random Number

View file

@ -98,9 +98,9 @@ struct smm_regs {
unsigned int edi __attribute__ ((packed));
};
static inline char *i8k_get_dmi_data(int field)
static inline const char *i8k_get_dmi_data(int field)
{
char *dmi_data = dmi_get_system_info(field);
const char *dmi_data = dmi_get_system_info(field);
return dmi_data && *dmi_data ? dmi_data : "?";
}

View file

@ -411,8 +411,8 @@ cleanup_module(void)
iiResetDelay( i2BoardPtrTable[i] );
/* free io addresses and Tibet */
release_region( ip2config.addr[i], 8 );
class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
}
/* Disable and remove interrupt handler. */
if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
@ -425,9 +425,7 @@ cleanup_module(void)
printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
}
put_tty_driver(ip2_tty_driver);
if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) ) {
printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err);
}
unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
remove_proc_entry("ip2mem", &proc_root);
// free memory
@ -502,7 +500,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
{
int i, j, box;
int err = 0;
int status = 0;
static int loaded;
i2eBordStrPtr pB = NULL;
int rc = -1;
@ -590,6 +587,8 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
case PCI:
#ifdef CONFIG_PCI
{
int status;
pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i);
if (pci_dev_i != NULL) {
@ -719,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
}
if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
class_device_create(ip2_class, NULL,
device_create(ip2_class, NULL,
MKDEV(IP2_IPL_MAJOR, 4 * i),
NULL, "ipl%d", i);
class_device_create(ip2_class, NULL,
"ipl%d", i);
device_create(ip2_class, NULL,
MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
NULL, "stat%d", i);
"stat%d", i);
for ( box = 0; box < ABS_MAX_BOXES; ++box )
{

View file

@ -865,7 +865,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
entry->dev = dev;
mutex_lock(&reg_list_mutex);
class_device_create(ipmi_class, NULL, dev, device, "ipmi%d", if_num);
device_create(ipmi_class, device, dev, "ipmi%d", if_num);
list_add(&entry->link, &reg_list);
mutex_unlock(&reg_list_mutex);
}
@ -883,7 +883,7 @@ static void ipmi_smi_gone(int if_num)
break;
}
}
class_device_destroy(ipmi_class, dev);
device_destroy(ipmi_class, dev);
mutex_unlock(&reg_list_mutex);
}
@ -938,7 +938,7 @@ static __exit void cleanup_ipmi(void)
mutex_lock(&reg_list_mutex);
list_for_each_entry_safe(entry, entry2, &reg_list, link) {
list_del(&entry->link);
class_device_destroy(ipmi_class, entry->dev);
device_destroy(ipmi_class, entry->dev);
kfree(entry);
}
mutex_unlock(&reg_list_mutex);

View file

@ -2639,10 +2639,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
return -ENODEV;
}
intf = kmalloc(sizeof(*intf), GFP_KERNEL);
intf = kzalloc(sizeof(*intf), GFP_KERNEL);
if (!intf)
return -ENOMEM;
memset(intf, 0, sizeof(*intf));
intf->ipmi_version_major = ipmi_version_major(device_id);
intf->ipmi_version_minor = ipmi_version_minor(device_id);

View file

@ -1965,10 +1965,10 @@ struct dmi_ipmi_data
u8 slave_addr;
};
static int __devinit decode_dmi(struct dmi_header *dm,
static int __devinit decode_dmi(const struct dmi_header *dm,
struct dmi_ipmi_data *dmi)
{
u8 *data = (u8 *)dm;
const u8 *data = (const u8 *)dm;
unsigned long base_addr;
u8 reg_spacing;
u8 len = dm->length;
@ -2050,6 +2050,7 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
info->si_type = SI_BT;
break;
default:
kfree(info);
return;
}
@ -2090,13 +2091,14 @@ static __devinit void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
static void __devinit dmi_find_bmc(void)
{
struct dmi_device *dev = NULL;
const struct dmi_device *dev = NULL;
struct dmi_ipmi_data data;
int rv;
while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) {
memset(&data, 0, sizeof(data));
rv = decode_dmi((struct dmi_header *) dev->device_data, &data);
rv = decode_dmi((const struct dmi_header *) dev->device_data,
&data);
if (!rv)
try_init_dmi(&data);
}
@ -2214,7 +2216,8 @@ static int ipmi_pci_resume(struct pci_dev *pdev)
static struct pci_device_id ipmi_pci_devices[] = {
{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
{ PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
@ -2250,19 +2253,19 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
return ret;
}
regsize = get_property(np, "reg-size", &proplen);
regsize = of_get_property(np, "reg-size", &proplen);
if (regsize && proplen != 4) {
dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
return -EINVAL;
}
regspacing = get_property(np, "reg-spacing", &proplen);
regspacing = of_get_property(np, "reg-spacing", &proplen);
if (regspacing && proplen != 4) {
dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
return -EINVAL;
}
regshift = get_property(np, "reg-shift", &proplen);
regshift = of_get_property(np, "reg-shift", &proplen);
if (regshift && proplen != 4) {
dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
return -EINVAL;
@ -2291,7 +2294,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev,
info->irq = irq_of_parse_and_map(dev->node, 0);
info->dev = &dev->dev;
dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n",
dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n",
info->io.addr_data, info->io.regsize, info->io.regspacing,
info->irq);

View file

@ -4624,9 +4624,8 @@ static int __init istallion_module_init(void)
istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++)
class_device_create(istallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i),
NULL, "staliomem%d", i);
device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
"staliomem%d", i);
return 0;
err_deinit:
@ -4659,8 +4658,7 @@ static void __exit istallion_module_exit(void)
unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
for (j = 0; j < 4; j++)
class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR,
j));
device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
class_destroy(istallion_class);
pci_unregister_driver(&stli_pcidriver);

View file

@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] =
308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
#ifdef CONFIG_MAC_EMUMOUSEBTN
extern int mac_hid_mouse_emulate_buttons(int, int, int);
#endif /* CONFIG_MAC_EMUMOUSEBTN */
#ifdef CONFIG_SPARC
static int sparc_l1_a_state = 0;
extern void sun_do_break(void);

View file

@ -25,7 +25,6 @@
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <linux/delay.h>
#include "lcd.h"

View file

@ -799,8 +799,7 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev,
"lp%d", nr);
device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr);
printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
(port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
@ -971,7 +970,7 @@ static void lp_cleanup_module (void)
if (lp_table[offset].dev == NULL)
continue;
parport_unregister_device(lp_table[offset].dev);
class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
}
class_destroy(lp_class);
}

View file

@ -39,14 +39,14 @@
#else
#define DBG(fmt...)
#endif
int mbcs_major;
static int mbcs_major;
LIST_HEAD(soft_list);
static LIST_HEAD(soft_list);
/*
* file operations
*/
const struct file_operations mbcs_ops = {
static const struct file_operations mbcs_ops = {
.open = mbcs_open,
.llseek = mbcs_sram_llseek,
.read = mbcs_sram_read,
@ -377,7 +377,7 @@ dmaread_exit:
return rv;
}
int mbcs_open(struct inode *ip, struct file *fp)
static int mbcs_open(struct inode *ip, struct file *fp)
{
struct mbcs_soft *soft;
int minor;
@ -394,7 +394,7 @@ int mbcs_open(struct inode *ip, struct file *fp)
return -ENODEV;
}
ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
static ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
{
struct cx_dev *cx_dev = fp->private_data;
struct mbcs_soft *soft = cx_dev->soft;
@ -418,7 +418,7 @@ ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t *
return rv;
}
ssize_t
static ssize_t
mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off)
{
struct cx_dev *cx_dev = fp->private_data;
@ -443,7 +443,7 @@ mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * o
return rv;
}
loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
{
loff_t newpos;
@ -491,7 +491,7 @@ static void mbcs_gscr_pioaddr_set(struct mbcs_soft *soft)
soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START);
}
int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
{
struct cx_dev *cx_dev = fp->private_data;
struct mbcs_soft *soft = cx_dev->soft;
@ -793,7 +793,7 @@ static int mbcs_remove(struct cx_dev *dev)
return 0;
}
const struct cx_device_id __devinitdata mbcs_id_table[] = {
static const struct cx_device_id __devinitdata mbcs_id_table[] = {
{
.part_num = MBCS_PART_NUM,
.mfg_num = MBCS_MFG_NUM,
@ -807,7 +807,7 @@ const struct cx_device_id __devinitdata mbcs_id_table[] = {
MODULE_DEVICE_TABLE(cx, mbcs_id_table);
struct cx_drv mbcs_driver = {
static struct cx_drv mbcs_driver = {
.name = DEVICE_NAME,
.id_table = mbcs_id_table,
.probe = mbcs_probe,
@ -816,12 +816,7 @@ struct cx_drv mbcs_driver = {
static void __exit mbcs_exit(void)
{
int rv;
rv = unregister_chrdev(mbcs_major, DEVICE_NAME);
if (rv < 0)
DBG(KERN_ALERT "Error in unregister_chrdev: %d\n", rv);
unregister_chrdev(mbcs_major, DEVICE_NAME);
cx_driver_unregister(&mbcs_driver);
}

View file

@ -542,12 +542,12 @@ struct mbcs_soft {
struct semaphore algolock;
};
extern int mbcs_open(struct inode *ip, struct file *fp);
extern ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
static int mbcs_open(struct inode *ip, struct file *fp);
static ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
loff_t * off);
extern ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
static ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
loff_t * off);
extern loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
extern int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
static loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
#endif // __MBCS_H__

View file

@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/mmtimer.h>
#include <linux/miscdevice.h>
#include <linux/posix-timers.h>

View file

@ -38,6 +38,7 @@
#include <linux/miscdevice.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/slab.h>
@ -66,7 +67,7 @@
/*
* Page types allocated by the device.
*/
enum {
enum mspec_page_type {
MSPEC_FETCHOP = 1,
MSPEC_CACHED,
MSPEC_UNCACHED
@ -82,15 +83,25 @@ static int is_sn2;
* One of these structures is allocated when an mspec region is mmaped. The
* structure is pointed to by the vma->vm_private_data field in the vma struct.
* This structure is used to record the addresses of the mspec pages.
* This structure is shared by all vma's that are split off from the
* original vma when split_vma()'s are done.
*
* The refcnt is incremented atomically because mm->mmap_sem does not
* protect in fork case where multiple tasks share the vma_data.
*/
struct vma_data {
atomic_t refcnt; /* Number of vmas sharing the data. */
spinlock_t lock; /* Serialize access to the vma. */
spinlock_t lock; /* Serialize access to this structure. */
int count; /* Number of pages allocated. */
int type; /* Type of pages allocated. */
enum mspec_page_type type; /* Type of pages allocated. */
int flags; /* See VMD_xxx below. */
unsigned long vm_start; /* Original (unsplit) base. */
unsigned long vm_end; /* Original (unsplit) end. */
unsigned long maddr[0]; /* Array of MSPEC addresses. */
};
#define VMD_VMALLOCED 0x1 /* vmalloc'd rather than kmalloc'd */
/* used on shub2 to clear FOP cache in the HUB */
static unsigned long scratch_page[MAX_NUMNODES];
#define SH2_AMO_CACHE_ENTRIES 4
@ -128,8 +139,8 @@ mspec_zero_block(unsigned long addr, int len)
* mspec_open
*
* Called when a device mapping is created by a means other than mmap
* (via fork, etc.). Increments the reference count on the underlying
* mspec data so it is not freed prematurely.
* (via fork, munmap, etc.). Increments the reference count on the
* underlying mspec data so it is not freed prematurely.
*/
static void
mspec_open(struct vm_area_struct *vma)
@ -144,43 +155,43 @@ mspec_open(struct vm_area_struct *vma)
* mspec_close
*
* Called when unmapping a device mapping. Frees all mspec pages
* belonging to the vma.
* belonging to all the vma's sharing this vma_data structure.
*/
static void
mspec_close(struct vm_area_struct *vma)
{
struct vma_data *vdata;
int i, pages, result, vdata_size;
int index, last_index;
unsigned long my_page;
vdata = vma->vm_private_data;
if (!atomic_dec_and_test(&vdata->refcnt))
return;
pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
for (i = 0; i < pages; i++) {
if (vdata->maddr[i] == 0)
last_index = (vdata->vm_end - vdata->vm_start) >> PAGE_SHIFT;
for (index = 0; index < last_index; index++) {
if (vdata->maddr[index] == 0)
continue;
/*
* Clear the page before sticking it back
* into the pool.
*/
result = mspec_zero_block(vdata->maddr[i], PAGE_SIZE);
if (!result)
uncached_free_page(vdata->maddr[i]);
my_page = vdata->maddr[index];
vdata->maddr[index] = 0;
if (!mspec_zero_block(my_page, PAGE_SIZE))
uncached_free_page(my_page);
else
printk(KERN_WARNING "mspec_close(): "
"failed to zero page %i\n",
result);
"failed to zero page %ld\n", my_page);
}
if (vdata_size <= PAGE_SIZE)
kfree(vdata);
else
if (vdata->flags & VMD_VMALLOCED)
vfree(vdata);
else
kfree(vdata);
}
/*
* mspec_nopfn
*
@ -194,7 +205,8 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
int index;
struct vma_data *vdata = vma->vm_private_data;
index = (address - vma->vm_start) >> PAGE_SHIFT;
BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
index = (address - vdata->vm_start) >> PAGE_SHIFT;
maddr = (volatile unsigned long) vdata->maddr[index];
if (maddr == 0) {
maddr = uncached_alloc_page(numa_node_id());
@ -236,10 +248,11 @@ static struct vm_operations_struct mspec_vm_ops = {
* underlying pages.
*/
static int
mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
mspec_mmap(struct file *file, struct vm_area_struct *vma,
enum mspec_page_type type)
{
struct vma_data *vdata;
int pages, vdata_size;
int pages, vdata_size, flags = 0;
if (vma->vm_pgoff != 0)
return -EINVAL;
@ -254,12 +267,17 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, int type)
vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
if (vdata_size <= PAGE_SIZE)
vdata = kmalloc(vdata_size, GFP_KERNEL);
else
else {
vdata = vmalloc(vdata_size);
flags = VMD_VMALLOCED;
}
if (!vdata)
return -ENOMEM;
memset(vdata, 0, vdata_size);
vdata->vm_start = vma->vm_start;
vdata->vm_end = vma->vm_end;
vdata->flags = flags;
vdata->type = type;
spin_lock_init(&vdata->lock);
vdata->refcnt = ATOMIC_INIT(1);

View file

@ -1629,7 +1629,7 @@ static int cmm_open(struct inode *inode, struct file *filp)
{
struct cm4000_dev *dev;
struct pcmcia_device *link;
int rc, minor = iminor(inode);
int minor = iminor(inode);
if (minor >= CM4000_MAX_DEV)
return -ENODEV;
@ -1668,7 +1668,6 @@ static int cmm_open(struct inode *inode, struct file *filp)
start_monitor(dev);
link->open = 1; /* only one open per device */
rc = 0;
DEBUGP(2, dev, "<- cmm_open\n");
return nonseekable_open(inode, filp);
@ -1824,7 +1823,7 @@ static int cm4000_resume(struct pcmcia_device *link)
static void cm4000_release(struct pcmcia_device *link)
{
cmm_cm4000_release(link->priv); /* delay release until device closed */
cmm_cm4000_release(link); /* delay release until device closed */
pcmcia_disable_device(link);
}
@ -1864,8 +1863,7 @@ static int cm4000_probe(struct pcmcia_device *link)
return ret;
}
class_device_create(cmm_class, NULL, MKDEV(major, i), NULL,
"cmm%d", i);
device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i);
return 0;
}
@ -1889,7 +1887,7 @@ static void cm4000_detach(struct pcmcia_device *link)
dev_table[devno] = NULL;
kfree(dev);
class_device_destroy(cmm_class, MKDEV(major, devno));
device_destroy(cmm_class, MKDEV(major, devno));
return;
}

View file

@ -599,7 +599,7 @@ cs_release:
static void reader_release(struct pcmcia_device *link)
{
cm4040_reader_release(link->priv);
cm4040_reader_release(link);
pcmcia_disable_device(link);
}
@ -642,8 +642,7 @@ static int reader_probe(struct pcmcia_device *link)
return ret;
}
class_device_create(cmx_class, NULL, MKDEV(major, i), NULL,
"cmx%d", i);
device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i);
return 0;
}
@ -666,7 +665,7 @@ static void reader_detach(struct pcmcia_device *link)
dev_table[devno] = NULL;
kfree(dev);
class_device_destroy(cmx_class, MKDEV(major, devno));
device_destroy(cmx_class, MKDEV(major, devno));
return;
}

View file

@ -540,13 +540,12 @@ static int mgslpc_probe(struct pcmcia_device *link)
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_attach\n");
info = kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
info = kzalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
return -ENOMEM;
}
memset(info, 0, sizeof(MGSLPC_INFO));
info->magic = MGSLPC_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;

440
drivers/char/ps3flash.c Normal file
View file

@ -0,0 +1,440 @@
/*
* PS3 FLASH ROM Storage Driver
*
* Copyright (C) 2007 Sony Computer Entertainment Inc.
* Copyright 2007 Sony Corp.
*
* 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; version 2 of the License.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <asm/lv1call.h>
#include <asm/ps3stor.h>
#define DEVICE_NAME "ps3flash"
#define FLASH_BLOCK_SIZE (256*1024)
struct ps3flash_private {
struct mutex mutex; /* Bounce buffer mutex */
};
static struct ps3_storage_device *ps3flash_dev;
static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev,
u64 lpar, u64 start_sector,
u64 sectors, int write)
{
u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors,
write);
if (res) {
dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%lx\n", __func__,
__LINE__, write ? "write" : "read", res);
return -EIO;
}
return sectors;
}
static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev,
u64 start_sector, u64 sectors,
unsigned int sector_offset)
{
u64 max_sectors, lpar;
max_sectors = dev->bounce_size / dev->blk_size;
if (sectors > max_sectors) {
dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %lu\n",
__func__, __LINE__, max_sectors);
sectors = max_sectors;
}
lpar = dev->bounce_lpar + sector_offset * dev->blk_size;
return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors,
0);
}
static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev,
u64 start_sector)
{
u64 sectors = dev->bounce_size / dev->blk_size;
return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector,
sectors, 1);
}
static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
{
struct ps3_storage_device *dev = ps3flash_dev;
loff_t res;
mutex_lock(&file->f_mapping->host->i_mutex);
switch (origin) {
case 1:
offset += file->f_pos;
break;
case 2:
offset += dev->regions[dev->region_idx].size*dev->blk_size;
break;
}
if (offset < 0) {
res = -EINVAL;
goto out;
}
file->f_pos = offset;
res = file->f_pos;
out:
mutex_unlock(&file->f_mapping->host->i_mutex);
return res;
}
static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
loff_t *pos)
{
struct ps3_storage_device *dev = ps3flash_dev;
struct ps3flash_private *priv = dev->sbd.core.driver_data;
u64 size, start_sector, end_sector, offset;
ssize_t sectors_read;
size_t remaining, n;
dev_dbg(&dev->sbd.core,
"%s:%u: Reading %zu bytes at position %lld to user 0x%p\n",
__func__, __LINE__, count, *pos, buf);
size = dev->regions[dev->region_idx].size*dev->blk_size;
if (*pos >= size || !count)
return 0;
if (*pos + count > size) {
dev_dbg(&dev->sbd.core,
"%s:%u Truncating count from %zu to %llu\n", __func__,
__LINE__, count, size - *pos);
count = size - *pos;
}
start_sector = *pos / dev->blk_size;
offset = *pos % dev->blk_size;
end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
remaining = count;
do {
mutex_lock(&priv->mutex);
sectors_read = ps3flash_read_sectors(dev, start_sector,
end_sector-start_sector,
0);
if (sectors_read < 0) {
mutex_unlock(&priv->mutex);
goto fail;
}
n = min(remaining, sectors_read*dev->blk_size-offset);
dev_dbg(&dev->sbd.core,
"%s:%u: copy %lu bytes from 0x%p to user 0x%p\n",
__func__, __LINE__, n, dev->bounce_buf+offset, buf);
if (copy_to_user(buf, dev->bounce_buf+offset, n)) {
mutex_unlock(&priv->mutex);
sectors_read = -EFAULT;
goto fail;
}
mutex_unlock(&priv->mutex);
*pos += n;
buf += n;
remaining -= n;
start_sector += sectors_read;
offset = 0;
} while (remaining > 0);
return count;
fail:
return sectors_read;
}
static ssize_t ps3flash_write(struct file *file, const char __user *buf,
size_t count, loff_t *pos)
{
struct ps3_storage_device *dev = ps3flash_dev;
struct ps3flash_private *priv = dev->sbd.core.driver_data;
u64 size, chunk_sectors, start_write_sector, end_write_sector,
end_read_sector, start_read_sector, head, tail, offset;
ssize_t res;
size_t remaining, n;
unsigned int sec_off;
dev_dbg(&dev->sbd.core,
"%s:%u: Writing %zu bytes at position %lld from user 0x%p\n",
__func__, __LINE__, count, *pos, buf);
size = dev->regions[dev->region_idx].size*dev->blk_size;
if (*pos >= size || !count)
return 0;
if (*pos + count > size) {
dev_dbg(&dev->sbd.core,
"%s:%u Truncating count from %zu to %llu\n", __func__,
__LINE__, count, size - *pos);
count = size - *pos;
}
chunk_sectors = dev->bounce_size / dev->blk_size;
start_write_sector = *pos / dev->bounce_size * chunk_sectors;
offset = *pos % dev->bounce_size;
end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
chunk_sectors;
end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
start_read_sector = (*pos + count) / dev->blk_size;
/*
* As we have to write in 256 KiB chunks, while we can read in blk_size
* (usually 512 bytes) chunks, we perform the following steps:
* 1. Read from start_write_sector to end_read_sector ("head")
* 2. Read from start_read_sector to end_write_sector ("tail")
* 3. Copy data to buffer
* 4. Write from start_write_sector to end_write_sector
* All of this is complicated by using only one 256 KiB bounce buffer.
*/
head = end_read_sector - start_write_sector;
tail = end_write_sector - start_read_sector;
remaining = count;
do {
mutex_lock(&priv->mutex);
if (end_read_sector >= start_read_sector) {
/* Merge head and tail */
dev_dbg(&dev->sbd.core,
"Merged head and tail: %lu sectors at %lu\n",
chunk_sectors, start_write_sector);
res = ps3flash_read_sectors(dev, start_write_sector,
chunk_sectors, 0);
if (res < 0)
goto fail;
} else {
if (head) {
/* Read head */
dev_dbg(&dev->sbd.core,
"head: %lu sectors at %lu\n", head,
start_write_sector);
res = ps3flash_read_sectors(dev,
start_write_sector,
head, 0);
if (res < 0)
goto fail;
}
if (start_read_sector <
start_write_sector+chunk_sectors) {
/* Read tail */
dev_dbg(&dev->sbd.core,
"tail: %lu sectors at %lu\n", tail,
start_read_sector);
sec_off = start_read_sector-start_write_sector;
res = ps3flash_read_sectors(dev,
start_read_sector,
tail, sec_off);
if (res < 0)
goto fail;
}
}
n = min(remaining, dev->bounce_size-offset);
dev_dbg(&dev->sbd.core,
"%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
__func__, __LINE__, n, buf, dev->bounce_buf+offset);
if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
res = -EFAULT;
goto fail;
}
res = ps3flash_write_chunk(dev, start_write_sector);
if (res < 0)
goto fail;
mutex_unlock(&priv->mutex);
*pos += n;
buf += n;
remaining -= n;
start_write_sector += chunk_sectors;
head = 0;
offset = 0;
} while (remaining > 0);
return count;
fail:
mutex_unlock(&priv->mutex);
return res;
}
static irqreturn_t ps3flash_interrupt(int irq, void *data)
{
struct ps3_storage_device *dev = data;
int res;
u64 tag, status;
res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
if (tag != dev->tag)
dev_err(&dev->sbd.core,
"%s:%u: tag mismatch, got %lx, expected %lx\n",
__func__, __LINE__, tag, dev->tag);
if (res) {
dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%lx\n",
__func__, __LINE__, res, status);
} else {
dev->lv1_status = status;
complete(&dev->done);
}
return IRQ_HANDLED;
}
static const struct file_operations ps3flash_fops = {
.owner = THIS_MODULE,
.llseek = ps3flash_llseek,
.read = ps3flash_read,
.write = ps3flash_write,
};
static struct miscdevice ps3flash_misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &ps3flash_fops,
};
static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
{
struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
struct ps3flash_private *priv;
int error;
unsigned long tmp;
tmp = dev->regions[dev->region_idx].start*dev->blk_size;
if (tmp % FLASH_BLOCK_SIZE) {
dev_err(&dev->sbd.core,
"%s:%u region start %lu is not aligned\n", __func__,
__LINE__, tmp);
return -EINVAL;
}
tmp = dev->regions[dev->region_idx].size*dev->blk_size;
if (tmp % FLASH_BLOCK_SIZE) {
dev_err(&dev->sbd.core,
"%s:%u region size %lu is not aligned\n", __func__,
__LINE__, tmp);
return -EINVAL;
}
/* use static buffer, kmalloc cannot allocate 256 KiB */
if (!ps3flash_bounce_buffer.address)
return -ENODEV;
if (ps3flash_dev) {
dev_err(&dev->sbd.core,
"Only one FLASH device is supported\n");
return -EBUSY;
}
ps3flash_dev = dev;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto fail;
}
dev->sbd.core.driver_data = priv;
mutex_init(&priv->mutex);
dev->bounce_size = ps3flash_bounce_buffer.size;
dev->bounce_buf = ps3flash_bounce_buffer.address;
error = ps3stor_setup(dev, ps3flash_interrupt);
if (error)
goto fail_free_priv;
ps3flash_misc.parent = &dev->sbd.core;
error = misc_register(&ps3flash_misc);
if (error) {
dev_err(&dev->sbd.core, "%s:%u: misc_register failed %d\n",
__func__, __LINE__, error);
goto fail_teardown;
}
dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
__func__, __LINE__, ps3flash_misc.minor);
return 0;
fail_teardown:
ps3stor_teardown(dev);
fail_free_priv:
kfree(priv);
dev->sbd.core.driver_data = NULL;
fail:
ps3flash_dev = NULL;
return error;
}
static int ps3flash_remove(struct ps3_system_bus_device *_dev)
{
struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
misc_deregister(&ps3flash_misc);
ps3stor_teardown(dev);
kfree(dev->sbd.core.driver_data);
dev->sbd.core.driver_data = NULL;
ps3flash_dev = NULL;
return 0;
}
static struct ps3_system_bus_driver ps3flash = {
.match_id = PS3_MATCH_ID_STOR_FLASH,
.core.name = DEVICE_NAME,
.core.owner = THIS_MODULE,
.probe = ps3flash_probe,
.remove = ps3flash_remove,
.shutdown = ps3flash_remove,
};
static int __init ps3flash_init(void)
{
return ps3_system_bus_driver_register(&ps3flash);
}
static void __exit ps3flash_exit(void)
{
ps3_system_bus_driver_unregister(&ps3flash);
}
module_init(ps3flash_init);
module_exit(ps3flash_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PS3 FLASH ROM Storage Driver");
MODULE_AUTHOR("Sony Corporation");
MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH);

View file

@ -248,14 +248,19 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
return -ENOIOCTLCMD;
}
static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
module_param(legacy_count, int, 0);
static void __init legacy_pty_init(void)
{
if (legacy_count <= 0)
return;
pty_driver = alloc_tty_driver(NR_PTYS);
pty_driver = alloc_tty_driver(legacy_count);
if (!pty_driver)
panic("Couldn't allocate pty driver");
pty_slave_driver = alloc_tty_driver(NR_PTYS);
pty_slave_driver = alloc_tty_driver(legacy_count);
if (!pty_slave_driver)
panic("Couldn't allocate pty slave driver");

View file

@ -693,9 +693,14 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
if (r->pull && r->entropy_count < nbytes * 8 &&
r->entropy_count < r->poolinfo->POOLBITS) {
int bytes = max_t(int, random_read_wakeup_thresh / 8,
min_t(int, nbytes, sizeof(tmp)));
/* If we're limited, always leave two wakeup worth's BITS */
int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
int bytes = nbytes;
/* pull at least as many as BYTES as wakeup BITS */
bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
/* but never more than the buffer size */
bytes = min_t(int, bytes, sizeof(tmp));
DEBUG_ENT("going to reseed %s with %d bits "
"(%d of %d requested)\n",
@ -1545,11 +1550,13 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
* As close as possible to RFC 793, which
* suggests using a 250 kHz clock.
* Further reading shows this assumes 2 Mb/s networks.
* For 10 Gb/s Ethernet, a 1 GHz clock is appropriate.
* That's funny, Linux has one built in! Use it!
* (Networks are faster now - should this be increased?)
* For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
* For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
* we also need to limit the resolution so that the u32 seq
* overlaps less than one time per MSL (2 minutes).
* Choosing a clock of 64 ns period is OK. (period of 274 s)
*/
seq += ktime_get_real().tv64;
seq += ktime_get_real().tv64 >> 6;
#if 0
printk("init_seq(%lx, %lx, %d, %d) = %d\n",
saddr, daddr, sport, dport, seq);

View file

@ -255,10 +255,7 @@ static const struct file_operations raw_ctl_fops = {
.owner = THIS_MODULE,
};
static struct cdev raw_cdev = {
.kobj = {.name = "raw", },
.owner = THIS_MODULE,
};
static struct cdev raw_cdev;
static int __init raw_init(void)
{

View file

@ -803,9 +803,7 @@ static void *ckmalloc(int size)
{
void *p;
p = kmalloc(size, GFP_KERNEL);
if (p)
memset(p, 0, size);
p = kzalloc(size, GFP_KERNEL);
return p;
}

View file

@ -556,9 +556,7 @@ struct CmdBlk *RIOGetCmdBlk(void)
{
struct CmdBlk *CmdBlkP;
CmdBlkP = kmalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
if (CmdBlkP)
memset(CmdBlkP, 0, sizeof(struct CmdBlk));
CmdBlkP = kzalloc(sizeof(struct CmdBlk), GFP_ATOMIC);
return CmdBlkP;
}

View file

@ -863,8 +863,7 @@ int RIOReMapPorts(struct rio_info *p, struct Host *HostP, struct Map *HostMapP)
if (PortP->TxRingBuffer)
memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
else if (p->RIOBufferSize) {
PortP->TxRingBuffer = kmalloc(p->RIOBufferSize, GFP_KERNEL);
memset(PortP->TxRingBuffer, 0, p->RIOBufferSize);
PortP->TxRingBuffer = kzalloc(p->RIOBufferSize, GFP_KERNEL);
}
PortP->TxBufferOut = 0;
PortP->TxBufferIn = 0;

View file

@ -635,12 +635,11 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
ctlp = sCtlNumToCtlPtr(board);
/* Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
info = kmalloc(sizeof (struct r_port), GFP_KERNEL);
info = kzalloc(sizeof (struct r_port), GFP_KERNEL);
if (!info) {
printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line);
return;
}
memset(info, 0, sizeof (struct r_port));
info->magic = RPORT_MAGIC;
info->line = line;

View file

@ -82,16 +82,13 @@
#include <asm/uaccess.h>
#include <asm/system.h>
#if defined(__i386__)
#ifdef CONFIG_X86
#include <asm/hpet.h>
#endif
#ifdef __sparc__
#ifdef CONFIG_SPARC32
#include <linux/pci.h>
#include <asm/ebus.h>
#ifdef __sparc_v9__
#include <asm/isa.h>
#endif
static unsigned long rtc_port;
static int rtc_irq = PCI_IRQ_NONE;
@ -930,13 +927,9 @@ static int __init rtc_init(void)
unsigned int year, ctrl;
char *guess = NULL;
#endif
#ifdef __sparc__
#ifdef CONFIG_SPARC32
struct linux_ebus *ebus;
struct linux_ebus_device *edev;
#ifdef __sparc_v9__
struct sparc_isa_bridge *isa_br;
struct sparc_isa_device *isa_dev;
#endif
#else
void *r;
#ifdef RTC_IRQ
@ -944,7 +937,7 @@ static int __init rtc_init(void)
#endif
#endif
#ifdef __sparc__
#ifdef CONFIG_SPARC32
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
if(strcmp(edev->prom_node->name, "rtc") == 0) {
@ -954,17 +947,6 @@ static int __init rtc_init(void)
}
}
}
#ifdef __sparc_v9__
for_each_isa(isa_br) {
for_each_isadev(isa_dev, isa_br) {
if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
rtc_port = isa_dev->resource.start;
rtc_irq = isa_dev->irq;
goto found;
}
}
}
#endif
rtc_has_irq = 0;
printk(KERN_ERR "rtc_init: no PC rtc found\n");
return -EIO;
@ -1020,7 +1002,7 @@ no_irq:
#endif
#endif /* __sparc__ vs. others */
#endif /* CONFIG_SPARC32 vs. others */
if (misc_register(&rtc_dev)) {
#ifdef RTC_IRQ
@ -1105,7 +1087,7 @@ static void __exit rtc_exit (void)
remove_proc_entry ("driver/rtc", NULL);
misc_deregister(&rtc_dev);
#ifdef __sparc__
#ifdef CONFIG_SPARC32
if (rtc_has_irq)
free_irq (rtc_irq, &rtc_port);
#else
@ -1117,7 +1099,7 @@ static void __exit rtc_exit (void)
if (rtc_has_irq)
free_irq (RTC_IRQ, NULL);
#endif
#endif /* __sparc__ */
#endif /* CONFIG_SPARC32 */
}
module_init(rtc_init);

View file

@ -2573,16 +2573,10 @@ static struct tty_driver *serial167_console_device(struct console *c,
return cy_serial_driver;
}
static int __init serial167_console_setup(struct console *co, char *options)
{
return 0;
}
static struct console sercons = {
.name = "ttyS",
.write = serial167_console_write,
.device = serial167_console_device,
.setup = serial167_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};

View file

@ -441,8 +441,7 @@ scdrv_init(void)
continue;
}
class_device_create(snsc_class, NULL, dev, NULL,
"%s", devname);
device_create(snsc_class, NULL, dev, "%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,
0 /*ignored */ ,

View file

@ -875,7 +875,7 @@ found:
#ifdef CONFIG_ACPI
if (sonypi_acpi_device)
acpi_bus_generate_event(sonypi_acpi_device, 1, event);
acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event);
#endif
kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
return 0;
}
const static struct acpi_device_id sonypi_device_ids[] = {
{"SNY6001", 0},
{"", 0},
};
static struct acpi_driver sonypi_acpi_driver = {
.name = "sonypi",
.class = "hkey",
.ids = "SNY6001",
.ids = sonypi_device_ids,
.ops = {
.add = sonypi_acpi_add,
.remove = sonypi_acpi_remove,

View file

@ -4778,9 +4778,8 @@ static int __init stallion_module_init(void)
if (IS_ERR(stallion_class))
printk("STALLION: failed to create class\n");
for (i = 0; i < 4; i++)
class_device_create(stallion_class, NULL,
MKDEV(STL_SIOMEMMAJOR, i), NULL,
"staliomem%d", i);
device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
"staliomem%d", i);
return 0;
err_unrtty:
@ -4795,7 +4794,6 @@ static void __exit stallion_module_exit(void)
{
struct stlbrd *brdp;
unsigned int i, j;
int retval;
pr_debug("cleanup_module()\n");
@ -4817,10 +4815,8 @@ static void __exit stallion_module_exit(void)
}
for (i = 0; i < 4; i++)
class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
if ((retval = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
printk("STALLION: failed to un-register serial memory device, "
"errno=%d\n", -retval);
device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
class_destroy(stallion_class);
pci_unregister_driver(&stl_pcidriver);

View file

@ -4324,13 +4324,12 @@ static struct mgsl_struct* mgsl_allocate_device(void)
{
struct mgsl_struct *info;
info = kmalloc(sizeof(struct mgsl_struct),
info = kzalloc(sizeof(struct mgsl_struct),
GFP_KERNEL);
if (!info) {
printk("Error can't allocate device instance data\n");
} else {
memset(info, 0, sizeof(struct mgsl_struct));
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, mgsl_bh_handler);
info->max_frame_size = 4096;

View file

@ -1,5 +1,5 @@
/*
* $Id: synclink_gt.c,v 4.36 2006/08/28 20:47:14 paulkf Exp $
* $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $
*
* Device driver for Microgate SyncLink GT serial adapters.
*
@ -93,7 +93,7 @@
* module identification
*/
static char *driver_name = "SyncLink GT";
static char *driver_version = "$Revision: 4.36 $";
static char *driver_version = "$Revision: 4.50 $";
static char *tty_driver_name = "synclink_gt";
static char *tty_dev_prefix = "ttySLG";
MODULE_LICENSE("GPL");
@ -477,6 +477,7 @@ static void tx_set_idle(struct slgt_info *info);
static unsigned int free_tbuf_count(struct slgt_info *info);
static void reset_tbufs(struct slgt_info *info);
static void tdma_reset(struct slgt_info *info);
static void tdma_start(struct slgt_info *info);
static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
static void get_signals(struct slgt_info *info);
@ -904,6 +905,8 @@ start:
spin_lock_irqsave(&info->lock,flags);
if (!info->tx_active)
tx_start(info);
else
tdma_start(info);
spin_unlock_irqrestore(&info->lock,flags);
}
@ -1562,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev)
int rc;
unsigned long flags;
if (!try_module_get(THIS_MODULE))
return -EBUSY;
DBGINFO(("%s hdlcdev_open\n", dev->name));
/* generic HDLC layer open processing */
@ -1631,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev)
info->netcount=0;
spin_unlock_irqrestore(&info->netlock, flags);
module_put(THIS_MODULE);
return 0;
}
@ -3414,13 +3421,12 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
{
struct slgt_info *info;
info = kmalloc(sizeof(struct slgt_info), GFP_KERNEL);
info = kzalloc(sizeof(struct slgt_info), GFP_KERNEL);
if (!info) {
DBGERR(("%s device alloc failed adapter=%d port=%d\n",
driver_name, adapter_num, port_num));
} else {
memset(info, 0, sizeof(struct slgt_info));
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
@ -3872,44 +3878,58 @@ static void tx_start(struct slgt_info *info)
slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
/* clear tx idle and underrun status bits */
wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
if (!(rd_reg32(info, TDCSR) & BIT0)) {
/* tx DMA stopped, restart tx DMA */
tdma_reset(info);
/* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
switch(info->params.mode) {
case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
break;
default:
wr_reg32(info, TDCSR, BIT0); /* DMA enable */
}
}
if (info->params.mode == MGSL_MODE_HDLC)
mod_timer(&info->tx_timer, jiffies +
msecs_to_jiffies(5000));
} else {
tdma_reset(info);
/* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
slgt_irq_off(info, IRQ_TXDATA);
slgt_irq_on(info, IRQ_TXIDLE);
/* clear tx idle status bit */
wr_reg16(info, SSR, IRQ_TXIDLE);
/* enable tx DMA */
wr_reg32(info, TDCSR, BIT0);
}
tdma_start(info);
info->tx_active = 1;
}
}
/*
* start transmit DMA if inactive and there are unsent buffers
*/
static void tdma_start(struct slgt_info *info)
{
unsigned int i;
if (rd_reg32(info, TDCSR) & BIT0)
return;
/* transmit DMA inactive, check for unsent buffers */
i = info->tbuf_start;
while (!desc_count(info->tbufs[i])) {
if (++i == info->tbuf_count)
i = 0;
if (i == info->tbuf_current)
return;
}
info->tbuf_start = i;
/* there are unsent buffers, start transmit DMA */
/* reset needed if previous error condition */
tdma_reset(info);
/* set 1st descriptor address */
wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
switch(info->params.mode) {
case MGSL_MODE_RAW:
case MGSL_MODE_MONOSYNC:
case MGSL_MODE_BISYNC:
wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
break;
default:
wr_reg32(info, TDCSR, BIT0); /* DMA enable */
}
}
static void tx_stop(struct slgt_info *info)
{
unsigned short val;
@ -4643,8 +4663,8 @@ static unsigned int free_tbuf_count(struct slgt_info *info)
i=0;
} while (i != info->tbuf_current);
/* last buffer with zero count may be in use, assume it is */
if (count)
/* if tx DMA active, last zero count buffer is in use */
if (count && (rd_reg32(info, TDCSR) & BIT0))
--count;
return count;

View file

@ -3786,14 +3786,13 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
{
SLMP_INFO *info;
info = kmalloc(sizeof(SLMP_INFO),
info = kzalloc(sizeof(SLMP_INFO),
GFP_KERNEL);
if (!info) {
printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n",
__FILE__,__LINE__, adapter_num, port_num);
} else {
memset(info, 0, sizeof(SLMP_INFO));
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;

View file

@ -441,8 +441,8 @@ tipar_register(int nr, struct parport *port)
goto out;
}
class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
TIPAR_MINOR + nr), port->dev, "par%d", nr);
device_create(tipar_class, port->dev, MKDEV(TIPAR_MAJOR,
TIPAR_MINOR + nr), "par%d", nr);
/* Display informations */
pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
@ -534,7 +534,7 @@ tipar_cleanup_module(void)
if (table[i].dev == NULL)
continue;
parport_unregister_device(table[i].dev);
class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
}
class_destroy(tipar_class);

View file

@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd_devel@lists.sourceforge.net>
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org

View file

@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd_devel@lists.sourceforge.net>
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org

View file

@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd_devel@lists.sourceforge.net>
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org

View file

@ -4,7 +4,7 @@
* Authors:
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd_devel@lists.sourceforge.net>
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org

View file

@ -7,6 +7,8 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Access to the eventlog extended by the TCG BIOS of PC platform
*
* This program is free software; you can redistribute it and/or
@ -427,7 +429,7 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
return -ENOMEM;
if ((err = read_log(log)))
return err;
goto out_free;
/* now register seq file */
err = seq_open(file, &tpm_ascii_b_measurments_seqops);
@ -435,10 +437,15 @@ static int tpm_ascii_bios_measurements_open(struct inode *inode,
seq = file->private_data;
seq->private = log;
} else {
kfree(log->bios_event_log);
kfree(log);
goto out_free;
}
out:
return err;
out_free:
kfree(log->bios_event_log);
kfree(log);
goto out;
}
const struct file_operations tpm_ascii_bios_measurements_ops = {
@ -460,7 +467,7 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
return -ENOMEM;
if ((err = read_log(log)))
return err;
goto out_free;
/* now register seq file */
err = seq_open(file, &tpm_binary_b_measurments_seqops);
@ -468,10 +475,15 @@ static int tpm_binary_bios_measurements_open(struct inode *inode,
seq = file->private_data;
seq->private = log;
} else {
kfree(log->bios_event_log);
kfree(log);
goto out_free;
}
out:
return err;
out_free:
kfree(log->bios_event_log);
kfree(log);
goto out;
}
const struct file_operations tpm_binary_bios_measurements_ops = {

View file

@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd_devel@lists.sourceforge.net>
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org

View file

@ -5,6 +5,8 @@
* Leendert van Doorn <leendert@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
* Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
*

View file

@ -368,26 +368,55 @@ static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b)
}
}
/**
* __tty_buffer_flush - flush full tty buffers
* @tty: tty to flush
*
* flush all the buffers containing receive data. Caller must
* hold the buffer lock and must have ensured no parallel flush to
* ldisc is running.
*
* Locking: Caller must hold tty->buf.lock
*/
static void __tty_buffer_flush(struct tty_struct *tty)
{
struct tty_buffer *thead;
while((thead = tty->buf.head) != NULL) {
tty->buf.head = thead->next;
tty_buffer_free(tty, thead);
}
tty->buf.tail = NULL;
}
/**
* tty_buffer_flush - flush full tty buffers
* @tty: tty to flush
*
* flush all the buffers containing receive data
* flush all the buffers containing receive data. If the buffer is
* being processed by flush_to_ldisc then we defer the processing
* to that function
*
* Locking: none
*/
static void tty_buffer_flush(struct tty_struct *tty)
{
struct tty_buffer *thead;
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
while((thead = tty->buf.head) != NULL) {
tty->buf.head = thead->next;
tty_buffer_free(tty, thead);
}
tty->buf.tail = NULL;
/* If the data is being pushed to the tty layer then we can't
process it here. Instead set a flag and the flush_to_ldisc
path will process the flush request before it exits */
if (test_bit(TTY_FLUSHING, &tty->flags)) {
set_bit(TTY_FLUSHPENDING, &tty->flags);
spin_unlock_irqrestore(&tty->buf.lock, flags);
wait_event(tty->read_wait,
test_bit(TTY_FLUSHPENDING, &tty->flags) == 0);
return;
} else
__tty_buffer_flush(tty);
spin_unlock_irqrestore(&tty->buf.lock, flags);
}
@ -2034,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx,
}
if (!*tp_loc) {
tp = (struct ktermios *) kmalloc(sizeof(struct ktermios),
GFP_KERNEL);
tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
if (!tp)
goto free_mem_out;
*tp = driver->init_termios;
@ -2065,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx,
}
if (!*o_tp_loc) {
o_tp = (struct ktermios *)
kmalloc(sizeof(struct ktermios), GFP_KERNEL);
o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
if (!o_tp)
goto free_mem_out;
*o_tp = driver->other->init_termios;
@ -3594,6 +3621,7 @@ static void flush_to_ldisc(struct work_struct *work)
return;
spin_lock_irqsave(&tty->buf.lock, flags);
set_bit(TTY_FLUSHING, &tty->flags); /* So we know a flush is running */
head = tty->buf.head;
if (head != NULL) {
tty->buf.head = NULL;
@ -3607,6 +3635,11 @@ static void flush_to_ldisc(struct work_struct *work)
tty_buffer_free(tty, tbuf);
continue;
}
/* Ldisc or user is trying to flush the buffers
we are feeding to the ldisc, stop feeding the
line discipline as we want to empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags))
break;
if (!tty->receive_room) {
schedule_delayed_work(&tty->buf.work, 1);
break;
@ -3620,8 +3653,17 @@ static void flush_to_ldisc(struct work_struct *work)
disc->receive_buf(tty, char_buf, flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
/* Restore the queue head */
tty->buf.head = head;
}
/* We may have a deferred request to flush the input buffer,
if so pull the chain under the lock and empty the queue */
if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
__tty_buffer_flush(tty);
clear_bit(TTY_FLUSHPENDING, &tty->flags);
wake_up(&tty->read_wait);
}
clear_bit(TTY_FLUSHING, &tty->flags);
spin_unlock_irqrestore(&tty->buf.lock, flags);
tty_ldisc_deref(disc);

View file

@ -795,6 +795,7 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
if (L_ICANON(tty))
retval = inq_canon(tty);
return put_user(retval, (unsigned int __user *) arg);
#ifndef TCGETS2
case TIOCGLCKTRMIOS:
if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
return -EFAULT;
@ -806,6 +807,19 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
return -EFAULT;
return 0;
#else
case TIOCGLCKTRMIOS:
if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
return -EFAULT;
return 0;
case TIOCSLCKTRMIOS:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (user_termios_to_kernel_termios_1(real_tty->termios_locked, (struct termios __user *) arg))
return -EFAULT;
return 0;
#endif
case TIOCPKT:
{

View file

@ -92,47 +92,6 @@ struct viot_devinfo_struct {
#define VIOTAPOP_SETPART 14
#define VIOTAPOP_UNLOAD 15
struct viotapelpevent {
struct HvLpEvent event;
u32 reserved;
u16 version;
u16 sub_type_result;
u16 tape;
u16 flags;
u32 token;
u64 len;
union {
struct {
u32 tape_op;
u32 count;
} op;
struct {
u32 type;
u32 resid;
u32 dsreg;
u32 gstat;
u32 erreg;
u32 file_no;
u32 block_no;
} get_status;
struct {
u32 block_no;
} get_pos;
} u;
};
enum viotapesubtype {
viotapeopen = 0x0001,
viotapeclose = 0x0002,
viotaperead = 0x0003,
viotapewrite = 0x0004,
viotapegetinfo = 0x0005,
viotapeop = 0x0006,
viotapegetpos = 0x0007,
viotapesetpos = 0x0008,
viotapegetstatus = 0x0009
};
enum viotaperc {
viotape_InvalidRange = 0x0601,
viotape_InvalidToken = 0x0602,
@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
#define VIOT_WRITING 2
/* Our info on the tapes */
struct tape_descr {
char rsrcname[10];
char type[4];
char model[3];
};
static struct tape_descr *viotape_unitinfo;
static dma_addr_t viotape_unitinfo_token;
static struct {
const char *rsrcname;
const char *type;
const char *model;
} viotape_unitinfo[VIOTAPE_MAX_TAPE];
static struct mtget viomtget[VIOTAPE_MAX_TAPE];
@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
return -err->errno;
}
/* Get info on all tapes from OS/400 */
static int get_viotape_info(void)
{
HvLpEvent_Rc hvrc;
int i;
size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
struct op_struct *op = get_op_struct();
if (op == NULL)
return -ENOMEM;
viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len,
&viotape_unitinfo_token, GFP_ATOMIC);
if (viotape_unitinfo == NULL) {
free_op_struct(op);
return -ENOMEM;
}
memset(viotape_unitinfo, 0, len);
hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
HvLpEvent_Type_VirtualIo,
viomajorsubtype_tape | viotapegetinfo,
HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
viopath_sourceinst(viopath_hostLp),
viopath_targetinst(viopath_hostLp),
(u64) (unsigned long) op, VIOVERSION << 16,
viotape_unitinfo_token, len, 0, 0);
if (hvrc != HvLpEvent_Rc_Good) {
printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
(int)hvrc);
free_op_struct(op);
return -EIO;
}
wait_for_completion(&op->com);
free_op_struct(op);
for (i = 0;
((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
i++)
viotape_numdev++;
return 0;
}
/* Write */
static ssize_t viotap_write(struct file *file, const char *buf,
size_t count, loff_t * ppos)
@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
op = (struct op_struct *)event->xCorrelationToken;
switch (tapeminor) {
case viotapegetinfo:
case viotapeopen:
case viotapeclose:
op->rc = tevent->sub_type_result;
@ -942,19 +850,31 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
int i = vdev->unit_address;
int j;
struct device_node *node = vdev->dev.archdata.of_node;
if (i >= viotape_numdev)
if (i > VIOTAPE_MAX_TAPE)
return -ENODEV;
if (!node)
return -ENODEV;
if (i >= viotape_numdev)
viotape_numdev = i + 1;
tape_device[i] = &vdev->dev;
viotape_unitinfo[i].rsrcname = of_get_property(node,
"linux,vio_rsrcname", NULL);
viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
NULL);
viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
NULL);
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
"iseries!vt%d", i);
class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
NULL, "iseries!nvt%d", i);
device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
"iseries!nvt%d", i);
printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
"resource %10.10s type %4.4s, model %3.3s\n",
i, viotape_unitinfo[i].rsrcname,
@ -966,8 +886,8 @@ static int viotape_remove(struct vio_dev *vdev)
{
int i = vdev->unit_address;
class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
return 0;
}
@ -1044,11 +964,6 @@ int __init viotap_init(void)
goto unreg_chrdev;
}
if ((ret = get_viotape_info()) < 0) {
printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
goto unreg_class;
}
ret = vio_register_driver(&viotape_driver);
if (ret)
goto unreg_class;
@ -1098,19 +1013,10 @@ static int chg_state(int index, unsigned char new_state, struct file *file)
/* Cleanup */
static void __exit viotap_exit(void)
{
int ret;
remove_proc_entry("iSeries/viotape", NULL);
vio_unregister_driver(&viotape_driver);
class_destroy(tape_class);
ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape");
if (ret < 0)
printk(VIOTAPE_KERN_WARN "Error unregistering device: %d\n",
ret);
if (viotape_unitinfo)
dma_free_coherent(iSeries_vio_dev,
sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
viotape_unitinfo, viotape_unitinfo_token);
unregister_chrdev(VIOTAPE_MAJOR, "viotape");
viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
vio_clearHandler(viomajorsubtype_tape);
clear_op_struct_pool();

View file

@ -1013,18 +1013,10 @@ static struct tty_driver *scc_console_device(struct console *c, int *index)
return scc_driver;
}
static int __init scc_console_setup(struct console *co, char *options)
{
return 0;
}
static struct console sercons = {
.name = "ttyS",
.write = scc_console_write,
.device = scc_console_device,
.setup = scc_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};

View file

@ -770,6 +770,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
/*
* Switching-from response
*/
acquire_console_sem();
if (vc->vt_newvt >= 0) {
if (arg == 0)
/*
@ -784,7 +785,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* complete the switch.
*/
int newvt;
acquire_console_sem();
newvt = vc->vt_newvt;
vc->vt_newvt = -1;
i = vc_allocate(newvt);
@ -798,7 +798,6 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
* other console switches..
*/
complete_change_console(vc_cons[newvt].d);
release_console_sem();
}
}
@ -810,9 +809,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
/*
* If it's just an ACK, ignore it
*/
if (arg != VT_ACKACQ)
if (arg != VT_ACKACQ) {
release_console_sem();
return -EINVAL;
}
}
release_console_sem();
return 0;
@ -1030,7 +1032,7 @@ static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue);
/*
* Sleeps until a vt is activated, or the task is interrupted. Returns
* 0 if activation, -EINTR if interrupted.
* 0 if activation, -EINTR if interrupted by a signal handler.
*/
int vt_waitactive(int vt)
{
@ -1055,7 +1057,7 @@ int vt_waitactive(int vt)
break;
}
release_console_sem();
retval = -EINTR;
retval = -ERESTARTNOHAND;
if (signal_pending(current))
break;
schedule();
@ -1208,15 +1210,18 @@ void change_console(struct vc_data *new_vc)
/*
* Send the signal as privileged - kill_pid() will
* tell us if the process has gone or something else
* is awry
* is awry.
*
* We need to set vt_newvt *before* sending the signal or we
* have a race.
*/
vc->vt_newvt = new_vc->vc_num;
if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
/*
* It worked. Mark the vt to switch to and
* return. The process needs to send us a
* VT_RELDISP ioctl to complete the switch.
*/
vc->vt_newvt = new_vc->vc_num;
return;
}

View file

@ -55,6 +55,8 @@ config SOFT_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called softdog.
# ALPHA Architecture
# ARM Architecture
config AT91RM9200_WATCHDOG
@ -187,15 +189,64 @@ config PNX4008_WATCHDOG
Say N if you are unsure.
config IOP_WATCHDOG
tristate "IOP Watchdog"
depends on PLAT_IOP
select WATCHDOG_NOWAYOUT if (ARCH_IOP32X || ARCH_IOP33X)
help
Say Y here if to include support for the watchdog timer
in the Intel IOP3XX & IOP13XX I/O Processors. This driver can
be built as a module by choosing M. The module will
be called iop_wdt.
Note: The IOP13XX watchdog does an Internal Bus Reset which will
affect both cores and the peripherals of the IOP. The ATU-X
and/or ATUe configuration registers will remain intact, but if
operating as an Root Complex and/or Central Resource, the PCI-X
and/or PCIe busses will also be reset. THIS IS A VERY BIG HAMMER.
config DAVINCI_WATCHDOG
tristate "DaVinci watchdog"
depends on ARCH_DAVINCI
help
Say Y here if to include support for the watchdog timer
in the DaVinci DM644x/DM646x processors.
To compile this driver as a module, choose M here: the
module will be called davinci_wdt.
NOTE: once enabled, this timer cannot be disabled.
Say N if you are unsure.
# ARM26 Architecture
# AVR32 Architecture
config AT32AP700X_WDT
tristate "AT32AP700x watchdog"
depends on WATCHDOG && CPU_AT32AP7000
depends on CPU_AT32AP7000
help
Watchdog timer embedded into AT32AP700x devices. This will reboot
your system when the timeout is reached.
# BLACKFIN Architecture
config BFIN_WDT
tristate "Blackfin On-Chip Watchdog Timer"
depends on BLACKFIN
---help---
If you say yes here you will get support for the Blackfin On-Chip
Watchdog Timer. If you have one of these processors and wish to
have watchdog support enabled, say Y, otherwise say N.
To compile this driver as a module, choose M here: the
module will be called bfin_wdt.
# CRIS Architecture
# FRV Architecture
# H8300 Architecture
# X86 (i386 + ia64 + x86_64) Architecture
config ACQUIRE_WDT
@ -524,7 +575,47 @@ config SBC_EPX_C3_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called sbc_epx_c3.
# PowerPC Architecture
# M32R Architecture
# M68K Architecture
# M68KNOMMU Architecture
# MIPS Architecture
config INDYDOG
tristate "Indy/I2 Hardware Watchdog"
depends on SGI_IP22
help
Hardware driver for the Indy's/I2's watchdog. This is a
watchdog timer that will reboot the machine after a 60 second
timer expired and no process has written to /dev/watchdog during
that time.
config WDT_MTX1
tristate "MTX-1 Hardware Watchdog"
depends on MIPS_MTX1
help
Hardware driver for the MTX-1 boards. This is a watchdog timer that
will reboot the machine after a 100 seconds timer expired.
config WDT_RM9K_GPI
tristate "RM9000/GPI hardware watchdog"
depends on CPU_RM9000
help
Watchdog implementation using the GPI hardware found on
PMC-Sierra RM9xxx CPUs.
To compile this driver as a module, choose M here: the
module will be called rm9k_wdt.
# PARISC Architecture
# POWERPC Architecture
config MPC5200_WDT
tristate "MPC5200 Watchdog Timer"
depends on PPC_MPC52xx
config 8xx_WDT
tristate "MPC8xx Watchdog Timer"
@ -556,34 +647,6 @@ config WATCHDOG_RTAS
To compile this driver as a module, choose M here. The module
will be called wdrtas.
# MIPS Architecture
config INDYDOG
tristate "Indy/I2 Hardware Watchdog"
depends on SGI_IP22
help
Hardware driver for the Indy's/I2's watchdog. This is a
watchdog timer that will reboot the machine after a 60 second
timer expired and no process has written to /dev/watchdog during
that time.
config WDT_MTX1
tristate "MTX-1 Hardware Watchdog"
depends on MIPS_MTX1
help
Hardware driver for the MTX-1 boards. This is a watchdog timer that
will reboot the machine after a 100 seconds timer expired.
config WDT_RM9K_GPI
tristate "RM9000/GPI hardware watchdog"
depends on CPU_RM9000
help
Watchdog implementation using the GPI hardware found on
PMC-Sierra RM9xxx CPUs.
To compile this driver as a module, choose M here: the
module will be called rm9k_wdt.
# S390 Architecture
config ZVM_WATCHDOG
@ -598,11 +661,11 @@ config ZVM_WATCHDOG
To compile this driver as a module, choose M here. The module
will be called vmwatchdog.
# SUPERH Architecture
# SUPERH (sh + sh64) Architecture
config SH_WDT
tristate "SuperH Watchdog"
depends on SUPERH
depends on SUPERH && (CPU_SH3 || CPU_SH4)
help
This driver adds watchdog support for the integrated watchdog in the
SuperH processors. If you have one of these processors and wish
@ -625,6 +688,8 @@ config SH_WDT_MMAP
If you say Y here, user applications will be able to mmap the
WDT/CPG registers.
# SPARC Architecture
# SPARC64 Architecture
config WATCHDOG_CP1XXX
@ -649,6 +714,10 @@ config WATCHDOG_RIO
machines. The watchdog timeout period is normally one minute but
can be changed with a boot-time parameter.
# V850 Architecture
# XTENSA Architecture
#
# ISA-based Watchdog Cards
#

View file

@ -22,6 +22,8 @@ obj-$(CONFIG_WDTPCI) += wdt_pci.o
# USB-based Watchdog Cards
obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o
# ALPHA Architecture
# ARM Architecture
obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o
obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
@ -35,10 +37,23 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o
obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o
obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o
obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o
obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o
# ARM26 Architecture
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
# BLACKFIN Architecture
obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
# CRIS Architecture
# FRV Architecture
# H8300 Architecture
# X86 (i386 + ia64 + x86_64) Architecture
obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o
obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o
@ -65,8 +80,22 @@ obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o
obj-$(CONFIG_MACHZ_WDT) += machzwd.o
obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
# PowerPC Architecture
# M32R Architecture
# M68K Architecture
# M68KNOMMU Architecture
# MIPS Architecture
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
# PARISC Architecture
# POWERPC Architecture
obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o
obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
@ -74,17 +103,18 @@ obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# PPC64 Architecture
obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o
# MIPS Architecture
obj-$(CONFIG_INDYDOG) += indydog.o
obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
# S390 Architecture
# SUPERH Architecture
# SUPERH (sh + sh64) Architecture
obj-$(CONFIG_SH_WDT) += shwdt.o
# SPARC Architecture
# SPARC64 Architecture
# V850 Architecture
# XTENSA Architecture
# Architecture Independant
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o

View file

@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void
*/
static struct pci_device_id ali_pci_tbl[] = {
{ PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,},
{ PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,},
{ 0, },
};
@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void)
struct pci_dev *pdev;
u32 wdog;
/* Check for a 1535 series bridge */
/* Check for a 1533/1535 series bridge */
pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL);
if(pdev == NULL)
if (pdev == NULL)
pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL);
if (pdev == NULL)
return -ENODEV;
pci_dev_put(pdev);

View file

@ -0,0 +1,490 @@
/*
* Blackfin On-Chip Watchdog Driver
* Supports BF53[123]/BF53[467]/BF54[2489]/BF561
*
* Originally based on softdog.c
* Copyright 2006-2007 Analog Devices Inc.
* Copyright 2006-2007 Michele d'Amico
* Copyright 1996 Alan Cox <alan@redhat.com>
*
* Enter bugs at http://blackfin.uclinux.org/
*
* Licensed under the GPL-2 or later.
*/
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/fs.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/blackfin.h>
#include <asm/uaccess.h>
#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
#define stampit() stamp("here i am")
#define WATCHDOG_NAME "bfin-wdt"
#define PFX WATCHDOG_NAME ": "
/* The BF561 has two watchdogs (one per core), but since Linux
* only runs on core A, we'll just work with that one.
*/
#ifdef BF561_FAMILY
# define bfin_read_WDOG_CTL() bfin_read_WDOGA_CTL()
# define bfin_read_WDOG_CNT() bfin_read_WDOGA_CNT()
# define bfin_read_WDOG_STAT() bfin_read_WDOGA_STAT()
# define bfin_write_WDOG_CTL(x) bfin_write_WDOGA_CTL(x)
# define bfin_write_WDOG_CNT(x) bfin_write_WDOGA_CNT(x)
# define bfin_write_WDOG_STAT(x) bfin_write_WDOGA_STAT(x)
#endif
/* Bit in SWRST that indicates boot caused by watchdog */
#define SWRST_RESET_WDOG 0x4000
/* Bit in WDOG_CTL that indicates watchdog has expired (WDR0) */
#define WDOG_EXPIRED 0x8000
/* Masks for WDEV field in WDOG_CTL register */
#define ICTL_RESET 0x0
#define ICTL_NMI 0x2
#define ICTL_GPI 0x4
#define ICTL_NONE 0x6
#define ICTL_MASK 0x6
/* Masks for WDEN field in WDOG_CTL register */
#define WDEN_MASK 0x0FF0
#define WDEN_ENABLE 0x0000
#define WDEN_DISABLE 0x0AD0
/* some defaults */
#define WATCHDOG_TIMEOUT 20
static unsigned int timeout = WATCHDOG_TIMEOUT;
static int nowayout = WATCHDOG_NOWAYOUT;
static struct watchdog_info bfin_wdt_info;
static unsigned long open_check;
static char expect_close;
static spinlock_t bfin_wdt_spinlock = SPIN_LOCK_UNLOCKED;
/**
* bfin_wdt_keepalive - Keep the Userspace Watchdog Alive
*
* The Userspace watchdog got a KeepAlive: schedule the next timeout.
*/
static int bfin_wdt_keepalive(void)
{
stampit();
bfin_write_WDOG_STAT(0);
return 0;
}
/**
* bfin_wdt_stop - Stop the Watchdog
*
* Stops the on-chip watchdog.
*/
static int bfin_wdt_stop(void)
{
stampit();
bfin_write_WDOG_CTL(WDEN_DISABLE);
return 0;
}
/**
* bfin_wdt_start - Start the Watchdog
*
* Starts the on-chip watchdog. Automatically loads WDOG_CNT
* into WDOG_STAT for us.
*/
static int bfin_wdt_start(void)
{
stampit();
bfin_write_WDOG_CTL(WDEN_ENABLE | ICTL_RESET);
return 0;
}
/**
* bfin_wdt_running - Check Watchdog status
*
* See if the watchdog is running.
*/
static int bfin_wdt_running(void)
{
stampit();
return ((bfin_read_WDOG_CTL() & WDEN_MASK) != WDEN_DISABLE);
}
/**
* bfin_wdt_set_timeout - Set the Userspace Watchdog timeout
* @t: new timeout value (in seconds)
*
* Translate the specified timeout in seconds into System Clock
* terms which is what the on-chip Watchdog requires.
*/
static int bfin_wdt_set_timeout(unsigned long t)
{
u32 cnt;
unsigned long flags;
stampit();
cnt = t * get_sclk();
if (cnt < get_sclk()) {
printk(KERN_WARNING PFX "timeout value is too large\n");
return -EINVAL;
}
spin_lock_irqsave(&bfin_wdt_spinlock, flags);
{
int run = bfin_wdt_running();
bfin_wdt_stop();
bfin_write_WDOG_CNT(cnt);
if (run) bfin_wdt_start();
}
spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
timeout = t;
return 0;
}
/**
* bfin_wdt_open - Open the Device
* @inode: inode of device
* @file: file handle of device
*
* Watchdog device is opened and started.
*/
static int bfin_wdt_open(struct inode *inode, struct file *file)
{
stampit();
if (test_and_set_bit(0, &open_check))
return -EBUSY;
if (nowayout)
__module_get(THIS_MODULE);
bfin_wdt_keepalive();
bfin_wdt_start();
return nonseekable_open(inode, file);
}
/**
* bfin_wdt_close - Close the Device
* @inode: inode of device
* @file: file handle of device
*
* Watchdog device is closed and stopped.
*/
static int bfin_wdt_release(struct inode *inode, struct file *file)
{
stampit();
if (expect_close == 42) {
bfin_wdt_stop();
} else {
printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
bfin_wdt_keepalive();
}
expect_close = 0;
clear_bit(0, &open_check);
return 0;
}
/**
* bfin_wdt_write - Write to Device
* @file: file handle of device
* @buf: buffer to write
* @count: length of buffer
* @ppos: offset
*
* Pings the watchdog on write.
*/
static ssize_t bfin_wdt_write(struct file *file, const char __user *data,
size_t len, loff_t *ppos)
{
stampit();
if (len) {
if (!nowayout) {
size_t i;
/* In case it was set long ago */
expect_close = 0;
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
expect_close = 42;
}
}
bfin_wdt_keepalive();
}
return len;
}
/**
* bfin_wdt_ioctl - Query Device
* @inode: inode of device
* @file: file handle of device
* @cmd: watchdog command
* @arg: argument
*
* Query basic information from the device or ping it, as outlined by the
* watchdog API.
*/
static int bfin_wdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
int __user *p = argp;
stampit();
switch (cmd) {
default:
return -ENOTTY;
case WDIOC_GETSUPPORT:
if (copy_to_user(argp, &bfin_wdt_info, sizeof(bfin_wdt_info)))
return -EFAULT;
else
return 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(!!(_bfin_swrst & SWRST_RESET_WDOG), p);
case WDIOC_KEEPALIVE:
bfin_wdt_keepalive();
return 0;
case WDIOC_SETTIMEOUT: {
int new_timeout;
if (get_user(new_timeout, p))
return -EFAULT;
if (bfin_wdt_set_timeout(new_timeout))
return -EINVAL;
}
/* Fall */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
case WDIOC_SETOPTIONS: {
unsigned long flags;
int options, ret = -EINVAL;
if (get_user(options, p))
return -EFAULT;
spin_lock_irqsave(&bfin_wdt_spinlock, flags);
if (options & WDIOS_DISABLECARD) {
bfin_wdt_stop();
ret = 0;
}
if (options & WDIOS_ENABLECARD) {
bfin_wdt_start();
ret = 0;
}
spin_unlock_irqrestore(&bfin_wdt_spinlock, flags);
return ret;
}
}
}
/**
* bfin_wdt_notify_sys - Notifier Handler
* @this: notifier block
* @code: notifier event
* @unused: unused
*
* Handles specific events, such as turning off the watchdog during a
* shutdown event.
*/
static int bfin_wdt_notify_sys(struct notifier_block *this, unsigned long code,
void *unused)
{
stampit();
if (code == SYS_DOWN || code == SYS_HALT)
bfin_wdt_stop();
return NOTIFY_DONE;
}
#ifdef CONFIG_PM
static int state_before_suspend;
/**
* bfin_wdt_suspend - suspend the watchdog
* @pdev: device being suspended
* @state: requested suspend state
*
* Remember if the watchdog was running and stop it.
* TODO: is this even right? Doesn't seem to be any
* standard in the watchdog world ...
*/
static int bfin_wdt_suspend(struct platform_device *pdev, pm_message_t state)
{
stampit();
state_before_suspend = bfin_wdt_running();
bfin_wdt_stop();
return 0;
}
/**
* bfin_wdt_resume - resume the watchdog
* @pdev: device being resumed
*
* If the watchdog was running, turn it back on.
*/
static int bfin_wdt_resume(struct platform_device *pdev)
{
stampit();
if (state_before_suspend) {
bfin_wdt_set_timeout(timeout);
bfin_wdt_start();
}
return 0;
}
#else
# define bfin_wdt_suspend NULL
# define bfin_wdt_resume NULL
#endif
static struct platform_device bfin_wdt_device = {
.name = WATCHDOG_NAME,
.id = -1,
};
static struct platform_driver bfin_wdt_driver = {
.driver = {
.name = WATCHDOG_NAME,
.owner = THIS_MODULE,
},
.suspend = bfin_wdt_suspend,
.resume = bfin_wdt_resume,
};
static struct file_operations bfin_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = bfin_wdt_write,
.ioctl = bfin_wdt_ioctl,
.open = bfin_wdt_open,
.release = bfin_wdt_release,
};
static struct miscdevice bfin_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &bfin_wdt_fops,
};
static struct watchdog_info bfin_wdt_info = {
.identity = "Blackfin Watchdog",
.options = WDIOF_SETTIMEOUT |
WDIOF_KEEPALIVEPING |
WDIOF_MAGICCLOSE,
};
static struct notifier_block bfin_wdt_notifier = {
.notifier_call = bfin_wdt_notify_sys,
};
/**
* bfin_wdt_init - Initialize module
*
* Registers the device and notifier handler. Actual device
* initialization is handled by bfin_wdt_open().
*/
static int __init bfin_wdt_init(void)
{
int ret;
stampit();
/* Check that the timeout value is within range */
if (bfin_wdt_set_timeout(timeout))
return -EINVAL;
/* Since this is an on-chip device and needs no board-specific
* resources, we'll handle all the platform device stuff here.
*/
ret = platform_device_register(&bfin_wdt_device);
if (ret)
return ret;
ret = platform_driver_probe(&bfin_wdt_driver, NULL);
if (ret)
return ret;
ret = register_reboot_notifier(&bfin_wdt_notifier);
if (ret) {
printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n", ret);
return ret;
}
ret = misc_register(&bfin_wdt_miscdev);
if (ret) {
printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
WATCHDOG_MINOR, ret);
unregister_reboot_notifier(&bfin_wdt_notifier);
return ret;
}
printk(KERN_INFO PFX "initialized: timeout=%d sec (nowayout=%d)\n",
timeout, nowayout);
return 0;
}
/**
* bfin_wdt_exit - Deinitialize module
*
* Unregisters the device and notifier handler. Actual device
* deinitialization is handled by bfin_wdt_close().
*/
static void __exit bfin_wdt_exit(void)
{
misc_deregister(&bfin_wdt_miscdev);
unregister_reboot_notifier(&bfin_wdt_notifier);
}
module_init(bfin_wdt_init);
module_exit(bfin_wdt_exit);
MODULE_AUTHOR("Michele d'Amico, Mike Frysinger <vapier@gentoo.org>");
MODULE_DESCRIPTION("Blackfin Watchdog Device Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
module_param(timeout, uint, 0);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=((2^32)/SCLK), default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");

View file

@ -144,7 +144,7 @@ static int booke_wdt_open (struct inode *inode, struct file *file)
booke_wdt_period);
}
return 0;
return nonseekable_open(inode, file);
}
static const struct file_operations booke_wdt_fops = {

View file

@ -162,6 +162,10 @@ static int cpu5wdt_ioctl(struct inode *inode, struct file *file, unsigned int cm
if ( copy_to_user(argp, &value, sizeof(int)) )
return -EFAULT;
break;
case WDIOC_GETBOOTSTATUS:
if ( copy_to_user(argp, &value, sizeof(int)) )
return -EFAULT;
break;
case WDIOC_GETSUPPORT:
if ( copy_to_user(argp, &ident, sizeof(ident)) )
return -EFAULT;

View file

@ -0,0 +1,281 @@
/*
* drivers/char/watchdog/davinci_wdt.c
*
* Watchdog driver for DaVinci DM644x/DM646x processors
*
* Copyright (C) 2006 Texas Instruments.
*
* 2007 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define MODULE_NAME "DAVINCI-WDT: "
#define DEFAULT_HEARTBEAT 60
#define MAX_HEARTBEAT 600 /* really the max margin is 264/27MHz*/
/* Timer register set definition */
#define PID12 (0x0)
#define EMUMGT (0x4)
#define TIM12 (0x10)
#define TIM34 (0x14)
#define PRD12 (0x18)
#define PRD34 (0x1C)
#define TCR (0x20)
#define TGCR (0x24)
#define WDTCR (0x28)
/* TCR bit definitions */
#define ENAMODE12_DISABLED (0 << 6)
#define ENAMODE12_ONESHOT (1 << 6)
#define ENAMODE12_PERIODIC (2 << 6)
/* TGCR bit definitions */
#define TIM12RS_UNRESET (1 << 0)
#define TIM34RS_UNRESET (1 << 1)
#define TIMMODE_64BIT_WDOG (2 << 2)
/* WDTCR bit definitions */
#define WDEN (1 << 14)
#define WDFLAG (1 << 15)
#define WDKEY_SEQ0 (0xa5c6 << 16)
#define WDKEY_SEQ1 (0xda7e << 16)
static int heartbeat = DEFAULT_HEARTBEAT;
static spinlock_t io_lock;
static unsigned long wdt_status;
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
#define WDT_REGION_INITED 2
#define WDT_DEVICE_INITED 3
static struct resource *wdt_mem;
static void __iomem *wdt_base;
static void wdt_service(void)
{
spin_lock(&io_lock);
/* put watchdog in service state */
davinci_writel(WDKEY_SEQ0, wdt_base + WDTCR);
/* put watchdog in active state */
davinci_writel(WDKEY_SEQ1, wdt_base + WDTCR);
spin_unlock(&io_lock);
}
static void wdt_enable(void)
{
u32 tgcr;
u32 timer_margin;
spin_lock(&io_lock);
/* disable, internal clock source */
davinci_writel(0, wdt_base + TCR);
/* reset timer, set mode to 64-bit watchdog, and unreset */
davinci_writel(0, wdt_base + TGCR);
tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
davinci_writel(tgcr, wdt_base + TGCR);
/* clear counter regs */
davinci_writel(0, wdt_base + TIM12);
davinci_writel(0, wdt_base + TIM34);
/* set timeout period */
timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) & 0xffffffff);
davinci_writel(timer_margin, wdt_base + PRD12);
timer_margin = (((u64)heartbeat * CLOCK_TICK_RATE) >> 32);
davinci_writel(timer_margin, wdt_base + PRD34);
/* enable run continuously */
davinci_writel(ENAMODE12_PERIODIC, wdt_base + TCR);
/* Once the WDT is in pre-active state write to
* TIM12, TIM34, PRD12, PRD34, TCR, TGCR, WDTCR are
* write protected (except for the WDKEY field)
*/
/* put watchdog in pre-active state */
davinci_writel(WDKEY_SEQ0 | WDEN, wdt_base + WDTCR);
/* put watchdog in active state */
davinci_writel(WDKEY_SEQ1 | WDEN, wdt_base + WDTCR);
spin_unlock(&io_lock);
}
static int davinci_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(WDT_IN_USE, &wdt_status))
return -EBUSY;
wdt_enable();
return nonseekable_open(inode, file);
}
static ssize_t
davinci_wdt_write(struct file *file, const char *data, size_t len,
loff_t *ppos)
{
if (len)
wdt_service();
return len;
}
static struct watchdog_info ident = {
.options = WDIOF_KEEPALIVEPING,
.identity = "DaVinci Watchdog",
};
static int
davinci_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
int ret = -ENOTTY;
switch (cmd) {
case WDIOC_GETSUPPORT:
ret = copy_to_user((struct watchdog_info *)arg, &ident,
sizeof(ident)) ? -EFAULT : 0;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
ret = put_user(0, (int *)arg);
break;
case WDIOC_GETTIMEOUT:
ret = put_user(heartbeat, (int *)arg);
break;
case WDIOC_KEEPALIVE:
wdt_service();
ret = 0;
break;
}
return ret;
}
static int davinci_wdt_release(struct inode *inode, struct file *file)
{
wdt_service();
clear_bit(WDT_IN_USE, &wdt_status);
return 0;
}
static const struct file_operations davinci_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = davinci_wdt_write,
.ioctl = davinci_wdt_ioctl,
.open = davinci_wdt_open,
.release = davinci_wdt_release,
};
static struct miscdevice davinci_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &davinci_wdt_fops,
};
static int davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
struct resource *res;
spin_lock_init(&io_lock);
if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
heartbeat = DEFAULT_HEARTBEAT;
printk(KERN_INFO MODULE_NAME
"DaVinci Watchdog Timer: heartbeat %d sec\n", heartbeat);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
printk(KERN_INFO MODULE_NAME
"failed to get memory region resource\n");
return -ENOENT;
}
size = res->end - res->start + 1;
wdt_mem = request_mem_region(res->start, size, pdev->name);
if (wdt_mem == NULL) {
printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
return -ENOENT;
}
wdt_base = (void __iomem *)(res->start);
ret = misc_register(&davinci_wdt_miscdev);
if (ret < 0) {
printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
release_resource(wdt_mem);
kfree(wdt_mem);
} else {
set_bit(WDT_DEVICE_INITED, &wdt_status);
}
return ret;
}
static int davinci_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&davinci_wdt_miscdev);
if (wdt_mem) {
release_resource(wdt_mem);
kfree(wdt_mem);
wdt_mem = NULL;
}
return 0;
}
static struct platform_driver platform_wdt_driver = {
.driver = {
.name = "watchdog",
},
.probe = davinci_wdt_probe,
.remove = davinci_wdt_remove,
};
static int __init davinci_wdt_init(void)
{
return platform_driver_register(&platform_wdt_driver);
}
static void __exit davinci_wdt_exit(void)
{
return platform_driver_unregister(&platform_wdt_driver);
}
module_init(davinci_wdt_init);
module_exit(davinci_wdt_exit);
MODULE_AUTHOR("Texas Instruments");
MODULE_DESCRIPTION("DaVinci Watchdog Driver");
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat,
"Watchdog heartbeat period in seconds from 1 to "
__MODULE_STRING(MAX_HEARTBEAT) ", default "
__MODULE_STRING(DEFAULT_HEARTBEAT));
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

View file

@ -1,5 +1,5 @@
/*
* Eurotech CPU-1220/1410 on board WDT driver
* Eurotech CPU-1220/1410/1420 on board WDT driver
*
* (c) Copyright 2001 Ascensit <support@ascensit.com>
* (c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
@ -24,6 +24,9 @@
*/
/* Changelog:
*
* 2001 - Rodolfo Giometti
* Initial release
*
* 2002/04/25 - Rob Radez
* clean up #includes
@ -33,13 +36,15 @@
* add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
* add expect_close support
*
* 2001 - Rodolfo Giometti
* Initial release
*
* 2002.05.30 - Joel Becker <joel.becker@oracle.com>
* Added Matt Domsch's nowayout module option.
*/
/*
* The eurotech CPU-1220/1410/1420's watchdog is a part
* of the on-board SUPER I/O device SMSC FDC 37B782.
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>

View file

@ -39,7 +39,12 @@
* 82801HR (ICH8R) : document number 313056-002, 313057-004,
* 82801HH (ICH8DH) : document number 313056-002, 313057-004,
* 82801HO (ICH8DO) : document number 313056-002, 313057-004,
* 6300ESB (6300ESB) : document number 300641-003
* 82801IB (ICH9) : document number 316972-001, 316973-001,
* 82801IR (ICH9R) : document number 316972-001, 316973-001,
* 82801IH (ICH9DH) : document number 316972-001, 316973-001,
* 6300ESB (6300ESB) : document number 300641-003, 300884-010,
* 631xESB (631xESB) : document number 313082-001, 313075-005,
* 632xESB (632xESB) : document number 313082-001, 313075-005
*/
/*
@ -48,8 +53,8 @@
/* Module and version information */
#define DRV_NAME "iTCO_wdt"
#define DRV_VERSION "1.01"
#define DRV_RELDATE "21-Jan-2007"
#define DRV_VERSION "1.02"
#define DRV_RELDATE "26-Jul-2007"
#define PFX DRV_NAME ": "
/* Includes */
@ -92,6 +97,10 @@ enum iTCO_chipsets {
TCO_ICH8, /* ICH8 & ICH8R */
TCO_ICH8DH, /* ICH8DH */
TCO_ICH8DO, /* ICH8DO */
TCO_ICH9, /* ICH9 */
TCO_ICH9R, /* ICH9R */
TCO_ICH9DH, /* ICH9DH */
TCO_631XESB, /* 631xESB/632xESB */
};
static struct {
@ -118,6 +127,10 @@ static struct {
{"ICH8 or ICH8R", 2},
{"ICH8DH", 2},
{"ICH8DO", 2},
{"ICH9", 2},
{"ICH9R", 2},
{"ICH9DH", 2},
{"631xESB/632xESB", 2},
{NULL,0}
};
@ -148,6 +161,25 @@ static struct pci_device_id iTCO_wdt_pci_tbl[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DH },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH8DO },
{ PCI_VENDOR_ID_INTEL, 0x2918, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9 },
{ PCI_VENDOR_ID_INTEL, 0x2916, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9R },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_ICH9DH },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ PCI_VENDOR_ID_INTEL, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TCO_631XESB },
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE (pci, iTCO_wdt_pci_tbl);

View file

@ -0,0 +1,262 @@
/*
* drivers/char/watchdog/iop_wdt.c
*
* WDT driver for Intel I/O Processors
* Copyright (C) 2005, Intel Corporation.
*
* Based on ixp4xx driver, Copyright 2004 (c) MontaVista, Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
* Curt E Bruns <curt.e.bruns@intel.com>
* Peter Milne <peter.milne@d-tacq.com>
* Dan Williams <dan.j.williams@intel.com>
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/uaccess.h>
#include <asm/hardware.h>
static int nowayout = WATCHDOG_NOWAYOUT;
static unsigned long wdt_status;
static unsigned long boot_status;
#define WDT_IN_USE 0
#define WDT_OK_TO_CLOSE 1
#define WDT_ENABLED 2
static unsigned long iop_watchdog_timeout(void)
{
return (0xffffffffUL / get_iop_tick_rate());
}
/**
* wdt_supports_disable - determine if we are accessing a iop13xx watchdog
* or iop3xx by whether it has a disable command
*/
static int wdt_supports_disable(void)
{
int can_disable;
if (IOP_WDTCR_EN_ARM != IOP_WDTCR_DIS_ARM)
can_disable = 1;
else
can_disable = 0;
return can_disable;
}
static void wdt_enable(void)
{
/* Arm and enable the Timer to starting counting down from 0xFFFF.FFFF
* Takes approx. 10.7s to timeout
*/
write_wdtcr(IOP_WDTCR_EN_ARM);
write_wdtcr(IOP_WDTCR_EN);
}
/* returns 0 if the timer was successfully disabled */
static int wdt_disable(void)
{
/* Stop Counting */
if (wdt_supports_disable()) {
write_wdtcr(IOP_WDTCR_DIS_ARM);
write_wdtcr(IOP_WDTCR_DIS);
clear_bit(WDT_ENABLED, &wdt_status);
printk(KERN_INFO "WATCHDOG: Disabled\n");
return 0;
} else
return 1;
}
static int iop_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(WDT_IN_USE, &wdt_status))
return -EBUSY;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
wdt_enable();
set_bit(WDT_ENABLED, &wdt_status);
return nonseekable_open(inode, file);
}
static ssize_t
iop_wdt_write(struct file *file, const char *data, size_t len,
loff_t *ppos)
{
if (len) {
if (!nowayout) {
size_t i;
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
for (i = 0; i != len; i++) {
char c;
if (get_user(c, data + i))
return -EFAULT;
if (c == 'V')
set_bit(WDT_OK_TO_CLOSE, &wdt_status);
}
}
wdt_enable();
}
return len;
}
static struct watchdog_info ident = {
.options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING,
.identity = "iop watchdog",
};
static int
iop_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
int options;
int ret = -ENOTTY;
switch (cmd) {
case WDIOC_GETSUPPORT:
if (copy_to_user
((struct watchdog_info *)arg, &ident, sizeof ident))
ret = -EFAULT;
else
ret = 0;
break;
case WDIOC_GETSTATUS:
ret = put_user(0, (int *)arg);
break;
case WDIOC_GETBOOTSTATUS:
ret = put_user(boot_status, (int *)arg);
break;
case WDIOC_GETTIMEOUT:
ret = put_user(iop_watchdog_timeout(), (int *)arg);
break;
case WDIOC_KEEPALIVE:
wdt_enable();
ret = 0;
break;
case WDIOC_SETOPTIONS:
if (get_user(options, (int *)arg))
return -EFAULT;
if (options & WDIOS_DISABLECARD) {
if (!nowayout) {
if (wdt_disable() == 0) {
set_bit(WDT_OK_TO_CLOSE, &wdt_status);
ret = 0;
} else
ret = -ENXIO;
} else
ret = 0;
}
if (options & WDIOS_ENABLECARD) {
wdt_enable();
ret = 0;
}
break;
}
return ret;
}
static int iop_wdt_release(struct inode *inode, struct file *file)
{
int state = 1;
if (test_bit(WDT_OK_TO_CLOSE, &wdt_status))
if (test_bit(WDT_ENABLED, &wdt_status))
state = wdt_disable();
/* if the timer is not disbaled reload and notify that we are still
* going down
*/
if (state != 0) {
wdt_enable();
printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - "
"reset in %lu seconds\n", iop_watchdog_timeout());
}
clear_bit(WDT_IN_USE, &wdt_status);
clear_bit(WDT_OK_TO_CLOSE, &wdt_status);
return 0;
}
static const struct file_operations iop_wdt_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.write = iop_wdt_write,
.ioctl = iop_wdt_ioctl,
.open = iop_wdt_open,
.release = iop_wdt_release,
};
static struct miscdevice iop_wdt_miscdev = {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &iop_wdt_fops,
};
static int __init iop_wdt_init(void)
{
int ret;
ret = misc_register(&iop_wdt_miscdev);
if (ret == 0)
printk("iop watchdog timer: timeout %lu sec\n",
iop_watchdog_timeout());
/* check if the reset was caused by the watchdog timer */
boot_status = (read_rcsr() & IOP_RCSR_WDT) ? WDIOF_CARDRESET : 0;
/* Configure Watchdog Timeout to cause an Internal Bus (IB) Reset
* NOTE: An IB Reset will Reset both cores in the IOP342
*/
write_wdtsr(IOP13XX_WDTCR_IB_RESET);
return ret;
}
static void __exit iop_wdt_exit(void)
{
misc_deregister(&iop_wdt_miscdev);
}
module_init(iop_wdt_init);
module_exit(iop_wdt_exit);
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started");
MODULE_AUTHOR("Curt E Bruns <curt.e.bruns@intel.com>");
MODULE_DESCRIPTION("iop watchdog timer driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

View file

@ -321,6 +321,7 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:

View file

@ -215,6 +215,11 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
return -EFAULT;
}
break;
case WDIOC_GETBOOTSTATUS:
if (copy_to_user(p, &status, sizeof(int))) {
return -EFAULT;
}
break;
case WDIOC_GETSUPPORT:
if (copy_to_user(argp, &ident, sizeof(ident))) {
return -EFAULT;

View file

@ -0,0 +1,286 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <asm/of_platform.h>
#include <asm/uaccess.h>
#include <asm/mpc52xx.h>
#define GPT_MODE_WDT (1<<15)
#define GPT_MODE_CE (1<<12)
#define GPT_MODE_MS_TIMER (0x4)
struct mpc5200_wdt {
unsigned count; /* timer ticks before watchdog kicks in */
long ipb_freq;
struct miscdevice miscdev;
struct resource mem;
struct mpc52xx_gpt __iomem *regs;
spinlock_t io_lock;
};
/* is_active stores wether or not the /dev/watchdog device is opened */
static unsigned long is_active;
/* misc devices don't provide a way, to get back to 'dev' or 'miscdev' from
* file operations, which sucks. But there can be max 1 watchdog anyway, so...
*/
static struct mpc5200_wdt *wdt_global;
/* helper to calculate timeout in timer counts */
static void mpc5200_wdt_set_timeout(struct mpc5200_wdt *wdt, int timeout)
{
/* use biggest prescaler of 64k */
wdt->count = (wdt->ipb_freq + 0xffff) / 0x10000 * timeout;
if (wdt->count > 0xffff)
wdt->count = 0xffff;
}
/* return timeout in seconds (calculated from timer count) */
static int mpc5200_wdt_get_timeout(struct mpc5200_wdt *wdt)
{
return wdt->count * 0x10000 / wdt->ipb_freq;
}
/* watchdog operations */
static int mpc5200_wdt_start(struct mpc5200_wdt *wdt)
{
spin_lock(&wdt->io_lock);
/* disable */
out_be32(&wdt->regs->mode, 0);
/* set timeout, with maximum prescaler */
out_be32(&wdt->regs->count, 0x0 | wdt->count);
/* enable watchdog */
out_be32(&wdt->regs->mode, GPT_MODE_CE | GPT_MODE_WDT | GPT_MODE_MS_TIMER);
spin_unlock(&wdt->io_lock);
return 0;
}
static int mpc5200_wdt_ping(struct mpc5200_wdt *wdt)
{
spin_lock(&wdt->io_lock);
/* writing A5 to OCPW resets the watchdog */
out_be32(&wdt->regs->mode, 0xA5000000 | (0xffffff & in_be32(&wdt->regs->mode)));
spin_unlock(&wdt->io_lock);
return 0;
}
static int mpc5200_wdt_stop(struct mpc5200_wdt *wdt)
{
spin_lock(&wdt->io_lock);
/* disable */
out_be32(&wdt->regs->mode, 0);
spin_unlock(&wdt->io_lock);
return 0;
}
/* file operations */
static ssize_t mpc5200_wdt_write(struct file *file, const char *data,
size_t len, loff_t *ppos)
{
struct mpc5200_wdt *wdt = file->private_data;
mpc5200_wdt_ping(wdt);
return 0;
}
static struct watchdog_info mpc5200_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = "mpc5200 watchdog on GPT0",
};
static int mpc5200_wdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct mpc5200_wdt *wdt = file->private_data;
int __user *data = (int __user *)arg;
int timeout;
int ret = 0;
switch (cmd) {
case WDIOC_GETSUPPORT:
ret = copy_to_user(data, &mpc5200_wdt_info,
sizeof(mpc5200_wdt_info));
if (ret)
ret = -EFAULT;
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
ret = put_user(0, data);
break;
case WDIOC_KEEPALIVE:
mpc5200_wdt_ping(wdt);
break;
case WDIOC_SETTIMEOUT:
ret = get_user(timeout, data);
if (ret)
break;
mpc5200_wdt_set_timeout(wdt, timeout);
mpc5200_wdt_start(wdt);
/* fall through and return the timeout */
case WDIOC_GETTIMEOUT:
timeout = mpc5200_wdt_get_timeout(wdt);
ret = put_user(timeout, data);
break;
default:
ret = -ENOTTY;
}
return ret;
}
static int mpc5200_wdt_open(struct inode *inode, struct file *file)
{
/* /dev/watchdog can only be opened once */
if (test_and_set_bit(0, &is_active))
return -EBUSY;
/* Set and activate the watchdog */
mpc5200_wdt_set_timeout(wdt_global, 30);
mpc5200_wdt_start(wdt_global);
file->private_data = wdt_global;
return nonseekable_open(inode, file);
}
static int mpc5200_wdt_release(struct inode *inode, struct file *file)
{
#if WATCHDOG_NOWAYOUT == 0
struct mpc5200_wdt *wdt = file->private_data;
mpc5200_wdt_stop(wdt);
wdt->count = 0; /* == disabled */
#endif
clear_bit(0, &is_active);
return 0;
}
static struct file_operations mpc5200_wdt_fops = {
.owner = THIS_MODULE,
.write = mpc5200_wdt_write,
.ioctl = mpc5200_wdt_ioctl,
.open = mpc5200_wdt_open,
.release = mpc5200_wdt_release,
};
/* module operations */
static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *match)
{
struct mpc5200_wdt *wdt;
int err;
const void *has_wdt;
int size;
has_wdt = of_get_property(op->node, "has-wdt", NULL);
if (!has_wdt)
return -ENODEV;
wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
if (!wdt)
return -ENOMEM;
wdt->ipb_freq = mpc52xx_find_ipb_freq(op->node);
err = of_address_to_resource(op->node, 0, &wdt->mem);
if (err)
goto out_free;
size = wdt->mem.end - wdt->mem.start + 1;
if (!request_mem_region(wdt->mem.start, size, "mpc5200_wdt")) {
err = -ENODEV;
goto out_free;
}
wdt->regs = ioremap(wdt->mem.start, size);
if (!wdt->regs) {
err = -ENODEV;
goto out_release;
}
dev_set_drvdata(&op->dev, wdt);
spin_lock_init(&wdt->io_lock);
wdt->miscdev = (struct miscdevice) {
.minor = WATCHDOG_MINOR,
.name = "watchdog",
.fops = &mpc5200_wdt_fops,
.parent = &op->dev,
};
wdt_global = wdt;
err = misc_register(&wdt->miscdev);
if (!err)
return 0;
iounmap(wdt->regs);
out_release:
release_mem_region(wdt->mem.start, size);
out_free:
kfree(wdt);
return err;
}
static int mpc5200_wdt_remove(struct of_device *op)
{
struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
mpc5200_wdt_stop(wdt);
misc_deregister(&wdt->miscdev);
iounmap(wdt->regs);
release_mem_region(wdt->mem.start, wdt->mem.end - wdt->mem.start + 1);
kfree(wdt);
return 0;
}
static int mpc5200_wdt_suspend(struct of_device *op, pm_message_t state)
{
struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
mpc5200_wdt_stop(wdt);
return 0;
}
static int mpc5200_wdt_resume(struct of_device *op)
{
struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
if (wdt->count)
mpc5200_wdt_start(wdt);
return 0;
}
static int mpc5200_wdt_shutdown(struct of_device *op)
{
struct mpc5200_wdt *wdt = dev_get_drvdata(&op->dev);
mpc5200_wdt_stop(wdt);
return 0;
}
static struct of_device_id mpc5200_wdt_match[] = {
{ .compatible = "mpc5200-gpt", },
{},
};
static struct of_platform_driver mpc5200_wdt_driver = {
.owner = THIS_MODULE,
.name = "mpc5200-gpt-wdt",
.match_table = mpc5200_wdt_match,
.probe = mpc5200_wdt_probe,
.remove = mpc5200_wdt_remove,
.suspend = mpc5200_wdt_suspend,
.resume = mpc5200_wdt_resume,
.shutdown = mpc5200_wdt_shutdown,
};
static int __init mpc5200_wdt_init(void)
{
return of_register_platform_driver(&mpc5200_wdt_driver);
}
static void __exit mpc5200_wdt_exit(void)
{
of_unregister_platform_driver(&mpc5200_wdt_driver);
}
module_init(mpc5200_wdt_init);
module_exit(mpc5200_wdt_exit);
MODULE_AUTHOR("Domen Puncer <domen.puncer@telargo.com>");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);

View file

@ -119,6 +119,9 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
case WDIOC_GETSUPPORT:
return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0, p);
case WDIOC_KEEPALIVE:
mpc83xx_wdt_keepalive();
return 0;

View file

@ -57,7 +57,7 @@ static int mpc8xx_wdt_open(struct inode *inode, struct file *file)
m8xx_wdt_reset();
mpc8xx_wdt_handler_disable();
return 0;
return nonseekable_open(inode, file);
}
static int mpc8xx_wdt_release(struct inode *inode, struct file *file)

View file

@ -328,12 +328,11 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
goto err_out;
}
wdt = kmalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
wdt = kzalloc(sizeof(struct mpcore_wdt), GFP_KERNEL);
if (!wdt) {
ret = -ENOMEM;
goto err_out;
}
memset(wdt, 0, sizeof(struct mpcore_wdt));
wdt->dev = &dev->dev;
wdt->irq = platform_get_irq(dev, 0);

View file

@ -143,6 +143,7 @@ static int mtx1_wdt_ioctl(struct inode *inode, struct file *file, unsigned int c
mtx1_wdt_reset();
break;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
if ( copy_to_user(argp, &value, sizeof(int)) )
return -EFAULT;
break;

View file

@ -23,83 +23,126 @@
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <asm/mv64x60.h>
#include <linux/mv643xx.h>
#include <asm/uaccess.h>
#include <asm/io.h>
/* MV64x60 WDC (config) register access definitions */
#define MV64x60_WDC_CTL1_MASK (3 << 24)
#define MV64x60_WDC_CTL1(val) ((val & 3) << 24)
#define MV64x60_WDC_CTL2_MASK (3 << 26)
#define MV64x60_WDC_CTL2(val) ((val & 3) << 26)
#define MV64x60_WDT_WDC_OFFSET 0
/*
* The watchdog configuration register contains a pair of 2-bit fields,
* 1. a reload field, bits 27-26, which triggers a reload of
* the countdown register, and
* 2. an enable field, bits 25-24, which toggles between
* enabling and disabling the watchdog timer.
* Bit 31 is a read-only field which indicates whether the
* watchdog timer is currently enabled.
*
* The low 24 bits contain the timer reload value.
*/
#define MV64x60_WDC_ENABLE_SHIFT 24
#define MV64x60_WDC_SERVICE_SHIFT 26
#define MV64x60_WDC_ENABLED_SHIFT 31
#define MV64x60_WDC_ENABLED_TRUE 1
#define MV64x60_WDC_ENABLED_FALSE 0
/* Flags bits */
#define MV64x60_WDOG_FLAG_OPENED 0
#define MV64x60_WDOG_FLAG_ENABLED 1
static unsigned long wdt_flags;
static int wdt_status;
static void __iomem *mv64x60_regs;
static void __iomem *mv64x60_wdt_regs;
static int mv64x60_wdt_timeout;
static int mv64x60_wdt_count;
static unsigned int bus_clk;
static char expect_close;
static DEFINE_SPINLOCK(mv64x60_wdt_spinlock);
static void mv64x60_wdt_reg_write(u32 val)
static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
static int mv64x60_wdt_toggle_wdc(int enabled_predicate, int field_shift)
{
/* Allow write only to CTL1 / CTL2 fields, retaining values in
* other fields.
*/
u32 data = readl(mv64x60_regs + MV64x60_WDT_WDC);
data &= ~(MV64x60_WDC_CTL1_MASK | MV64x60_WDC_CTL2_MASK);
data |= val;
writel(data, mv64x60_regs + MV64x60_WDT_WDC);
u32 data;
u32 enabled;
int ret = 0;
spin_lock(&mv64x60_wdt_spinlock);
data = readl(mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
enabled = (data >> MV64x60_WDC_ENABLED_SHIFT) & 1;
/* only toggle the requested field if enabled state matches predicate */
if ((enabled ^ enabled_predicate) == 0) {
/* We write a 1, then a 2 -- to the appropriate field */
data = (1 << field_shift) | mv64x60_wdt_count;
writel(data, mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
data = (2 << field_shift) | mv64x60_wdt_count;
writel(data, mv64x60_wdt_regs + MV64x60_WDT_WDC_OFFSET);
ret = 1;
}
spin_unlock(&mv64x60_wdt_spinlock);
return ret;
}
static void mv64x60_wdt_service(void)
{
/* Write 01 followed by 10 to CTL2 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL2(0x02));
}
static void mv64x60_wdt_handler_disable(void)
{
if (test_and_clear_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
/* Write 01 followed by 10 to CTL1 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
}
mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_TRUE,
MV64x60_WDC_SERVICE_SHIFT);
}
static void mv64x60_wdt_handler_enable(void)
{
if (!test_and_set_bit(MV64x60_WDOG_FLAG_ENABLED, &wdt_flags)) {
/* Write 01 followed by 10 to CTL1 */
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x01));
mv64x60_wdt_reg_write(MV64x60_WDC_CTL1(0x02));
if (mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_FALSE,
MV64x60_WDC_ENABLE_SHIFT)) {
mv64x60_wdt_service();
printk(KERN_NOTICE "mv64x60_wdt: watchdog activated\n");
}
}
static void mv64x60_wdt_handler_disable(void)
{
if (mv64x60_wdt_toggle_wdc(MV64x60_WDC_ENABLED_TRUE,
MV64x60_WDC_ENABLE_SHIFT))
printk(KERN_NOTICE "mv64x60_wdt: watchdog deactivated\n");
}
static void mv64x60_wdt_set_timeout(unsigned int timeout)
{
/* maximum bus cycle count is 0xFFFFFFFF */
if (timeout > 0xFFFFFFFF / bus_clk)
timeout = 0xFFFFFFFF / bus_clk;
mv64x60_wdt_count = timeout * bus_clk >> 8;
mv64x60_wdt_timeout = timeout;
}
static int mv64x60_wdt_open(struct inode *inode, struct file *file)
{
if (test_and_set_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags))
return -EBUSY;
mv64x60_wdt_service();
if (nowayout)
__module_get(THIS_MODULE);
mv64x60_wdt_handler_enable();
nonseekable_open(inode, file);
return 0;
return nonseekable_open(inode, file);
}
static int mv64x60_wdt_release(struct inode *inode, struct file *file)
{
mv64x60_wdt_service();
#if !defined(CONFIG_WATCHDOG_NOWAYOUT)
mv64x60_wdt_handler_disable();
#endif
if (expect_close == 42)
mv64x60_wdt_handler_disable();
else {
printk(KERN_CRIT
"mv64x60_wdt: unexpected close, not stopping timer!\n");
mv64x60_wdt_service();
}
expect_close = 0;
clear_bit(MV64x60_WDOG_FLAG_OPENED, &wdt_flags);
@ -109,8 +152,22 @@ static int mv64x60_wdt_release(struct inode *inode, struct file *file)
static ssize_t mv64x60_wdt_write(struct file *file, const char __user *data,
size_t len, loff_t * ppos)
{
if (len)
if (len) {
if (!nowayout) {
size_t i;
expect_close = 0;
for (i = 0; i != len; i++) {
char c;
if(get_user(c, data + i))
return -EFAULT;
if (c == 'V')
expect_close = 42;
}
}
mv64x60_wdt_service();
}
return len;
}
@ -119,9 +176,12 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int timeout;
int options;
void __user *argp = (void __user *)arg;
static struct watchdog_info info = {
.options = WDIOF_KEEPALIVEPING,
.options = WDIOF_SETTIMEOUT |
WDIOF_MAGICCLOSE |
WDIOF_KEEPALIVEPING,
.firmware_version = 0,
.identity = "MV64x60 watchdog",
};
@ -143,7 +203,15 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
return -EOPNOTSUPP;
case WDIOC_SETOPTIONS:
return -EOPNOTSUPP;
if (get_user(options, (int __user *)argp))
return -EFAULT;
if (options & WDIOS_DISABLECARD)
mv64x60_wdt_handler_disable();
if (options & WDIOS_ENABLECARD)
mv64x60_wdt_handler_enable();
break;
case WDIOC_KEEPALIVE:
mv64x60_wdt_service();
@ -151,11 +219,13 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
break;
case WDIOC_SETTIMEOUT:
return -EOPNOTSUPP;
if (get_user(timeout, (int __user *)argp))
return -EFAULT;
mv64x60_wdt_set_timeout(timeout);
/* Fall through */
case WDIOC_GETTIMEOUT:
timeout = mv64x60_wdt_timeout * HZ;
if (put_user(timeout, (int __user *)argp))
if (put_user(mv64x60_wdt_timeout, (int __user *)argp))
return -EFAULT;
break;
@ -184,18 +254,33 @@ static struct miscdevice mv64x60_wdt_miscdev = {
static int __devinit mv64x60_wdt_probe(struct platform_device *dev)
{
struct mv64x60_wdt_pdata *pdata = dev->dev.platform_data;
int bus_clk = 133;
struct resource *r;
int timeout = 10;
mv64x60_wdt_timeout = 10;
bus_clk = 133; /* in MHz */
if (pdata) {
mv64x60_wdt_timeout = pdata->timeout;
timeout = pdata->timeout;
bus_clk = pdata->bus_clk;
}
mv64x60_regs = mv64x60_get_bridge_vbase();
/* Since bus_clk is truncated MHz, actual frequency could be
* up to 1MHz higher. Round up, since it's better to time out
* too late than too soon.
*/
bus_clk++;
bus_clk *= 1000000; /* convert to Hz */
writel((mv64x60_wdt_timeout * (bus_clk * 1000000)) >> 8,
mv64x60_regs + MV64x60_WDT_WDC);
r = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!r)
return -ENODEV;
mv64x60_wdt_regs = ioremap(r->start, r->end - r->start + 1);
if (mv64x60_wdt_regs == NULL)
return -ENOMEM;
mv64x60_wdt_set_timeout(timeout);
mv64x60_wdt_handler_disable(); /* in case timer was already running */
return misc_register(&mv64x60_wdt_miscdev);
}
@ -204,9 +289,10 @@ static int __devexit mv64x60_wdt_remove(struct platform_device *dev)
{
misc_deregister(&mv64x60_wdt_miscdev);
mv64x60_wdt_service();
mv64x60_wdt_handler_disable();
iounmap(mv64x60_wdt_regs);
return 0;
}
@ -219,40 +305,16 @@ static struct platform_driver mv64x60_wdt_driver = {
},
};
static struct platform_device *mv64x60_wdt_dev;
static int __init mv64x60_wdt_init(void)
{
int ret;
printk(KERN_INFO "MV64x60 watchdog driver\n");
mv64x60_wdt_dev = platform_device_alloc(MV64x60_WDT_NAME, -1);
if (!mv64x60_wdt_dev) {
ret = -ENOMEM;
goto out;
}
ret = platform_device_add(mv64x60_wdt_dev);
if (ret) {
platform_device_put(mv64x60_wdt_dev);
goto out;
}
ret = platform_driver_register(&mv64x60_wdt_driver);
if (ret) {
platform_device_unregister(mv64x60_wdt_dev);
goto out;
}
out:
return ret;
return platform_driver_register(&mv64x60_wdt_driver);
}
static void __exit mv64x60_wdt_exit(void)
{
platform_driver_unregister(&mv64x60_wdt_driver);
platform_device_unregister(mv64x60_wdt_dev);
}
module_init(mv64x60_wdt_init);

View file

@ -142,7 +142,7 @@ static int omap_wdt_open(struct inode *inode, struct file *file)
omap_wdt_set_timeout();
omap_wdt_enable();
return 0;
return nonseekable_open(inode, file);
}
static int omap_wdt_release(struct inode *inode, struct file *file)
@ -197,7 +197,7 @@ omap_wdt_ioctl(struct inode *inode, struct file *file,
switch (cmd) {
default:
return -ENOIOCTLCMD;
return -ENOTTY;
case WDIOC_GETSUPPORT:
return copy_to_user((struct watchdog_info __user *)arg, &ident,
sizeof(ident));

View file

@ -626,12 +626,11 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi
maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
/* allocate memory for our device and initialize it */
usb_pcwd = kmalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL);
usb_pcwd = kzalloc (sizeof(struct usb_pcwd_private), GFP_KERNEL);
if (usb_pcwd == NULL) {
printk(KERN_ERR PFX "Out of memory\n");
goto error;
}
memset (usb_pcwd, 0x00, sizeof (*usb_pcwd));
usb_pcwd_device = usb_pcwd;

View file

@ -52,10 +52,10 @@
#include <asm/arch/map.h>
#undef S3C24XX_VA_WATCHDOG
#define S3C24XX_VA_WATCHDOG (0)
#undef S3C_VA_WATCHDOG
#define S3C_VA_WATCHDOG (0)
#include <asm/arch/regs-watchdog.h>
#include <asm/plat-s3c/regs-watchdog.h>
#define PFX "s3c2410-wdt: "

View file

@ -45,7 +45,6 @@ static int boot_status;
*/
static int sa1100dog_open(struct inode *inode, struct file *file)
{
nonseekable_open(inode, file);
if (test_and_set_bit(1,&sa1100wdt_users))
return -EBUSY;
@ -54,7 +53,7 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
OSSR = OSSR_M3;
OWER = OWER_WME;
OIER |= OIER_E3;
return 0;
return nonseekable_open(inode, file);
}
/*

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