Commit 1071ec7b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc patches from Greg KH:
 "Here's the big char/misc driver patchset for 3.13-rc1.

  Lots of stuff in here, including some new drivers for Intel's "MIC"
  co-processor devices, and a new eeprom driver.  Other things include
  the driver attribute cleanups, extcon driver updates, hyperv updates,
  and a raft of other miscellaneous driver fixes.

  All of these have been in linux-next for a while"

* tag 'char-misc-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (121 commits)
  misc: mic: Fixes for randconfig build errors and warnings.
  tifm: fix error return code in tifm_7xx1_probe()
  w1-gpio: Use devm_* functions
  w1-gpio: Detect of_gpio_error for first gpio
  uio: Pass pointers to virt_to_page(), not integers
  uio: fix memory leak
  misc/at24: avoid infinite loop on write()
  misc/93xx46: avoid infinite loop on write()
  misc: atmel_pwm: add deferred-probing support
  mei: wd: host_init propagate error codes from called functions
  mei: replace stray pr_debug with dev_dbg
  mei: bus: propagate error code returned by mei_me_cl_by_id
  mei: mei_cl_link remove duplicated check for open_handle_count
  mei: print correct device state during unexpected reset
  mei: nfc: fix memory leak in error path
  lkdtm: add tests for additional page permissions
  lkdtm: adjust recursion size to avoid warnings
  lkdtm: isolate stack corruption test
  mei: move host_clients_map cleanup to device init
  mei: me: downgrade two errors to debug level
  ...
parents c287322c 42579226
What: /sys/class/mic/
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
The mic class directory belongs to Intel MIC devices and
provides information per MIC device. An Intel MIC device is a
PCIe form factor add-in Coprocessor card based on the Intel Many
Integrated Core (MIC) architecture that runs a Linux OS.
What: /sys/class/mic/mic(x)
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
The directories /sys/class/mic/mic0, /sys/class/mic/mic1 etc.,
represent MIC devices (0,1,..etc). Each directory has
information specific to that MIC device.
What: /sys/class/mic/mic(x)/family
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
Provides information about the Coprocessor family for an Intel
MIC device. For example - "x100"
What: /sys/class/mic/mic(x)/stepping
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
Provides information about the silicon stepping for an Intel
MIC device. For example - "A0" or "B0"
What: /sys/class/mic/mic(x)/state
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
When read, this entry provides the current state of an Intel
MIC device in the context of the card OS. Possible values that
will be read are:
"offline" - The MIC device is ready to boot the card OS. On
reading this entry after an OSPM resume, a "boot" has to be
written to this entry if the card was previously shutdown
during OSPM suspend.
"online" - The MIC device has initiated booting a card OS.
"shutting_down" - The card OS is shutting down.
"reset_failed" - The MIC device has failed to reset.
"suspending" - The MIC device is currently being prepared for
suspend. On reading this entry, a "suspend" has to be written
to the state sysfs entry to ensure the card is shutdown during
OSPM suspend.
"suspended" - The MIC device has been suspended.
When written, this sysfs entry triggers different state change
operations depending upon the current state of the card OS.
Acceptable values are:
"boot" - Boot the card OS image specified by the combination
of firmware, ramdisk, cmdline and bootmode
sysfs entries.
"reset" - Initiates device reset.
"shutdown" - Initiates card OS shutdown.
"suspend" - Initiates card OS shutdown and also marks the card
as suspended.
What: /sys/class/mic/mic(x)/shutdown_status
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
An Intel MIC device runs a Linux OS during its operation. This
OS can shutdown because of various reasons. When read, this
entry provides the status on why the card OS was shutdown.
Possible values are:
"nop" - shutdown status is not applicable, when the card OS is
"online"
"crashed" - Shutdown because of a HW or SW crash.
"halted" - Shutdown because of a halt command.
"poweroff" - Shutdown because of a poweroff command.
"restart" - Shutdown because of a restart command.
What: /sys/class/mic/mic(x)/cmdline
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
An Intel MIC device runs a Linux OS during its operation. Before
booting this card OS, it is possible to pass kernel command line
options to configure various features in it, similar to
self-bootable machines. When read, this entry provides
information about the current kernel command line options set to
boot the card OS. This entry can be written to change the
existing kernel command line options. Typically, the user would
want to read the current command line options, append new ones
or modify existing ones and then write the whole kernel command
line back to this entry.
What: /sys/class/mic/mic(x)/firmware
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
When read, this sysfs entry provides the path name under
/lib/firmware/ where the firmware image to be booted on the
card can be found. The entry can be written to change the
firmware image location under /lib/firmware/.
What: /sys/class/mic/mic(x)/ramdisk
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
When read, this sysfs entry provides the path name under
/lib/firmware/ where the ramdisk image to be used during card
OS boot can be found. The entry can be written to change
the ramdisk image location under /lib/firmware/.
What: /sys/class/mic/mic(x)/bootmode
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
When read, this sysfs entry provides the current bootmode for
the card. This sysfs entry can be written with the following
valid strings:
a) linux - Boot a Linux image.
b) elf - Boot an elf image for flash updates.
What: /sys/class/mic/mic(x)/log_buf_addr
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
An Intel MIC device runs a Linux OS during its operation. For
debugging purpose and early kernel boot messages, the user can
access the card OS log buffer via debugfs. When read, this entry
provides the kernel virtual address of the buffer where the card
OS log buffer can be read. This entry is written by the host
configuration daemon to set the log buffer address. The correct
log buffer address to be written can be found in the System.map
file of the card OS.
What: /sys/class/mic/mic(x)/log_buf_len
Date: October 2013
KernelVersion: 3.13
Contact: Sudeep Dutt <sudeep.dutt@intel.com>
Description:
An Intel MIC device runs a Linux OS during its operation. For
debugging purpose and early kernel boot messages, the user can
access the card OS log buffer via debugfs. When read, this entry
provides the kernel virtual address where the card OS log buffer
length can be read. This entry is written by host configuration
daemon to set the log buffer length address. The correct log
buffer length address to be written can be found in the
System.map file of the card OS.
What: /sys/devices/*/<our-device>/eeprom
Date: August 2013
Contact: Oliver Schinagl <oliver@schinagl.nl>
Description: read-only access to the SID (Security-ID) on current
A-series SoC's from Allwinner. Currently supports A10, A10s, A13
and A20 CPU's. The earlier A1x series of SoCs exports 16 bytes,
whereas the newer A20 SoC exposes 512 bytes split into sections.
Besides the 16 bytes of SID, there's also an SJTAG area,
HDMI-HDCP key and some custom keys. Below a quick overview, for
details see the user manual:
0x000 128 bit root-key (sun[457]i)
0x010 128 bit boot-key (sun7i)
0x020 64 bit security-jtag-key (sun7i)
0x028 16 bit key configuration (sun7i)
0x02b 16 bit custom-vendor-key (sun7i)
0x02c 320 bit low general key (sun7i)
0x040 32 bit read-control access (sun7i)
0x064 224 bit low general key (sun7i)
0x080 2304 bit HDCP-key (sun7i)
0x1a0 768 bit high general key (sun7i)
Users: any user space application which wants to read the SID on
Allwinner's A-series of CPU's.
Allwinner sunxi-sid
Required properties:
- compatible: "allwinner,sun4i-sid" or "allwinner,sun7i-a20-sid".
- reg: Should contain registers location and length
Example for sun4i:
sid@01c23800 {
compatible = "allwinner,sun4i-sid";
reg = <0x01c23800 0x10>
};
Example for sun7i:
sid@01c23800 {
compatible = "allwinner,sun7i-a20-sid";
reg = <0x01c23800 0x200>
};
TI DAC7512 DEVICETREE BINDINGS
Required properties:
- "compatible" Must be set to "ti,dac7512"
Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
apply. In particular, "reg" and "spi-max-frequency" properties must be given.
Example:
spi_master {
dac7512: dac7512@0 {
compatible = "ti,dac7512";
reg = <0>; /* CS0 */
spi-max-frequency = <1000000>;
};
};
......@@ -25,8 +25,10 @@ MyungJoo Ham <myungjoo.ham@samsung.com>
@print_state: no change but type change (switch_dev->extcon_dev)
- switch_dev_register(sdev, dev)
=> extcon_dev_register(edev, dev)
: no change but type change (sdev->edev)
=> extcon_dev_register(edev)
: type change (sdev->edev)
: remove second param('dev'). if edev has parent device, should store
'dev' to 'edev.dev.parent' before registering extcon device
- switch_dev_unregister(sdev)
=> extcon_dev_unregister(edev)
: no change but type change (sdev->edev)
......
An Intel MIC X100 device is a PCIe form factor add-in coprocessor
card based on the Intel Many Integrated Core (MIC) architecture
that runs a Linux OS. It is a PCIe endpoint in a platform and therefore
implements the three required standard address spaces i.e. configuration,
memory and I/O. The host OS loads a device driver as is typical for
PCIe devices. The card itself runs a bootstrap after reset that
transfers control to the card OS downloaded from the host driver. The
host driver supports OSPM suspend and resume operations. It shuts down
the card during suspend and reboots the card OS during resume.
The card OS as shipped by Intel is a Linux kernel with modifications
for the X100 devices.
Since it is a PCIe card, it does not have the ability to host hardware
devices for networking, storage and console. We provide these devices
on X100 coprocessors thus enabling a self-bootable equivalent environment
for applications. A key benefit of our solution is that it leverages
the standard virtio framework for network, disk and console devices,
though in our case the virtio framework is used across a PCIe bus.
Here is a block diagram of the various components described above. The
virtio backends are situated on the host rather than the card given better
single threaded performance for the host compared to MIC, the ability of
the host to initiate DMA's to/from the card using the MIC DMA engine and
the fact that the virtio block storage backend can only be on the host.
|
+----------+ | +----------+
| Card OS | | | Host OS |
+----------+ | +----------+
|
+-------+ +--------+ +------+ | +---------+ +--------+ +--------+
| Virtio| |Virtio | |Virtio| | |Virtio | |Virtio | |Virtio |
| Net | |Console | |Block | | |Net | |Console | |Block |
| Driver| |Driver | |Driver| | |backend | |backend | |backend |
+-------+ +--------+ +------+ | +---------+ +--------+ +--------+
| | | | | | |
| | | |User | | |
| | | |------|------------|---------|-------
+-------------------+ |Kernel +--------------------------+
| | | Virtio over PCIe IOCTLs |
| | +--------------------------+
+--------------+ | |
|Intel MIC | | +---------------+
|Card Driver | | |Intel MIC |
+--------------+ | |Host Driver |
| | +---------------+
| | |
+-------------------------------------------------------------+
| |
| PCIe Bus |
+-------------------------------------------------------------+
#
# Makefile - Intel MIC User Space Tools.
# Copyright(c) 2013, Intel Corporation.
#
ifdef DEBUG
CFLAGS += $(USERWARNFLAGS) -I. -g -Wall -DDEBUG=$(DEBUG)
else
CFLAGS += $(USERWARNFLAGS) -I. -g -Wall
endif
mpssd: mpssd.o sysfs.o
$(CC) $(CFLAGS) -o $@ $^ -lpthread
install:
install mpssd /usr/sbin/mpssd
install micctrl /usr/sbin/micctrl
clean:
rm -f mpssd *.o
#!/bin/bash
# Intel MIC Platform Software Stack (MPSS)
#
# Copyright(c) 2013 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# 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.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Intel MIC User Space Tools.
#
# micctrl - Controls MIC boot/start/stop.
#
# chkconfig: 2345 95 05
# description: start MPSS stack processing.
#
### BEGIN INIT INFO
# Provides: micctrl
### END INIT INFO
# Source function library.
. /etc/init.d/functions
sysfs="/sys/class/mic"
_status()
{
f=$sysfs/$1
echo -e $1 state: "`cat $f/state`" shutdown_status: "`cat $f/shutdown_status`"
}
status()
{
if [ "`echo $1 | head -c3`" == "mic" ]; then
_status $1
return $?
fi
for f in $sysfs/*
do
_status `basename $f`
RETVAL=$?
[ $RETVAL -ne 0 ] && return $RETVAL
done
return 0
}
_reset()
{
f=$sysfs/$1
echo reset > $f/state
}
reset()
{
if [ "`echo $1 | head -c3`" == "mic" ]; then
_reset $1
return $?
fi
for f in $sysfs/*
do
_reset `basename $f`
RETVAL=$?
[ $RETVAL -ne 0 ] && return $RETVAL
done
return 0
}
_boot()
{
f=$sysfs/$1
echo "linux" > $f/bootmode
echo "mic/uos.img" > $f/firmware
echo "mic/$1.image" > $f/ramdisk
echo "boot" > $f/state
}
boot()
{
if [ "`echo $1 | head -c3`" == "mic" ]; then
_boot $1
return $?
fi
for f in $sysfs/*
do
_boot `basename $f`
RETVAL=$?
[ $RETVAL -ne 0 ] && return $RETVAL
done
return 0
}
_shutdown()
{
f=$sysfs/$1
echo shutdown > $f/state
}
shutdown()
{
if [ "`echo $1 | head -c3`" == "mic" ]; then
_shutdown $1
return $?
fi
for f in $sysfs/*
do
_shutdown `basename $f`
RETVAL=$?
[ $RETVAL -ne 0 ] && return $RETVAL
done
return 0
}
_wait()
{
f=$sysfs/$1
while [ "`cat $f/state`" != "offline" -a "`cat $f/state`" != "online" ]
do
sleep 1
echo -e "Waiting for $1 to go offline"
done
}
wait()
{
if [ "`echo $1 | head -c3`" == "mic" ]; then
_wait $1
return $?
fi
# Wait for the cards to go offline
for f in $sysfs/*
do
_wait `basename $f`
RETVAL=$?
[ $RETVAL -ne 0 ] && return $RETVAL
done
return 0
}
if [ ! -d "$sysfs" ]; then
echo -e $"Module unloaded "
exit 3
fi
case $1 in
-s)
status $2
;;
-r)
reset $2
;;
-b)
boot $2
;;
-S)
shutdown $2
;;
-w)
wait $2
;;
*)
echo $"Usage: $0 {-s (status) |-r (reset) |-b (boot) |-S (shutdown) |-w (wait)}"
exit 2
esac
exit $?
#!/bin/bash
# Intel MIC Platform Software Stack (MPSS)
#
# Copyright(c) 2013 Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# 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.
#
# The full GNU General Public License is included in this distribution in
# the file called "COPYING".
#
# Intel MIC User Space Tools.
#
# mpss Start mpssd.
#
# chkconfig: 2345 95 05
# description: start MPSS stack processing.
#
### BEGIN INIT INFO
# Provides: mpss
# Required-Start:
# Required-Stop:
# Short-Description: MPSS stack control
# Description: MPSS stack control
### END INIT INFO
# Source function library.
. /etc/init.d/functions
exec=/usr/sbin/mpssd
sysfs="/sys/class/mic"
start()
{
[ -x $exec ] || exit 5
if [ "`ps -e | awk '{print $4}' | grep mpssd | head -1`" = "mpssd" ]; then
echo -e $"MPSSD already running! "
success
echo
return 0
fi
echo -e $"Starting MPSS Stack"
echo -e $"Loading MIC_HOST Module"
# Ensure the driver is loaded
if [ ! -d "$sysfs" ]; then
modprobe mic_host
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
failure
echo
return $RETVAL
fi
fi
# Start the daemon
echo -n $"Starting MPSSD "
$exec
RETVAL=$?
if [ $RETVAL -ne 0 ]; then
failure
echo
return $RETVAL
fi
success
echo
sleep 5
# Boot the cards
micctrl -b
# Wait till ping works
for f in $sysfs/*
do
count=100
ipaddr=`cat $f/cmdline`
ipaddr=${ipaddr#*address,}
ipaddr=`echo $ipaddr | cut -d, -f1 | cut -d\; -f1`
while [ $count -ge 0 ]
do
echo -e "Pinging "`basename $f`" "
ping -c 1 $ipaddr &> /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
success
break
fi
sleep 1
count=`expr $count - 1`
done
[ $RETVAL -ne 0 ] && failure || success
echo
done
return $RETVAL
}
stop()
{
echo -e $"Shutting down MPSS Stack: "
# Bail out if module is unloaded
if [ ! -d "$sysfs" ]; then
echo -n $"Module unloaded "
success
echo
return 0
fi
# Shut down the cards.
micctrl -S
# Wait for the cards to go offline
for f in $sysfs/*
do
while [ "`cat $f/state`" != "offline" ]
do
sleep 1
echo -e "Waiting for "`basename $f`" to go offline"
done
done
# Display the status of the cards
micctrl -s
# Kill MPSSD now
echo -n $"Killing MPSSD"
killall -9 mpssd 2>/dev/null
RETVAL=$?
[ $RETVAL -ne 0 ] && failure || success
echo
return $RETVAL
}
restart()
{
stop
sleep 5
start
}
status()
{
micctrl -s
if [ "`ps -e | awk '{print $4}' | grep mpssd | head -n 1`" = "mpssd" ]; then
echo "mpssd is running"
else
echo "mpssd is stopped"
fi
return 0
}
unload()
{
if [ ! -d "$sysfs" ]; then
echo -n $"No MIC_HOST Module: "
success
echo
return
fi
stop
sleep 5
echo -n $"Removing MIC_HOST Module: "
modprobe -r mic_host
RETVAL=$?
[ $RETVAL -ne 0 ] && failure || success
echo
return $RETVAL
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status
;;
unload)
unload
;;
*)
echo $"Usage: $0 {start|stop|restart|status|unload}"
exit 2
esac
exit $?
This diff is collapsed.
/*
* Intel MIC Platform Software Stack (MPSS)
*
* Copyright(c) 2013 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*
* 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.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Intel MIC User Space Tools.
*/
#ifndef _MPSSD_H_
#define _MPSSD_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <libgen.h>
#include <pthread.h>
#include <stdarg.h>
#include <time.h>
#include <errno.h>
#include <sys/dir.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <signal.h>
#include <limits.h>
#include <syslog.h>
#include <getopt.h>
#include <net/if.h>
#include <linux/if_tun.h>
#include <linux/if_tun.h>
#include <linux/virtio_ids.h>
#define MICSYSFSDIR "/sys/class/mic"
#define LOGFILE_NAME "/var/log/mpssd"
#define PAGE_SIZE 4096
struct mic_console_info {
pthread_t console_thread;
int virtio_console_fd;
void *console_dp;
};
struct mic_net_info {
pthread_t net_thread;
int virtio_net_fd;
int tap_fd;
void *net_dp;
};
struct mic_virtblk_info {
pthread_t block_thread;
int virtio_block_fd;
void *block_dp;
volatile sig_atomic_t signaled;
char *backend_file;
int backend;
void *backend_addr;
long backend_size;
};
struct mic_info {
int id;
char *name;
pthread_t config_thread;
pid_t pid;
struct mic_console_info mic_console;
struct mic_net_info mic_net;
struct mic_virtblk_info mic_virtblk;
int restart;
int boot_on_resume;
struct mic_info *next;
};
__attribute__((format(printf, 1, 2)))
void mpsslog(char *format, ...);
char *readsysfs(char *dir, char *entry);
int setsysfs(char *dir, char *entry, char *value);
#endif
/*
* Intel MIC Platform Software Stack (MPSS)
*
* Copyright(c) 2013 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
*
* 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.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Intel MIC User Space Tools.
*/
#include "mpssd.h"
#define PAGE_SIZE 4096
char *
readsysfs(char *dir, char *entry)
{
char filename[PATH_MAX];
char value[PAGE_SIZE];
char *string = NULL;
int fd;
int len;
if (dir == NULL)
snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
else
snprintf(filename, PATH_MAX,
"%s/%s/%s", MICSYSFSDIR, dir, entry);
fd = open(filename, O_RDONLY);
if (fd < 0) {
mpsslog("Failed to open sysfs entry '%s': %s\n",
filename, strerror(errno));
return NULL;
}
len = read(fd, value, sizeof(value));
if (len < 0) {
mpsslog("Failed to read sysfs entry '%s': %s\n",
filename, strerror(errno));
goto readsys_ret;
}
if (len == 0)
goto readsys_ret;
value[len - 1] = '\0';
string = malloc(strlen(value) + 1);
if (string)
strcpy(string, value);
readsys_ret:
close(fd);
return string;
}
int
setsysfs(char *dir, char *entry, char *value)
{
char filename[PATH_MAX];
char *oldvalue;
int fd, ret = 0;
if (dir == NULL)
snprintf(filename, PATH_MAX, "%s/%s", MICSYSFSDIR, entry);
else
snprintf(filename, PATH_MAX, "%s/%s/%s",
MICSYSFSDIR, dir, entry);
oldvalue = readsysfs(dir, entry);
fd = open(filename, O_RDWR);
if (fd < 0) {
ret = errno;
mpsslog("Failed to open sysfs entry '%s': %s\n",
filename, strerror(errno));
goto done;
}
if (!oldvalue || strcmp(value, oldvalue)) {
if (write(fd, value, strlen(value)) < 0) {
ret = errno;
mpsslog("Failed to write new sysfs entry '%s': %s\n",
filename, strerror(errno));
}
}
close(fd);
done:
if (oldvalue)
free(oldvalue);
return ret;
}
......@@ -486,8 +486,7 @@ static int hpet_ioctl_ieon(struct hpet_dev *devp)
}
sprintf(devp->hd_name, "hpet%d", (int)(devp - hpetp->hp_dev));
irq_flags = devp->hd_flags & HPET_SHARED_IRQ
? IRQF_SHARED : IRQF_DISABLED;
irq_flags = devp->hd_flags & HPET_SHARED_IRQ ? IRQF_SHARED : 0;
if (request_irq(irq, hpet_interrupt, irq_flags,
devp->hd_name, (void *)devp)) {
printk(KERN_ERR "hpet: IRQ %d is not free\n", irq);
......@@ -971,8 +970,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
struct acpi_resource_fixed_memory32 *fixmem32;
fixmem32 = &res->data.fixed_memory32;
if (!fixmem32)
return AE_NO_MEMORY;
hdp->hd_phys_address = fixmem32->address;
hdp->hd_address = ioremap(fixmem32->address,
......
......@@ -193,8 +193,8 @@ int misc_register(struct miscdevice * misc)
if (misc->minor == MISC_DYNAMIC_MINOR) {
int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
if (i >= DYNAMIC_MINORS) {
mutex_unlock(&misc_mtx);
return -EBUSY;
err = -EBUSY;
goto out;
}
misc->minor = DYNAMIC_MINORS - i - 1;
set_bit(i, misc_minors);
......@@ -203,8 +203,8 @@ int misc_register(struct miscdevice * misc)
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
mutex_unlock(&misc_mtx);
return -EBUSY;
err = -EBUSY;
goto out;
}
}
}
......
......@@ -220,7 +220,7 @@ static int __init nwbutton_init(void)
return -EBUSY;
}
if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, IRQF_DISABLED,
if (request_irq (IRQ_NETWINDER_BUTTON, button_handler, 0,
"nwbutton", NULL)) {
printk (KERN_WARNING "nwbutton: IRQ %d is not free.\n",
IRQ_NETWINDER_BUTTON);
......
......@@ -227,7 +227,7 @@ static inline unsigned char rtc_is_updating(void)
#ifdef RTC_IRQ
/*
* A very tiny interrupt handler. It runs with IRQF_DISABLED set,
* A very tiny interrupt handler. It runs with interrupts disabled,
* but there is possibility of conflicting with the set_rtc_mmss()
* call (the rtc irq and the timer irq can easily run at the same
* time in two different CPUs). So we need to serialize
......@@ -1040,8 +1040,7 @@ static int __init rtc_init(void)
rtc_int_handler_ptr = rtc_interrupt;
}
if (request_irq(RTC_IRQ, rtc_int_handler_ptr, IRQF_DISABLED,
"rtc", NULL)) {
if (request_irq(RTC_IRQ, rtc_int_handler_ptr, 0, "rtc", NULL)) {
/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
rtc_has_irq = 0;
printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
......
......@@ -108,8 +108,7 @@ scdrv_open(struct inode *inode, struct file *file)
/* hook this subchannel up to the system controller interrupt */
mutex_lock(&scdrv_mutex);
rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
IRQF_SHARED | IRQF_DISABLED,
SYSCTL_BASENAME, sd);
IRQF_SHARED, SYSCTL_BASENAME, sd);
if (rv) {
ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
kfree(sd);
......
......@@ -292,8 +292,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
/* hook event subchannel up to the system controller interrupt */
rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt,
IRQF_SHARED | IRQF_DISABLED,
"system controller events", event_sd);
IRQF_SHARED, "system controller events", event_sd);
if (rv) {
printk(KERN_WARNING "%s: irq request failed (%d)\n",
__func__, rv);
......
......@@ -222,7 +222,7 @@ static int tlclk_open(struct inode *inode, struct file *filp)
/* This device is wired through the FPGA IO space of the ATCA blade
* we can't share this IRQ */
result = request_irq(telclk_interrupt, &tlclk_interrupt,
IRQF_DISABLED, "telco_clock", tlclk_interrupt);
0, "telco_clock", tlclk_interrupt);
if (result == -EBUSY)
printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
else
......
......@@ -721,7 +721,7 @@ static int hwicap_remove(struct device *dev)
{
struct hwicap_drvdata *drvdata;
drvdata = (struct hwicap_drvdata *)dev_get_drvdata(dev);
drvdata = dev_get_drvdata(dev);
if (!drvdata)
return 0;
......@@ -731,7 +731,6 @@ static int hwicap_remove(struct device *dev)
iounmap(drvdata->base_address);
release_mem_region(drvdata->mem_start, drvdata->mem_size);
kfree(drvdata);
dev_set_drvdata(dev, NULL);
mutex_lock(&icap_sem);
probed_devices[MINOR(dev->devt)-XHWICAP_MINOR] = 0;
......
......@@ -27,16 +27,16 @@
/**
* struct adc_jack_data - internal data for adc_jack device driver
* @edev - extcon device.
* @cable_names - list of supported cables.
* @num_cables - size of cable_names.
* @adc_conditions - list of adc value conditions.
* @num_conditions - size of adc_conditions.
* @irq - irq number of attach/detach event (0 if not exist).
* @handling_delay - interrupt handler will schedule extcon event
* handling at handling_delay jiffies.
* @handler - extcon event handler called by interrupt handler.
* @chan - iio channel being queried.
* @edev: extcon device.
* @cable_names: list of supported cables.
* @num_cables: size of cable_names.
* @adc_conditions: list of adc value conditions.
* @num_conditions: size of adc_conditions.
* @irq: irq number of attach/detach event (0 if not exist).
* @handling_delay: interrupt handler will schedule extcon event
* handling at handling_delay jiffies.
* @handler: extcon event handler called by interrupt handler.
* @chan: iio channel being queried.
*/
struct adc_jack_data {
struct extcon_dev edev;
......@@ -64,7 +64,7 @@ static void adc_jack_handler(struct work_struct *work)
ret = iio_read_channel_raw(data->chan, &adc_val);
if (ret < 0) {
dev_err(data->edev.dev, "read channel() error: %d\n", ret);
dev_err(&data->edev.dev, "read channel() error: %d\n", ret);
return;
}
......@@ -95,7 +95,7 @@ static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
static int adc_jack_probe(struct platform_device *pdev)
{
struct adc_jack_data *data;
struct adc_jack_pdata *pdata = pdev->dev.platform_data;
struct adc_jack_pdata *pdata = dev_get_platdata(&pdev->dev);
int i, err = 0;
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
......@@ -110,6 +110,7 @@ static int adc_jack_probe(struct platform_device *pdev)
goto out;
}
data->edev.dev.parent = &pdev->dev;
data->edev.supported_cable = pdata->cable_names;
/* Check the length of array and set num_cables */
......@@ -148,7 +149,7 @@ static int adc_jack_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data);
err = extcon_dev_register(&data->edev, &pdev->dev);
err = extcon_dev_register(&data->edev);
if (err)
goto out;
......
......@@ -86,8 +86,8 @@ struct arizona_extcon_info {
};
static const struct arizona_micd_config micd_default_modes[] = {
{ ARIZONA_ACCDET_SRC, 1 << ARIZONA_MICD_BIAS_SRC_SHIFT, 0 },
{ 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
{ ARIZONA_ACCDET_SRC, 1, 0 },
{ 0, 2, 1 },
};
static const struct arizona_micd_range micd_default_ranges[] = {
......@@ -182,7 +182,8 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
info->micd_modes[mode].gpio);
regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1,
ARIZONA_MICD_BIAS_SRC_MASK,
info->micd_modes[mode].bias);
info->micd_modes[mode].bias <<
ARIZONA_MICD_BIAS_SRC_SHIFT);
regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1,
ARIZONA_ACCDET_SRC, info->micd_modes[mode].src);
......@@ -193,7 +194,7 @@ static void arizona_extcon_set_mode(struct arizona_extcon_info *info, int mode)
static const char *arizona_extcon_get_micbias(struct arizona_extcon_info *info)
{
switch (info->micd_modes[0].bias >> ARIZONA_MICD_BIAS_SRC_SHIFT) {
switch (info->micd_modes[0].bias) {
case 1:
return "MICBIAS1";
case 2:
......@@ -388,7 +389,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
>> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
(val < 100 || val > 0x3fb)) {
(val < 100 || val >= 0x3fb)) {
range++;
dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
range);
......@@ -401,7 +402,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
}
/* If we go out of range report top of range */
if (val < 100 || val > 0x3fb) {
if (val < 100 || val >= 0x3fb) {
dev_dbg(arizona->dev, "Measurement out of range\n");
return ARIZONA_HPDET_MAX;
}
......@@ -514,7 +515,7 @@ static int arizona_hpdet_do_id(struct arizona_extcon_info *info, int *reading,
}
/*
* If we measure the mic as
* If we measure the mic as high impedance
*/
if (!id_gpio || info->hpdet_res[1] > 50) {
dev_dbg(arizona->dev, "Detected mic\n");
......@@ -564,11 +565,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
}
ret = arizona_hpdet_read(info);
if (ret == -EAGAIN) {
if (ret == -EAGAIN)
goto out;
} else if (ret < 0) {
else if (ret < 0)
goto done;
}
reading = ret;
/* Reset back to starting range */
......@@ -578,11 +578,10 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
0);
ret = arizona_hpdet_do_id(info, &reading, &mic);
if (ret == -EAGAIN) {
if (ret == -EAGAIN)
goto out;
} else if (ret < 0) {
else if (ret < 0)
goto done;
}
/* Report high impedence cables as line outputs */
if (reading >= 5000)
......@@ -738,8 +737,8 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
static void arizona_micd_timeout_work(struct work_struct *work)
{
struct arizona_extcon_info *info = container_of(work,
struct arizona_extcon_info,
micd_timeout_work.work);
struct arizona_extcon_info,
micd_timeout_work.work);
mutex_lock(&info->lock);
......@@ -756,8 +755,8 @@ static void arizona_micd_timeout_work(struct work_struct *work)
static void arizona_micd_detect(struct work_struct *work)
{
struct arizona_extcon_info *info = container_of(work,
struct arizona_extcon_info,
micd_detect_work.work);
struct arizona_extcon_info,
micd_detect_work.work);
struct arizona *arizona = info->arizona;
unsigned int val = 0, lvl;
int ret, i, key;
......@@ -769,7 +768,8 @@ static void arizona_micd_detect(struct work_struct *work)
for (i = 0; i < 10 && !(val & 0x7fc); i++) {
ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val);
if (ret != 0) {
dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret);
dev_err(arizona->dev,
"Failed to read MICDET: %d\n", ret);
mutex_unlock(&info->lock);
return;
}
......@@ -777,7 +777,8 @@ static void arizona_micd_detect(struct work_struct *work)
dev_dbg(arizona->dev, "MICDET: %x\n", val);
if (!(val & ARIZONA_MICD_VALID)) {
dev_warn(arizona->dev, "Microphone detection state invalid\n");
dev_warn(arizona->dev,
"Microphone detection state invalid\n");
mutex_unlock(&info->lock);
return;
}
......@@ -925,8 +926,8 @@ static irqreturn_t arizona_micdet(int irq, void *data)
static void arizona_hpdet_work(struct work_struct *work)
{
struct arizona_extcon_info *info = container_of(work,
struct arizona_extcon_info,
hpdet_work.work);
struct arizona_extcon_info,
hpdet_work.work);
mutex_lock(&info->lock);
arizona_start_hpdet_acc_id(info);
......@@ -973,10 +974,13 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
&info->hpdet_work,
msecs_to_jiffies(HPDET_DEBOUNCE));
if (cancelled_mic)
if (cancelled_mic) {
int micd_timeout = info->micd_timeout;
queue_delayed_work(system_power_efficient_wq,
&info->micd_timeout_work,
msecs_to_jiffies(info->micd_timeout));
msecs_to_jiffies(micd_timeout));
}
goto out;
}
......@@ -1039,6 +1043,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
else
info->micd_timeout = DEFAULT_MICD_TIMEOUT;
out:
/* Clear trig_sts to make sure DCVDD is not forced up */
regmap_write(arizona->regmap, ARIZONA_AOD_WKUP_AND_TRIG,
ARIZONA_MICD_CLAMP_FALL_TRIG_STS |
......@@ -1046,7 +1051,6 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
ARIZONA_JD1_FALL_TRIG_STS |
ARIZONA_JD1_RISE_TRIG_STS);
out:
mutex_unlock(&info->lock);
pm_runtime_mark_last_busy(info->dev);
......@@ -1129,9 +1133,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
}
info->edev.name = "Headset Jack";
info->edev.dev.parent = arizona->dev;
info->edev.supported_cable = arizona_cable;
ret = extcon_dev_register(&info->edev, arizona->dev);
ret = extcon_dev_register(&info->edev);
if (ret < 0) {
dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
ret);
......
This diff is collapsed.
......@@ -34,6 +34,7 @@
struct gpio_extcon_data {
struct extcon_dev edev;
unsigned gpio;
bool gpio_active_low;
const char *state_on;
const char *state_off;
int irq;
......@@ -49,6 +50,8 @@ static void gpio_extcon_work(struct work_struct *work)
work);
state = gpio_get_value(data->gpio);
if (data->gpio_active_low)
state = !state;
extcon_set_state(&data->edev, state);
}
......@@ -78,9 +81,9 @@ static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
static int gpio_extcon_probe(struct platform_device *pdev)
{
struct gpio_extcon_platform_data *pdata = pdev->dev.platform_data;
struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct gpio_extcon_data *extcon_data;
int ret = 0;
int ret;
if (!pdata)
return -EBUSY;
......@@ -95,14 +98,22 @@ static int gpio_extcon_probe(struct platform_device *pdev)
return -ENOMEM;
extcon_data->edev.name = pdata->name;
extcon_data->edev.dev.parent = &pdev->dev;
extcon_data->gpio = pdata->gpio;
extcon_data->gpio_active_low = pdata->gpio_active_low;
extcon_data->state_on = pdata->state_on;
extcon_data->state_off = pdata->state_off;
if (pdata->state_on && pdata->state_off)
extcon_data->edev.print_state = extcon_gpio_print_state;
extcon_data->debounce_jiffies = msecs_to_jiffies(pdata->debounce);
if (pdata->debounce) {
ret = gpio_set_debounce(extcon_data->gpio,
pdata->debounce * 1000);
if (ret < 0)
extcon_data->debounce_jiffies =
msecs_to_jiffies(pdata->debounce);
}
ret = extcon_dev_register(&extcon_data->edev, &pdev->dev);
ret = extcon_dev_register(&extcon_data->edev);
if (ret < 0)
return ret;
......
This diff is collapsed.
......@@ -426,7 +426,8 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info)
break;
case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF:
case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON:
ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, attached);
ret = max8997_muic_handle_usb(info,
MAX8997_USB_DEVICE, attached);
if (ret < 0)
return ret;
break;
......@@ -504,7 +505,8 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info)
}
break;
case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
extcon_set_cable_state(info->edev, "Charge-downstream", attached);
extcon_set_cable_state(info->edev,
"Charge-downstream", attached);
break;
case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
extcon_set_cable_state(info->edev, "TA", attached);
......@@ -537,7 +539,7 @@ static void max8997_muic_irq_work(struct work_struct *work)
mutex_lock(&info->mutex);
for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
if (info->irq == muic_irqs[i].virq)
irq_type = muic_irqs[i].irq;
......@@ -705,8 +707,9 @@ static int max8997_muic_probe(struct platform_device *pdev)
goto err_irq;
}
info->edev->name = DEV_NAME;
info->edev->dev.parent = &pdev->dev;
info->edev->supported_cable = max8997_extcon_cable;
ret = extcon_dev_register(info->edev, NULL);
ret = extcon_dev_register(info->edev);
if (ret) {
dev_err(&pdev->dev, "failed to register extcon device\n");
goto err_irq;
......
......@@ -135,7 +135,7 @@ static void palmas_enable_irq(struct palmas_usb *palmas_usb)
static int palmas_usb_probe(struct platform_device *pdev)
{
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
struct palmas_usb_platform_data *pdata = pdev->dev.platform_data;
struct palmas_usb_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *node = pdev->dev.of_node;
struct palmas_usb *palmas_usb;
int status;
......@@ -178,9 +178,10 @@ static int palmas_usb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, palmas_usb);
palmas_usb->edev.supported_cable = palmas_extcon_cable;
palmas_usb->edev.dev.parent = palmas_usb->dev;
palmas_usb->edev.mutually_exclusive = mutually_exclusive;
status = extcon_dev_register(&palmas_usb->edev, palmas_usb->dev);
status = extcon_dev_register(&palmas_usb->edev);
if (status) {
dev_err(&pdev->dev, "failed to register extcon device\n");
return status;
......
......@@ -47,8 +47,8 @@ static void vmbus_setevent(struct vmbus_channel *channel)
(unsigned long *) vmbus_connection.send_int_page +
(channel->offermsg.child_relid >> 5));
monitorpage = vmbus_connection.monitor_pages;
monitorpage++; /* Get the child to parent monitor page */
/* Get the child to parent monitor page */
monitorpage = vmbus_connection.monitor_pages[1];
sync_set_bit(channel->monitor_bit,
(unsigned long *)&monitorpage->trigger_group
......@@ -59,50 +59,6 @@ static void vmbus_setevent(struct vmbus_channel *channel)
}
}
/*
* vmbus_get_debug_info -Retrieve various channel debug info
*/
void vmbus_get_debug_info(struct vmbus_channel *channel,
struct vmbus_channel_debug_info *debuginfo)
{
struct hv_monitor_page *monitorpage;
u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
debuginfo->relid = channel->offermsg.child_relid;
debuginfo->state = channel->state;
memcpy(&debuginfo->interfacetype,
&channel->offermsg.offer.if_type, sizeof(uuid_le));
memcpy(&debuginfo->interface_instance,
&channel->offermsg.offer.if_instance,
sizeof(uuid_le));
monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
debuginfo->monitorid = channel->offermsg.monitorid;
debuginfo->servermonitor_pending =
monitorpage->trigger_group[monitor_group].pending;
debuginfo->servermonitor_latency =
monitorpage->latency[monitor_group][monitor_offset];
debuginfo->servermonitor_connectionid =
monitorpage->parameter[monitor_group]
[monitor_offset].connectionid.u.id;
monitorpage++;
debuginfo->clientmonitor_pending =
monitorpage->trigger_group[monitor_group].pending;
debuginfo->clientmonitor_latency =
monitorpage->latency[monitor_group][monitor_offset];
debuginfo->clientmonitor_connectionid =
monitorpage->parameter[monitor_group]
[monitor_offset].connectionid.u.id;
hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
}
/*
* vmbus_open - Open the specified channel.
*/
......@@ -855,6 +811,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
if (signal)
vmbus_setevent(channel);
return 0;
return ret;
}
EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
......@@ -203,7 +203,8 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
struct vmbus_channel *primary_channel;
struct vmbus_channel_relid_released msg;
vmbus_device_unregister(channel->device_obj);
if (channel->device_obj)
vmbus_device_unregister(channel->device_obj);
memset(&msg, 0, sizeof(struct vmbus_channel_relid_released));
msg.child_relid = channel->offermsg.child_relid;
msg.header.msgtype = CHANNELMSG_RELID_RELEASED;
......@@ -216,7 +217,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
} else {
primary_channel = channel->primary_channel;
spin_lock_irqsave(&primary_channel->sc_lock, flags);
list_del(&channel->listentry);
list_del(&channel->sc_list);
spin_unlock_irqrestore(&primary_channel->sc_lock, flags);
}
free_channel(channel);
......
......@@ -76,10 +76,8 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT;
msg->vmbus_version_requested = version;
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages);
msg->monitor_page2 = virt_to_phys(
(void *)((unsigned long)vmbus_connection.monitor_pages +
PAGE_SIZE));
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
/*
* Add to list before we send the request since we may
......@@ -169,9 +167,10 @@ int vmbus_connect(void)
* Setup the monitor notification facility. The 1st page for
* parent->child and the 2nd page for child->parent
*/
vmbus_connection.monitor_pages =
(void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
if (vmbus_connection.monitor_pages == NULL) {
vmbus_connection.monitor_pages[0] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
vmbus_connection.monitor_pages[1] = (void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 0);
if ((vmbus_connection.monitor_pages[0] == NULL) ||
(vmbus_connection.monitor_pages[1] == NULL)) {
ret = -ENOMEM;
goto cleanup;
}
......@@ -229,10 +228,10 @@ int vmbus_connect(void)
vmbus_connection.int_page = NULL;
}
if (vmbus_connection.monitor_pages) {
free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
vmbus_connection.monitor_pages = NULL;
}
free_pages((unsigned long)vmbus_connection.monitor_pages[0], 1);
free_pages((unsigned long)vmbus_connection.monitor_pages[1], 1);
vmbus_connection.monitor_pages[0] = NULL;
vmbus_connection.monitor_pages[1] = NULL;
kfree(msginfo);
......
......@@ -304,7 +304,7 @@ int hv_synic_alloc(void)
void hv_synic_free_cpu(int cpu)
{
kfree(hv_context.event_dpc[cpu]);
if (hv_context.synic_message_page[cpu])
if (hv_context.synic_event_page[cpu])
free_page((unsigned long)hv_context.synic_event_page[cpu]);
if (hv_context.synic_message_page[cpu])
free_page((unsigned long)hv_context.synic_message_page[cpu]);
......
......@@ -97,7 +97,7 @@ static void shutdown_onchannelcallback(void *context)
struct vmbus_channel *channel = context;
u32 recvlen;
u64 requestid;
u8 execute_shutdown = false;
bool execute_shutdown = false;
u8 *shut_txf_buf = util_shutdown.recv_buffer;
struct shutdown_msg_data *shutdown_msg;
......
......@@ -514,6 +514,13 @@ struct hv_context {
extern struct hv_context hv_context;
struct hv_ring_buffer_debug_info {
u32 current_interrupt_mask;
u32 current_read_index;
u32 current_write_index;
u32 bytes_avail_toread;
u32 bytes_avail_towrite;
};
/* Hv Interface */
......@@ -612,7 +619,7 @@ struct vmbus_connection {
* 2 pages - 1st page for parent->child notification and 2nd
* is child->parent notification
*/
void *monitor_pages;
struct hv_monitor_page *monitor_pages[2];
struct list_head chn_msg_list;
spinlock_t channelmsg_lock;
......
This diff is collapsed.
......@@ -537,4 +537,5 @@ source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig"
source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig"
source "drivers/misc/mic/Kconfig"
endmenu
......@@ -53,3 +53,4 @@ obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
......@@ -297,7 +297,7 @@ static int __init charlcd_probe(struct platform_device *pdev)
lcd->irq = platform_get_irq(pdev, 0);
/* If no IRQ is supplied, we'll survive without it */
if (lcd->irq >= 0) {
if (request_irq(lcd->irq, charlcd_interrupt, IRQF_DISABLED,
if (request_irq(lcd->irq, charlcd_interrupt, 0,
DRIVERNAME, lcd)) {
ret = -EIO;
goto out_no_irq;
......
......@@ -90,8 +90,10 @@ int pwm_channel_alloc(int index, struct pwm_channel *ch)
unsigned long flags;
int status = 0;
/* insist on PWM init, with this signal pinned out */
if (!pwm || !(pwm->mask & 1 << index))
if (!pwm)
return -EPROBE_DEFER;
if (!(pwm->mask & 1 << index))
return -ENODEV;
if (index < 0 || index >= PWM_NCHAN || !ch)
......
......@@ -23,6 +23,7 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#define BH1780_REG_CONTROL 0x80
#define BH1780_REG_PARTID 0x8A
......@@ -244,6 +245,15 @@ static const struct i2c_device_id bh1780_id[] = {
{ },
};
#ifdef CONFIG_OF
static const struct of_device_id of_bh1780_match[] = {
{ .compatible = "rohm,bh1780gli", },
{},
};
MODULE_DEVICE_TABLE(of, of_bh1780_match);
#endif
static struct i2c_driver bh1780_driver = {
.probe = bh1780_probe,
.remove = bh1780_remove,
......@@ -251,6 +261,7 @@ static struct i2c_driver bh1780_driver = {
.driver = {
.name = "bh1780",
.pm = &bh1780_pm,
.of_match_table = of_match_ptr(of_bh1780_match),
},
};
......
......@@ -374,7 +374,7 @@ int bmp085_detect(struct device *dev)
}
EXPORT_SYMBOL_GPL(bmp085_detect);
static void __init bmp085_get_of_properties(struct bmp085_data *data)
static void bmp085_get_of_properties(struct bmp085_data *data)
{
#ifdef CONFIG_OF
struct device_node *np = data->dev->of_node;
......
......@@ -176,7 +176,7 @@ static int cb710_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct cb710_chip *chip = pci_get_drvdata(pdev);
free_irq(pdev->irq, chip);
devm_free_irq(&pdev->dev, pdev->irq, chip);
pci_save_state(pdev);
pci_disable_device(pdev);
if (state.event & PM_EVENT_SLEEP)
......
......@@ -96,4 +96,17 @@ config EEPROM_DIGSY_MTC_CFG
If unsure, say N.
config EEPROM_SUNXI_SID
tristate "Allwinner sunxi security ID support"
depends on ARCH_SUNXI && SYSFS
help
This is a driver for the 'security ID' available on various Allwinner
devices.
Due to the potential risks involved with changing e-fuses,
this driver is read-only.
This driver can also be built as a module. If so, the module
will be called sunxi_sid.
endmenu
......@@ -4,4 +4,5 @@ obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
obj-$(CONFIG_EEPROM_93XX46) += eeprom_93xx46.o
obj-$(CONFIG_EEPROM_SUNXI_SID) += sunxi_sid.o
obj-$(CONFIG_EEPROM_DIGSY_MTC_CFG) += digsy_mtc_eeprom.o
......@@ -428,6 +428,9 @@ static ssize_t at24_bin_write(struct file *filp, struct kobject *kobj,
{
struct at24_data *at24;
if (unlikely(off >= attr->size))
return -EFBIG;
at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
return at24_write(at24, buf, off, count);
}
......
......@@ -462,10 +462,17 @@ static int at25_remove(struct spi_device *spi)
/*-------------------------------------------------------------------------*/
static const struct of_device_id at25_of_match[] = {
{ .compatible = "atmel,at25", },
{ }
};
MODULE_DEVICE_TABLE(of, at25_of_match);
static struct spi_driver at25_driver = {
.driver = {
.name = "at25",
.owner = THIS_MODULE,
.of_match_table = at25_of_match,
},
.probe = at25_probe,
.remove = at25_remove,
......
......@@ -202,7 +202,7 @@ eeprom_93xx46_bin_write(struct file *filp, struct kobject *kobj,
edev = dev_get_drvdata(dev);
if (unlikely(off >= edev->bin.size))
return 0;
return -EFBIG;
if ((off + count) > edev->bin.size)
count = edev->bin.size - off;
if (unlikely(!count))
......
/*
* Copyright (c) 2013 Oliver Schinagl <oliver@schinagl.nl>
* http://www.linux-sunxi.org
*
* 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.
*
* This driver exposes the Allwinner security ID, efuses exported in byte-
* sized chunks.
*/
#include <linux/compiler.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#define DRV_NAME "sunxi-sid"
struct sunxi_sid_data {
void __iomem *reg_base;
unsigned int keysize;
};
/* We read the entire key, due to a 32 bit read alignment requirement. Since we
* want to return the requested byte, this results in somewhat slower code and
* uses 4 times more reads as needed but keeps code simpler. Since the SID is
* only very rarely probed, this is not really an issue.
*/
static u8 sunxi_sid_read_byte(const struct sunxi_sid_data *sid_data,
const unsigned int offset)
{
u32 sid_key;
if (offset >= sid_data->keysize)
return 0;
sid_key = ioread32be(sid_data->reg_base + round_down(offset, 4));
sid_key >>= (offset % 4) * 8;
return sid_key; /* Only return the last byte */
}
static ssize_t sid_read(struct file *fd, struct kobject *kobj,
struct bin_attribute *attr, char *buf,
loff_t pos, size_t size)
{
struct platform_device *pdev;
struct sunxi_sid_data *sid_data;
int i;
pdev = to_platform_device(kobj_to_dev(kobj));
sid_data = platform_get_drvdata(pdev);
if (pos < 0 || pos >= sid_data->keysize)
return 0;
if (size > sid_data->keysize - pos)
size = sid_data->keysize - pos;
for (i = 0; i < size; i++)
buf[i] = sunxi_sid_read_byte(sid_data, pos + i);
return i;
}
static struct bin_attribute sid_bin_attr = {
.attr = { .name = "eeprom", .mode = S_IRUGO, },
.read = sid_read,
};
static int sunxi_sid_remove(struct platform_device *pdev)
{
device_remove_bin_file(&pdev->dev, &sid_bin_attr);
dev_dbg(&pdev->dev, "driver unloaded\n");
return 0;
}
static const struct of_device_id sunxi_sid_of_match[] = {
{ .compatible = "allwinner,sun4i-sid", .data = (void *)16},
{ .compatible = "allwinner,sun7i-a20-sid", .data = (void *)512},
{/* sentinel */},
};
MODULE_DEVICE_TABLE(of, sunxi_sid_of_match);
static int sunxi_sid_probe(struct platform_device *pdev)
{
struct sunxi_sid_data *sid_data;
struct resource *res;
const struct of_device_id *of_dev_id;
u8 *entropy;
unsigned int i;
sid_data = devm_kzalloc(&pdev->dev, sizeof(struct sunxi_sid_data),
GFP_KERNEL);
if (!sid_data)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
sid_data->reg_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sid_data->reg_base))
return PTR_ERR(sid_data->reg_base);
of_dev_id = of_match_device(sunxi_sid_of_match, &pdev->dev);
if (!of_dev_id)
return -ENODEV;
sid_data->keysize = (int)of_dev_id->data;
platform_set_drvdata(pdev, sid_data);
sid_bin_attr.size = sid_data->keysize;
if (device_create_bin_file(&pdev->dev, &sid_bin_attr))
return -ENODEV;
entropy = kzalloc(sizeof(u8) * sid_data->keysize, GFP_KERNEL);
for (i = 0; i < sid_data->keysize; i++)
entropy[i] = sunxi_sid_read_byte(sid_data, i);
add_device_randomness(entropy, sid_data->keysize);
kfree(entropy);
dev_dbg(&pdev->dev, "loaded\n");
return 0;
}
static struct platform_driver sunxi_sid_driver = {
.probe = sunxi_sid_probe,
.remove = sunxi_sid_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = sunxi_sid_of_match,
},
};
module_platform_driver(sunxi_sid_driver);
MODULE_AUTHOR("Oliver Schinagl <oliver@schinagl.nl>");
MODULE_DESCRIPTION("Allwinner sunxi security id driver");
MODULE_LICENSE("GPL");
......@@ -153,7 +153,6 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
error_heartbeat:
ibmasm_event_buffer_exit(sp);
error_eventbuffer:
pci_set_drvdata(pdev, NULL);
kfree(sp);
error_kmalloc:
pci_release_regions(pdev);
......@@ -165,7 +164,7 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static void ibmasm_remove_one(struct pci_dev *pdev)
{
struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
struct service_processor *sp = pci_get_drvdata(pdev);
dbg("Unregistering UART\n");
ibmasm_unregister_uart(sp);
......@@ -182,7 +181,6 @@ static void ibmasm_remove_one(struct pci_dev *pdev)
ibmasm_free_remote_input_dev(sp);
iounmap(sp->base_address);
ibmasm_event_buffer_exit(sp);
pci_set_drvdata(pdev, NULL);
kfree(sp);
pci_release_regions(pdev);
pci_disable_device(pdev);
......
......@@ -44,13 +44,25 @@
#include <scsi/scsi_cmnd.h>
#include <linux/debugfs.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#ifdef CONFIG_IDE
#include <linux/ide.h>
#endif
/*
* Make sure our attempts to over run the kernel stack doesn't trigger
* a compiler warning when CONFIG_FRAME_WARN is set. Then make sure we
* recurse past the end of THREAD_SIZE by default.
*/
#if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0)
#define REC_STACK_SIZE (CONFIG_FRAME_WARN / 2)
#else
#define REC_STACK_SIZE (THREAD_SIZE / 8)
#endif
#define REC_NUM_DEFAULT ((THREAD_SIZE / REC_STACK_SIZE) * 2)
#define DEFAULT_COUNT 10
#define REC_NUM_DEFAULT 10
#define EXEC_SIZE 64
enum cname {
......@@ -86,6 +98,9 @@ enum ctype {
CT_EXEC_STACK,
CT_EXEC_KMALLOC,
CT_EXEC_VMALLOC,
CT_EXEC_USERSPACE,
CT_ACCESS_USERSPACE,
CT_WRITE_RO,
};
static char* cp_name[] = {
......@@ -119,6 +134,9 @@ static char* cp_type[] = {
"EXEC_STACK",
"EXEC_KMALLOC",
"EXEC_VMALLOC",
"EXEC_USERSPACE",
"ACCESS_USERSPACE",
"WRITE_RO",
};
static struct jprobe lkdtm;
......@@ -139,9 +157,10 @@ static DEFINE_SPINLOCK(lock_me_up);
static u8 data_area[EXEC_SIZE];
static const unsigned long rodata = 0xAA55AA55;
module_param(recur_count, int, 0644);
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
"default is 10");
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
module_param(cpoint_name, charp, 0444);
MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
module_param(cpoint_type, charp, 0444);
......@@ -280,16 +299,16 @@ static int lkdtm_parse_commandline(void)
return -EINVAL;
}
static int recursive_loop(int a)
static int recursive_loop(int remaining)
{
char buf[1024];
char buf[REC_STACK_SIZE];
memset(buf,0xFF,1024);
recur_count--;
if (!recur_count)
/* Make sure compiler does not optimize this away. */
memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE);
if (!remaining)
return 0;
else
return recursive_loop(a);
return recursive_loop(remaining - 1);
}
static void do_nothing(void)
......@@ -297,6 +316,14 @@ static void do_nothing(void)
return;
}
static noinline void corrupt_stack(void)
{
/* Use default char array length that triggers stack protection. */
char data[8];
memset((void *)data, 0, 64);
}
static void execute_location(void *dst)
{
void (*func)(void) = dst;
......@@ -305,6 +332,15 @@ static void execute_location(void *dst)
func();
}
static void execute_user_location(void *dst)
{
void (*func)(void) = dst;
if (copy_to_user(dst, do_nothing, EXEC_SIZE))
return;
func();
}
static void lkdtm_do_action(enum ctype which)
{
switch (which) {
......@@ -325,15 +361,11 @@ static void lkdtm_do_action(enum ctype which)
;
break;
case CT_OVERFLOW:
(void) recursive_loop(0);
(void) recursive_loop(recur_count);
break;
case CT_CORRUPT_STACK: {
/* Make sure the compiler creates and uses an 8 char array. */
volatile char data[8];
memset((void *)data, 0, 64);
case CT_CORRUPT_STACK:
corrupt_stack();
break;
}
case CT_UNALIGNED_LOAD_STORE_WRITE: {
static u8 data[5] __attribute__((aligned(4))) = {1, 2,
3, 4, 5};
......@@ -401,6 +433,49 @@ static void lkdtm_do_action(enum ctype which)
vfree(vmalloc_area);
break;
}
case CT_EXEC_USERSPACE: {
unsigned long user_addr;
user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, 0);
if (user_addr >= TASK_SIZE) {
pr_warn("Failed to allocate user memory\n");
return;
}
execute_user_location((void *)user_addr);
vm_munmap(user_addr, PAGE_SIZE);
break;
}
case CT_ACCESS_USERSPACE: {
unsigned long user_addr, tmp;
unsigned long *ptr;
user_addr = vm_mmap(NULL, 0, PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, 0);
if (user_addr >= TASK_SIZE) {
pr_warn("Failed to allocate user memory\n");
return;
}
ptr = (unsigned long *)user_addr;
tmp = *ptr;
tmp += 0xc0dec0de;
*ptr = tmp;
vm_munmap(user_addr, PAGE_SIZE);
break;
}
case CT_WRITE_RO: {
unsigned long *ptr;
ptr = (unsigned long *)&rodata;
*ptr ^= 0xabcd1234;
break;
}
case CT_NONE:
default:
break;
......
......@@ -58,6 +58,7 @@ void mei_amthif_reset_params(struct mei_device *dev)
dev->iamthif_state = MEI_IAMTHIF_IDLE;
dev->iamthif_timer = 0;
dev->iamthif_stall_timer = 0;
dev->iamthif_open_count = 0;
}
/**
......@@ -78,8 +79,10 @@ int mei_amthif_host_init(struct mei_device *dev)
i = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
if (i < 0) {
dev_info(&dev->pdev->dev, "amthif: failed to find the client\n");
return -ENOENT;
ret = i;
dev_info(&dev->pdev->dev,
"amthif: failed to find the client %d\n", ret);
return ret;
}
cl->me_client_id = dev->me_clients[i].client_id;
......@@ -106,8 +109,9 @@ int mei_amthif_host_init(struct mei_device *dev)
ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
if (ret < 0) {
dev_err(&dev->pdev->dev, "amthif: failed link client\n");
return -ENOENT;
dev_err(&dev->pdev->dev,
"amthif: failed link client %d\n", ret);
return ret;
}
cl->state = MEI_FILE_CONNECTING;
......@@ -313,13 +317,13 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
mei_hdr.reserved = 0;
dev->iamthif_msg_buf_index += mei_hdr.length;
if (mei_write_message(dev, &mei_hdr,
(unsigned char *)dev->iamthif_msg_buf))
return -ENODEV;
ret = mei_write_message(dev, &mei_hdr, dev->iamthif_msg_buf);
if (ret)
return ret;
if (mei_hdr.msg_complete) {
if (mei_cl_flow_ctrl_reduce(&dev->iamthif_cl))
return -ENODEV;
return -EIO;
dev->iamthif_flow_control_pending = true;
dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
dev_dbg(&dev->pdev->dev, "add amthif cb to write waiting list\n");
......@@ -459,6 +463,16 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
struct mei_msg_hdr mei_hdr;
size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
u32 msg_slots = mei_data2slots(len);
int rets;
rets = mei_cl_flow_ctrl_creds(cl);
if (rets < 0)
return rets;
if (rets == 0) {
cl_dbg(dev, cl, "No flow control credentials: not sending.\n");
return 0;
}
mei_hdr.host_addr = cl->host_client_id;
mei_hdr.me_addr = cl->me_client_id;
......@@ -481,16 +495,17 @@ int mei_amthif_irq_write_complete(struct mei_cl *cl, struct mei_cl_cb *cb,
dev_dbg(&dev->pdev->dev, MEI_HDR_FMT, MEI_HDR_PRM(&mei_hdr));
*slots -= msg_slots;
if (mei_write_message(dev, &mei_hdr,
dev->iamthif_msg_buf + dev->iamthif_msg_buf_index)) {
dev->iamthif_state = MEI_IAMTHIF_IDLE;
cl->status = -ENODEV;
list_del(&cb->list);
return -ENODEV;
rets = mei_write_message(dev, &mei_hdr,
dev->iamthif_msg_buf + dev->iamthif_msg_buf_index);
if (rets) {
dev->iamthif_state = MEI_IAMTHIF_IDLE;
cl->status = rets;
list_del(&cb->list);
return rets;
}
if (mei_cl_flow_ctrl_reduce(cl))
return -ENODEV;
return -EIO;
dev->iamthif_msg_buf_index += mei_hdr.length;
cl->status = 0;
......@@ -720,8 +735,8 @@ static bool mei_clear_lists(struct mei_device *dev, struct file *file)
*/
int mei_amthif_release(struct mei_device *dev, struct file *file)
{
if (dev->open_handle_count > 0)
dev->open_handle_count--;
if (dev->iamthif_open_count > 0)
dev->iamthif_open_count--;
if (dev->iamthif_file_object == file &&
dev->iamthif_state != MEI_IAMTHIF_IDLE) {
......
......@@ -245,7 +245,7 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
/* Check if we have an ME client device */
id = mei_me_cl_by_id(dev, cl->me_client_id);
if (id < 0)
return -ENODEV;
return id;
if (length > dev->me_clients[id].props.max_msg_length)
return -EINVAL;
......
This diff is collapsed.
......@@ -115,4 +115,13 @@ void mei_cl_all_disconnect(struct mei_device *dev);
void mei_cl_all_wakeup(struct mei_device *dev);
void mei_cl_all_write_clear(struct mei_device *dev);
#define MEI_CL_FMT "cl:host=%02d me=%02d "
#define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id
#define cl_dbg(dev, cl, format, arg...) \
dev_dbg(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
#define cl_err(dev, cl, format, arg...) \
dev_err(&(dev)->pdev->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
#endif /* _MEI_CLIENT_H_ */
......@@ -49,7 +49,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
kfree(dev->me_clients);
dev->me_clients = NULL;
dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
dev->me_clients_num * sizeof(struct mei_me_client));
/* allocate storage for ME clients representation */
clients = kcalloc(dev->me_clients_num,
......@@ -174,7 +174,7 @@ int mei_hbm_start_req(struct mei_device *dev)
dev_err(&dev->pdev->dev, "version message write failed\n");
dev->dev_state = MEI_DEV_RESETTING;
mei_reset(dev, 1);
return -ENODEV;
return -EIO;
}
dev->hbm_state = MEI_HBM_START;
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
......@@ -677,7 +677,10 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
case HOST_ENUM_RES_CMD:
enum_res = (struct hbm_host_enum_response *) mei_msg;
memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
BUILD_BUG_ON(sizeof(dev->me_clients_map)
< sizeof(enum_res->valid_addresses));
memcpy(dev->me_clients_map, enum_res->valid_addresses,
sizeof(enum_res->valid_addresses));
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
dev->init_clients_timer = 0;
......
......@@ -110,6 +110,7 @@
#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
#define MEI_DEV_ID_LPT_W 0x8D3A /* Lynx Point - Wellsburg */
#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
/*
* MEI HW Section
......
......@@ -68,6 +68,14 @@ void mei_device_init(struct mei_device *dev)
mei_io_list_init(&dev->amthif_cmd_list);
mei_io_list_init(&dev->amthif_rd_complete_list);
bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
dev->open_handle_count = 0;
/*
* Reserving the first client ID
* 0: Reserved for MEI Bus Message communications
*/
bitmap_set(dev->host_clients_map, 0, 1);
}
EXPORT_SYMBOL_GPL(mei_device_init);
......@@ -139,6 +147,10 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->dev_state != MEI_DEV_POWER_DOWN &&
dev->dev_state != MEI_DEV_POWER_UP);
if (unexpected)
dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
ret = mei_hw_reset(dev, interrupts_enabled);
if (ret) {
dev_err(&dev->pdev->dev, "hw reset failed disabling the device\n");
......@@ -165,12 +177,7 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
/* remove entry if already in list */
dev_dbg(&dev->pdev->dev, "remove iamthif and wd from the file list.\n");
mei_cl_unlink(&dev->wd_cl);
if (dev->open_handle_count > 0)
dev->open_handle_count--;
mei_cl_unlink(&dev->iamthif_cl);
if (dev->open_handle_count > 0)
dev->open_handle_count--;
mei_amthif_reset_params(dev);
memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
}
......@@ -182,10 +189,6 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
dev->rd_msg_hdr = 0;
dev->wd_pending = false;
if (unexpected)
dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
mei_dev_state_str(dev->dev_state));
if (!interrupts_enabled) {
dev_dbg(&dev->pdev->dev, "intr not enabled end of reset\n");
return;
......
This diff is collapsed.
This diff is collapsed.
......@@ -414,6 +414,7 @@ struct mei_device {
struct file *iamthif_file_object;
struct mei_cl iamthif_cl;
struct mei_cl_cb *iamthif_current_cb;
long iamthif_open_count;
int iamthif_mtu;
unsigned long iamthif_timer;
u32 iamthif_stall_timer;
......
......@@ -485,8 +485,11 @@ int mei_nfc_host_init(struct mei_device *dev)
if (ndev->cl_info)
return 0;
cl_info = mei_cl_allocate(dev);
cl = mei_cl_allocate(dev);
ndev->cl_info = mei_cl_allocate(dev);
ndev->cl = mei_cl_allocate(dev);
cl = ndev->cl;
cl_info = ndev->cl_info;
if (!cl || !cl_info) {
ret = -ENOMEM;
......@@ -527,10 +530,9 @@ int mei_nfc_host_init(struct mei_device *dev)
cl->device_uuid = mei_nfc_guid;
list_add_tail(&cl->device_link, &dev->device_list);
ndev->cl_info = cl_info;
ndev->cl = cl;
ndev->req_id = 1;
INIT_WORK(&ndev->init_work, mei_nfc_init);
......
......@@ -77,6 +77,7 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
/* required last entry */
......@@ -189,7 +190,7 @@ static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
schedule_delayed_work(&dev->timer_work, HZ);
pr_debug("initialization successful.\n");
dev_dbg(&pdev->dev, "initialization successful.\n");
return 0;
......@@ -231,7 +232,7 @@ static void mei_me_remove(struct pci_dev *pdev)
hw = to_me_hw(dev);
dev_err(&pdev->dev, "stop\n");
dev_dbg(&pdev->dev, "stop\n");
mei_stop(dev);
/* disable interrupts */
......@@ -239,7 +240,6 @@ static void mei_me_remove(struct pci_dev *pdev)
free_irq(pdev->irq, dev);
pci_disable_msi(pdev);
pci_set_drvdata(pdev, NULL);
if (hw->mem_addr)
pci_iounmap(pdev, hw->mem_addr);
......@@ -262,7 +262,7 @@ static int mei_me_pci_suspend(struct device *device)
if (!dev)
return -ENODEV;
dev_err(&pdev->dev, "suspend\n");
dev_dbg(&pdev->dev, "suspend\n");
mei_stop(dev);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment