Commit d8782381 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull char/misc driver updates from Greg KH:
 "Here's the big char/misc driver pull request for 4.2-rc1.

  Lots of mei, extcon, coresight, uio, mic, and other driver updates in
  here.  Full details in the shortlog.  All of these have been in
  linux-next for some time with no reported problems"

* tag 'char-misc-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (176 commits)
  mei: me: wait for power gating exit confirmation
  mei: reset flow control on the last client disconnection
  MAINTAINERS: mei: add mei_cl_bus.h to maintained file list
  misc: sram: sort and clean up included headers
  misc: sram: move reserved block logic out of probe function
  misc: sram: add private struct device and virt_base members
  misc: sram: report correct SRAM pool size
  misc: sram: bump error message level on unclean driver unbinding
  misc: sram: fix device node reference leak on error
  misc: sram: fix enabled clock leak on error path
  misc: mic: Fix reported static checker warning
  misc: mic: Fix randconfig build error by including errno.h
  uio: pruss: Drop depends on ARCH_DAVINCI_DA850 from config
  uio: pruss: Add CONFIG_HAS_IOMEM dependence
  uio: pruss: Include <linux/sizes.h>
  extcon: Redefine the unique id of supported external connectors without 'enum extcon' type
  char:xilinx_hwicap:buffer_icap - change 1/0 to true/false for bool type variable in function buffer_icap_set_configuration().
  Drivers: hv: vmbus: Allocate ring buffer memory in NUMA aware fashion
  parport: check exclusive access before register
  w1: use correct lock on error in w1_seq_show()
  ...
parents e3826082 3dc196ea
What: /sys/bus/w1/devices/.../w1_master_timeout_us
Date: April 2015
Contact: Dmitry Khromov <dk@icelogic.net>
Description: Bus scanning interval, microseconds component.
Some of 1-Wire devices commonly associated with physical access
control systems are attached/generate presence for as short as
100 ms - hence the tens-to-hundreds milliseconds scan intervals
are required.
see Documentation/w1/w1.generic for detailed information.
Users: any user space application which wants to know bus scanning
interval
What: /sys/bus/w1/devices/.../w1_seq
Date: Apr 2015
Contact: Matt Campbell <mattrcampbell@gmail.com>
Description: Support for the DS28EA00 chain sequence function
see Documentation/w1/slaves/w1_therm for detailed information
Users: any user space application which wants to communicate with DS28EA00
This diff is collapsed.
...@@ -4,4 +4,18 @@ KernelVersion: 3.10 ...@@ -4,4 +4,18 @@ KernelVersion: 3.10
Contact: Samuel Ortiz <sameo@linux.intel.com> Contact: Samuel Ortiz <sameo@linux.intel.com>
linux-mei@linux.intel.com linux-mei@linux.intel.com
Description: Stores the same MODALIAS value emitted by uevent Description: Stores the same MODALIAS value emitted by uevent
Format: mei:<mei device name> Format: mei:<mei device name>:<device uuid>:
What: /sys/bus/mei/devices/.../name
Date: May 2015
KernelVersion: 4.2
Contact: Tomas Winkler <tomas.winkler@intel.com>
Description: Stores mei client device name
Format: string
What: /sys/bus/mei/devices/.../uuid
Date: May 2015
KernelVersion: 4.2
Contact: Tomas Winkler <tomas.winkler@intel.com>
Description: Stores mei client device uuid
Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
...@@ -17,15 +17,19 @@ its hardware characteristcs. ...@@ -17,15 +17,19 @@ its hardware characteristcs.
- "arm,coresight-tmc", "arm,primecell"; - "arm,coresight-tmc", "arm,primecell";
- "arm,coresight-funnel", "arm,primecell"; - "arm,coresight-funnel", "arm,primecell";
- "arm,coresight-etm3x", "arm,primecell"; - "arm,coresight-etm3x", "arm,primecell";
- "qcom,coresight-replicator1x", "arm,primecell";
* reg: physical base address and length of the register * reg: physical base address and length of the register
set(s) of the component. set(s) of the component.
* clocks: the clock associated to this component. * clocks: the clocks associated to this component.
* clock-names: the name of the clock as referenced by the code. * clock-names: the name of the clocks referenced by the code.
Since we are using the AMBA framework, the name should be Since we are using the AMBA framework, the name of the clock
"apb_pclk". providing the interconnect should be "apb_pclk", and some
coresight blocks also have an additional clock "atclk", which
clocks the core of that coresight component. The latter clock
is optional.
* port or ports: The representation of the component's port * port or ports: The representation of the component's port
layout using the generic DT graph presentation found in layout using the generic DT graph presentation found in
......
...@@ -67,6 +67,12 @@ Optional properties: ...@@ -67,6 +67,12 @@ Optional properties:
present, the number of values should be less than or equal to the present, the number of values should be less than or equal to the
number of inputs, unspecified inputs will use the chip default. number of inputs, unspecified inputs will use the chip default.
- wlf,hpdet-channel : Headphone detection channel.
ARIZONA_ACCDET_MODE_HPL or 1 - Headphone detect mode is set to HPDETL
ARIZONA_ACCDET_MODE_HPR or 2 - Headphone detect mode is set to HPDETR
If this node is not mentioned or if the value is unknown, then
headphone detection mode is set to HPDETL.
- DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
they are being externally supplied. As covered in they are being externally supplied. As covered in
Documentation/devicetree/bindings/regulator/regulator.txt Documentation/devicetree/bindings/regulator/regulator.txt
......
...@@ -24,6 +24,10 @@ a virtual bus called mic bus is created and virtual dma devices are ...@@ -24,6 +24,10 @@ a virtual bus called mic bus is created and virtual dma devices are
created on it by the host/card drivers. On host the channels are private created on it by the host/card drivers. On host the channels are private
and used only by the host driver to transfer data for the virtio devices. and used only by the host driver to transfer data for the virtio devices.
The Symmetric Communication Interface (SCIF (pronounced as skiff)) is a
low level communications API across PCIe currently implemented for MIC.
More details are available at scif_overview.txt.
Here is a block diagram of the various components described above. The 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 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 single threaded performance for the host compared to MIC, the ability of
...@@ -47,18 +51,18 @@ the fact that the virtio block storage backend can only be on the host. ...@@ -47,18 +51,18 @@ the fact that the virtio block storage backend can only be on the host.
| | | Virtio over PCIe IOCTLs | | | | Virtio over PCIe IOCTLs |
| | +--------------------------+ | | +--------------------------+
+-----------+ | | | +-----------+ +-----------+ | | | +-----------+
| MIC DMA | | | | | MIC DMA | | MIC DMA | | +----------+ | +-----------+ | | MIC DMA |
| Driver | | | | | Driver | | Driver | | | SCIF | | | SCIF | | | Driver |
+-----------+ | | | +-----------+ +-----------+ | +----------+ | +-----------+ | +-----------+
| | | | | | | | | | | |
+---------------+ | | | +----------------+ +---------------+ | +-----+-----+ | +-----+-----+ | +---------------+
|MIC virtual Bus| | | | |MIC virtual Bus | |MIC virtual Bus| | |SCIF HW Bus| | |SCIF HW BUS| | |MIC virtual Bus|
+---------------+ | | | +----------------+ +---------------+ | +-----------+ | +-----+-----+ | +---------------+
| | | | | | | | | | | |
| +--------------+ | +---------------+ | | +--------------+ | | | +---------------+ |
| |Intel MIC | | |Intel MIC | | | |Intel MIC | | | | |Intel MIC | |
+---|Card Driver | | |Host Driver | | +---|Card Driver +----+ | | |Host Driver | |
+--------------+ | +---------------+-----+ +--------------+ | +----+---------------+-----+
| | | | | |
+-------------------------------------------------------------+ +-------------------------------------------------------------+
| | | |
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
exec=/usr/sbin/mpssd exec=/usr/sbin/mpssd
sysfs="/sys/class/mic" sysfs="/sys/class/mic"
mic_modules="mic_host mic_x100_dma scif"
start() start()
{ {
...@@ -48,18 +49,15 @@ start() ...@@ -48,18 +49,15 @@ start()
fi fi
echo -e $"Starting MPSS Stack" echo -e $"Starting MPSS Stack"
echo -e $"Loading MIC_X100_DMA & MIC_HOST Modules" echo -e $"Loading MIC drivers:" $mic_modules
for f in "mic_host" "mic_x100_dma" modprobe -a $mic_modules
do
modprobe $f
RETVAL=$? RETVAL=$?
if [ $RETVAL -ne 0 ]; then if [ $RETVAL -ne 0 ]; then
failure failure
echo echo
return $RETVAL return $RETVAL
fi fi
done
# Start the daemon # Start the daemon
echo -n $"Starting MPSSD " echo -n $"Starting MPSSD "
...@@ -170,8 +168,8 @@ unload() ...@@ -170,8 +168,8 @@ unload()
stop stop
sleep 5 sleep 5
echo -n $"Removing MIC_HOST & MIC_X100_DMA Modules: " echo -n $"Removing MIC drivers:" $mic_modules
modprobe -r mic_host mic_x100_dma modprobe -r $mic_modules
RETVAL=$? RETVAL=$?
[ $RETVAL -ne 0 ] && failure || success [ $RETVAL -ne 0 ] && failure || success
echo echo
......
The Symmetric Communication Interface (SCIF (pronounced as skiff)) is a low
level communications API across PCIe currently implemented for MIC. Currently
SCIF provides inter-node communication within a single host platform, where a
node is a MIC Coprocessor or Xeon based host. SCIF abstracts the details of
communicating over the PCIe bus while providing an API that is symmetric
across all the nodes in the PCIe network. An important design objective for SCIF
is to deliver the maximum possible performance given the communication
abilities of the hardware. SCIF has been used to implement an offload compiler
runtime and OFED support for MPI implementations for MIC coprocessors.
==== SCIF API Components ====
The SCIF API has the following parts:
1. Connection establishment using a client server model
2. Byte stream messaging intended for short messages
3. Node enumeration to determine online nodes
4. Poll semantics for detection of incoming connections and messages
5. Memory registration to pin down pages
6. Remote memory mapping for low latency CPU accesses via mmap
7. Remote DMA (RDMA) for high bandwidth DMA transfers
8. Fence APIs for RDMA synchronization
SCIF exposes the notion of a connection which can be used by peer processes on
nodes in a SCIF PCIe "network" to share memory "windows" and to communicate. A
process in a SCIF node initiates a SCIF connection to a peer process on a
different node via a SCIF "endpoint". SCIF endpoints support messaging APIs
which are similar to connection oriented socket APIs. Connected SCIF endpoints
can also register local memory which is followed by data transfer using either
DMA, CPU copies or remote memory mapping via mmap. SCIF supports both user and
kernel mode clients which are functionally equivalent.
==== SCIF Performance for MIC ====
DMA bandwidth comparison between the TCP (over ethernet over PCIe) stack versus
SCIF shows the performance advantages of SCIF for HPC applications and runtimes.
Comparison of TCP and SCIF based BW
Throughput (GB/sec)
8 + PCIe Bandwidth ******
+ TCP ######
7 + ************************************** SCIF %%%%%%
| %%%%%%%%%%%%%%%%%%%
6 + %%%%
| %%
| %%%
5 + %%
| %%
4 + %%
| %%
3 + %%
| %
2 + %%
| %%
| %
1 +
+ ######################################
0 +++---+++--+--+-+--+--+-++-+--+-++-+--+-++-+-
1 10 100 1000 10000 100000
Transfer Size (KBytes)
SCIF allows memory sharing via mmap(..) between processes on different PCIe
nodes and thus provides bare-metal PCIe latency. The round trip SCIF mmap
latency from the host to an x100 MIC for an 8 byte message is 0.44 usecs.
SCIF has a user space library which is a thin IOCTL wrapper providing a user
space API similar to the kernel API in scif.h. The SCIF user space library
is distributed @ https://software.intel.com/en-us/mic-developer
Here is some pseudo code for an example of how two applications on two PCIe
nodes would typically use the SCIF API:
Process A (on node A) Process B (on node B)
/* get online node information */
scif_get_node_ids(..) scif_get_node_ids(..)
scif_open(..) scif_open(..)
scif_bind(..) scif_bind(..)
scif_listen(..)
scif_accept(..) scif_connect(..)
/* SCIF connection established */
/* Send and receive short messages */
scif_send(..)/scif_recv(..) scif_send(..)/scif_recv(..)
/* Register memory */
scif_register(..) scif_register(..)
/* RDMA */
scif_readfrom(..)/scif_writeto(..) scif_readfrom(..)/scif_writeto(..)
/* Fence DMAs */
scif_fence_signal(..) scif_fence_signal(..)
mmap(..) mmap(..)
/* Access remote registered memory */
/* Close the endpoints */
scif_close(..) scif_close(..)
...@@ -11,12 +11,14 @@ Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> ...@@ -11,12 +11,14 @@ Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Description Description
----------- -----------
w1_therm provides basic temperature conversion for ds18*20 devices. w1_therm provides basic temperature conversion for ds18*20 devices, and the
ds28ea00 device.
supported family codes: supported family codes:
W1_THERM_DS18S20 0x10 W1_THERM_DS18S20 0x10
W1_THERM_DS1822 0x22 W1_THERM_DS1822 0x22
W1_THERM_DS18B20 0x28 W1_THERM_DS18B20 0x28
W1_THERM_DS1825 0x3B W1_THERM_DS1825 0x3B
W1_THERM_DS28EA00 0x42
Support is provided through the sysfs w1_slave file. Each open and Support is provided through the sysfs w1_slave file. Each open and
read sequence will initiate a temperature conversion then provide two read sequence will initiate a temperature conversion then provide two
...@@ -48,3 +50,10 @@ resistor). The DS18b20 temperature sensor specification lists a ...@@ -48,3 +50,10 @@ resistor). The DS18b20 temperature sensor specification lists a
maximum current draw of 1.5mA and that a 5k pullup resistor is not maximum current draw of 1.5mA and that a 5k pullup resistor is not
sufficient. The strong pullup is designed to provide the additional sufficient. The strong pullup is designed to provide the additional
current required. current required.
The DS28EA00 provides an additional two pins for implementing a sequence
detection algorithm. This feature allows you to determine the physical
location of the chip in the 1-wire bus without needing pre-existing
knowledge of the bus ordering. Support is provided through the sysfs
w1_seq file. The file will contain a single line with an integer value
representing the device index in the bus starting at 0.
...@@ -76,21 +76,24 @@ See struct w1_bus_master definition in w1.h for details. ...@@ -76,21 +76,24 @@ See struct w1_bus_master definition in w1.h for details.
w1 master sysfs interface w1 master sysfs interface
------------------------------------------------------------------ ------------------------------------------------------------------
<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial <xx-xxxxxxxxxxxxx> - A directory for a found device. The format is family-serial
bus - (standard) symlink to the w1 bus bus - (standard) symlink to the w1 bus
driver - (standard) symlink to the w1 driver driver - (standard) symlink to the w1 driver
w1_master_add - Manually register a slave device w1_master_add - (rw) manually register a slave device
w1_master_attempts - the number of times a search was attempted w1_master_attempts - (ro) the number of times a search was attempted
w1_master_max_slave_count w1_master_max_slave_count
- maximum number of slaves to search for at a time - (rw) maximum number of slaves to search for at a time
w1_master_name - the name of the device (w1_bus_masterX) w1_master_name - (ro) the name of the device (w1_bus_masterX)
w1_master_pullup - 5V strong pullup 0 enabled, 1 disabled w1_master_pullup - (rw) 5V strong pullup 0 enabled, 1 disabled
w1_master_remove - Manually remove a slave device w1_master_remove - (rw) manually remove a slave device
w1_master_search - the number of searches left to do, -1=continual (default) w1_master_search - (rw) the number of searches left to do,
-1=continual (default)
w1_master_slave_count w1_master_slave_count
- the number of slaves found - (ro) the number of slaves found
w1_master_slaves - the names of the slaves, one per line w1_master_slaves - (ro) the names of the slaves, one per line
w1_master_timeout - the delay in seconds between searches w1_master_timeout - (ro) the delay in seconds between searches
w1_master_timeout_us
- (ro) the delay in microseconds beetwen searches
If you have a w1 bus that never changes (you don't add or remove devices), If you have a w1 bus that never changes (you don't add or remove devices),
you can set the module parameter search_count to a small positive number you can set the module parameter search_count to a small positive number
...@@ -101,6 +104,11 @@ generally only make sense when searching is disabled, as a search will ...@@ -101,6 +104,11 @@ generally only make sense when searching is disabled, as a search will
redetect manually removed devices that are present and timeout manually redetect manually removed devices that are present and timeout manually
added devices that aren't on the bus. added devices that aren't on the bus.
Bus searches occur at an interval, specified as a summ of timeout and
timeout_us module parameters (either of which may be 0) for as long as
w1_master_search remains greater than 0 or is -1. Each search attempt
decrements w1_master_search by 1 (down to 0) and increments
w1_master_attempts by 1.
w1 slave sysfs interface w1 slave sysfs interface
------------------------------------------------------------------ ------------------------------------------------------------------
......
...@@ -732,7 +732,7 @@ ANDROID DRIVERS ...@@ -732,7 +732,7 @@ ANDROID DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
M: Arve Hjønnevåg <arve@android.com> M: Arve Hjønnevåg <arve@android.com>
M: Riley Andrews <riandrews@android.com> M: Riley Andrews <riandrews@android.com>
T: git git://git.kernel.org/pub/scm/linux/kernel/gregkh/staging.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
L: devel@driverdev.osuosl.org L: devel@driverdev.osuosl.org
S: Supported S: Supported
F: drivers/android/ F: drivers/android/
...@@ -3207,9 +3207,9 @@ S: Maintained ...@@ -3207,9 +3207,9 @@ S: Maintained
F: drivers/platform/x86/dell-smo8800.c F: drivers/platform/x86/dell-smo8800.c
DELL LAPTOP SMM DRIVER DELL LAPTOP SMM DRIVER
M: Guenter Roeck <linux@roeck-us.net> M: Pali Rohár <pali.rohar@gmail.com>
S: Maintained S: Maintained
F: drivers/char/i8k.c F: drivers/hwmon/dell-smm-hwmon.c
F: include/uapi/linux/i8k.h F: include/uapi/linux/i8k.h
DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas) DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
...@@ -5444,6 +5444,7 @@ M: Tomas Winkler <tomas.winkler@intel.com> ...@@ -5444,6 +5444,7 @@ M: Tomas Winkler <tomas.winkler@intel.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
S: Supported S: Supported
F: include/uapi/linux/mei.h F: include/uapi/linux/mei.h
F: include/linux/mei_cl_bus.h
F: drivers/misc/mei/* F: drivers/misc/mei/*
F: Documentation/misc-devices/mei/* F: Documentation/misc-devices/mei/*
...@@ -7572,13 +7573,16 @@ S: Maintained ...@@ -7572,13 +7573,16 @@ S: Maintained
F: Documentation/mn10300/ F: Documentation/mn10300/
F: arch/mn10300/ F: arch/mn10300/
PARALLEL PORT SUPPORT PARALLEL PORT SUBSYSTEM
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
M: Sudip Mukherjee <sudip@vectorindia.org>
L: linux-parport@lists.infradead.org (subscribers-only) L: linux-parport@lists.infradead.org (subscribers-only)
S: Orphan S: Maintained
F: drivers/parport/ F: drivers/parport/
F: include/linux/parport*.h F: include/linux/parport*.h
F: drivers/char/ppdev.c F: drivers/char/ppdev.c
F: include/uapi/linux/ppdev.h F: include/uapi/linux/ppdev.h
F: Documentation/parport*.txt
PARAVIRT_OPS INTERFACE PARAVIRT_OPS INTERFACE
M: Jeremy Fitzhardinge <jeremy@goop.org> M: Jeremy Fitzhardinge <jeremy@goop.org>
......
...@@ -105,7 +105,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, ...@@ -105,7 +105,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
sprintf(data_fd_buf, "%d", data_remote); sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION); sprintf(version_buf, "%d", UML_NET_VERSION);
if (gate != NULL) { if (gate != NULL) {
strcpy(gate_buf, gate); strncpy(gate_buf, gate, 15);
args = setup_args; args = setup_args;
} }
else args = nosetup_args; else args = nosetup_args;
......
...@@ -1055,24 +1055,19 @@ config TOSHIBA ...@@ -1055,24 +1055,19 @@ config TOSHIBA
Say N otherwise. Say N otherwise.
config I8K config I8K
tristate "Dell laptop support" tristate "Dell i8k legacy laptop support"
select HWMON select HWMON
select SENSORS_DELL_SMM
---help--- ---help---
This adds a driver to safely access the System Management Mode This option enables legacy /proc/i8k userspace interface in hwmon
of the CPU on the Dell Inspiron 8000. The System Management Mode dell-smm-hwmon driver. Character file /proc/i8k reports bios version,
is used to read cpu temperature and cooling fan status and to temperature and allows controlling fan speeds of Dell laptops via
control the fans on the I8K portables. System Management Mode. For old Dell laptops (like Dell Inspiron 8000)
it reports also power and hotkey status. For fan speed control is
needed userspace package i8kutils.
This driver has been tested only on the Inspiron 8000 but it may Say Y if you intend to run this kernel on old Dell laptops or want to
also work with other Dell laptops. You can force loading on other use userspace package i8kutils.
models by passing the parameter `force=1' to the module. Use at
your own risk.
For information on utilities to make use of this driver see the
I8K Linux utilities web site at:
<http://people.debian.org/~dz/i8k/>
Say Y if you intend to run this kernel on a Dell Inspiron 8000.
Say N otherwise. Say N otherwise.
config X86_REBOOTFIXUPS config X86_REBOOTFIXUPS
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/sched.h> /* TASK_* */ #include <linux/sched.h> /* TASK_* */
#include <linux/parport.h> #include <linux/parport.h>
#include <linux/slab.h>
#include "paride.h" #include "paride.h"
...@@ -244,17 +245,19 @@ void paride_unregister(PIP * pr) ...@@ -244,17 +245,19 @@ void paride_unregister(PIP * pr)
EXPORT_SYMBOL(paride_unregister); EXPORT_SYMBOL(paride_unregister);
static int pi_register_parport(PIA * pi, int verbose) static int pi_register_parport(PIA *pi, int verbose, int unit)
{ {
struct parport *port; struct parport *port;
struct pardev_cb par_cb;
port = parport_find_base(pi->port); port = parport_find_base(pi->port);
if (!port) if (!port)
return 0; return 0;
memset(&par_cb, 0, sizeof(par_cb));
pi->pardev = parport_register_device(port, par_cb.wakeup = pi_wake_up;
pi->device, NULL, par_cb.private = (void *)pi;
pi_wake_up, NULL, 0, (void *) pi); pi->pardev = parport_register_dev_model(port, pi->device, &par_cb,
unit);
parport_put_port(port); parport_put_port(port);
if (!pi->pardev) if (!pi->pardev)
return 0; return 0;
...@@ -311,7 +314,7 @@ static int pi_probe_unit(PIA * pi, int unit, char *scratch, int verbose) ...@@ -311,7 +314,7 @@ static int pi_probe_unit(PIA * pi, int unit, char *scratch, int verbose)
e = pi->proto->max_units; e = pi->proto->max_units;
} }
if (!pi_register_parport(pi, verbose)) if (!pi_register_parport(pi, verbose, s))
return 0; return 0;
if (pi->proto->test_port) { if (pi->proto->test_port) {
...@@ -432,3 +435,45 @@ int pi_init(PIA * pi, int autoprobe, int port, int mode, ...@@ -432,3 +435,45 @@ int pi_init(PIA * pi, int autoprobe, int port, int mode,
} }
EXPORT_SYMBOL(pi_init); EXPORT_SYMBOL(pi_init);
static int pi_probe(struct pardevice *par_dev)
{
struct device_driver *drv = par_dev->dev.driver;
int len = strlen(drv->name);
if (strncmp(par_dev->name, drv->name, len))
return -ENODEV;
return 0;
}
void *pi_register_driver(char *name)
{
struct parport_driver *parp_drv;
int ret;
parp_drv = kzalloc(sizeof(*parp_drv), GFP_KERNEL);
if (!parp_drv)
return NULL;
parp_drv->name = name;
parp_drv->probe = pi_probe;
parp_drv->devmodel = true;
ret = parport_register_driver(parp_drv);
if (ret) {
kfree(parp_drv);
return NULL;
}
return (void *)parp_drv;
}
EXPORT_SYMBOL(pi_register_driver);
void pi_unregister_driver(void *_drv)
{
struct parport_driver *drv = _drv;
parport_unregister_driver(drv);
kfree(drv);
}
EXPORT_SYMBOL(pi_unregister_driver);
...@@ -165,6 +165,8 @@ typedef struct pi_protocol PIP; ...@@ -165,6 +165,8 @@ typedef struct pi_protocol PIP;
extern int paride_register( PIP * ); extern int paride_register( PIP * );
extern void paride_unregister ( PIP * ); extern void paride_unregister ( PIP * );
void *pi_register_driver(char *);
void pi_unregister_driver(void *);
#endif /* __DRIVERS_PARIDE_H__ */ #endif /* __DRIVERS_PARIDE_H__ */
/* end of paride.h */ /* end of paride.h */
...@@ -221,6 +221,7 @@ static int pcd_busy; /* request being processed ? */ ...@@ -221,6 +221,7 @@ static int pcd_busy; /* request being processed ? */
static int pcd_sector; /* address of next requested sector */ static int pcd_sector; /* address of next requested sector */
static int pcd_count; /* number of blocks still to do */ static int pcd_count; /* number of blocks still to do */
static char *pcd_buf; /* buffer for request in progress */ static char *pcd_buf; /* buffer for request in progress */
static void *par_drv; /* reference of parport driver */
/* kernel glue structures */ /* kernel glue structures */
...@@ -690,6 +691,12 @@ static int pcd_detect(void) ...@@ -690,6 +691,12 @@ static int pcd_detect(void)
printk("%s: %s version %s, major %d, nice %d\n", printk("%s: %s version %s, major %d, nice %d\n",
name, name, PCD_VERSION, major, nice); name, name, PCD_VERSION, major, nice);
par_drv = pi_register_driver(name);
if (!par_drv) {
pr_err("failed to register %s driver\n", name);
return -1;
}
k = 0; k = 0;
if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
cd = pcd; cd = pcd;
...@@ -723,6 +730,7 @@ static int pcd_detect(void) ...@@ -723,6 +730,7 @@ static int pcd_detect(void)
printk("%s: No CD-ROM drive found\n", name); printk("%s: No CD-ROM drive found\n", name);
for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
put_disk(cd->disk); put_disk(cd->disk);
pi_unregister_driver(par_drv);
return -1; return -1;
} }
...@@ -984,6 +992,7 @@ static void __exit pcd_exit(void) ...@@ -984,6 +992,7 @@ static void __exit pcd_exit(void)
} }
blk_cleanup_queue(pcd_queue); blk_cleanup_queue(pcd_queue);
unregister_blkdev(major, name); unregister_blkdev(major, name);
pi_unregister_driver(par_drv);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
......
...@@ -247,6 +247,8 @@ static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR", ...@@ -247,6 +247,8 @@ static char *pd_errs[17] = { "ERR", "INDEX", "ECC", "DRQ", "SEEK", "WRERR",
"IDNF", "MC", "UNC", "???", "TMO" "IDNF", "MC", "UNC", "???", "TMO"
}; };
static void *par_drv; /* reference of parport driver */
static inline int status_reg(struct pd_unit *disk) static inline int status_reg(struct pd_unit *disk)
{ {
return pi_read_regr(disk->pi, 1, 6); return pi_read_regr(disk->pi, 1, 6);
...@@ -872,6 +874,12 @@ static int pd_detect(void) ...@@ -872,6 +874,12 @@ static int pd_detect(void)
pd_drive_count++; pd_drive_count++;
} }
par_drv = pi_register_driver(name);
if (!par_drv) {
pr_err("failed to register %s driver\n", name);
return -1;
}
if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */ if (pd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
disk = pd; disk = pd;
if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch, if (pi_init(disk->pi, 1, -1, -1, -1, -1, -1, pd_scratch,
...@@ -902,8 +910,10 @@ static int pd_detect(void) ...@@ -902,8 +910,10 @@ static int pd_detect(void)
found = 1; found = 1;
} }
} }
if (!found) if (!found) {
printk("%s: no valid drive found\n", name); printk("%s: no valid drive found\n", name);
pi_unregister_driver(par_drv);
}
return found; return found;
} }
......
...@@ -264,6 +264,7 @@ static int pf_cmd; /* current command READ/WRITE */ ...@@ -264,6 +264,7 @@ static int pf_cmd; /* current command READ/WRITE */
static struct pf_unit *pf_current;/* unit of current request */ static struct pf_unit *pf_current;/* unit of current request */
static int pf_mask; /* stopper for pseudo-int */ static int pf_mask; /* stopper for pseudo-int */
static char *pf_buf; /* buffer for request in progress */ static char *pf_buf; /* buffer for request in progress */
static void *par_drv; /* reference of parport driver */
/* kernel glue structures */ /* kernel glue structures */
...@@ -703,6 +704,11 @@ static int pf_detect(void) ...@@ -703,6 +704,11 @@ static int pf_detect(void)
printk("%s: %s version %s, major %d, cluster %d, nice %d\n", printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
name, name, PF_VERSION, major, cluster, nice); name, name, PF_VERSION, major, cluster, nice);
par_drv = pi_register_driver(name);
if (!par_drv) {
pr_err("failed to register %s driver\n", name);
return -1;
}
k = 0; k = 0;
if (pf_drive_count == 0) { if (pf_drive_count == 0) {
if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF, if (pi_init(pf->pi, 1, -1, -1, -1, -1, -1, pf_scratch, PI_PF,
...@@ -735,6 +741,7 @@ static int pf_detect(void) ...@@ -735,6 +741,7 @@ static int pf_detect(void)
printk("%s: No ATAPI disk detected\n", name); printk("%s: No ATAPI disk detected\n", name);
for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++) for (pf = units, unit = 0; unit < PF_UNITS; pf++, unit++)
put_disk(pf->disk); put_disk(pf->disk);
pi_unregister_driver(par_drv);
return -1; return -1;
} }
......
...@@ -227,6 +227,7 @@ static int pg_identify(struct pg *dev, int log); ...@@ -227,6 +227,7 @@ static int pg_identify(struct pg *dev, int log);
static char pg_scratch[512]; /* scratch block buffer */ static char pg_scratch[512]; /* scratch block buffer */
static struct class *pg_class; static struct class *pg_class;
static void *par_drv; /* reference of parport driver */
/* kernel glue structures */ /* kernel glue structures */
...@@ -481,6 +482,12 @@ static int pg_detect(void) ...@@ -481,6 +482,12 @@ static int pg_detect(void)
printk("%s: %s version %s, major %d\n", name, name, PG_VERSION, major); printk("%s: %s version %s, major %d\n", name, name, PG_VERSION, major);
par_drv = pi_register_driver(name);
if (!par_drv) {
pr_err("failed to register %s driver\n", name);
return -1;
}
k = 0; k = 0;
if (pg_drive_count == 0) { if (pg_drive_count == 0) {
if (pi_init(dev->pi, 1, -1, -1, -1, -1, -1, pg_scratch, if (pi_init(dev->pi, 1, -1, -1, -1, -1, -1, pg_scratch,
...@@ -511,6 +518,7 @@ static int pg_detect(void) ...@@ -511,6 +518,7 @@ static int pg_detect(void)
if (k) if (k)
return 0; return 0;
pi_unregister_driver(par_drv);
printk("%s: No ATAPI device detected\n", name); printk("%s: No ATAPI device detected\n", name);
return -1; return -1;
} }
......
...@@ -232,6 +232,7 @@ static int pt_identify(struct pt_unit *tape); ...@@ -232,6 +232,7 @@ static int pt_identify(struct pt_unit *tape);
static struct pt_unit pt[PT_UNITS]; static struct pt_unit pt[PT_UNITS];
static char pt_scratch[512]; /* scratch block buffer */ static char pt_scratch[512]; /* scratch block buffer */
static void *par_drv; /* reference of parport driver */
/* kernel glue structures */ /* kernel glue structures */
...@@ -605,6 +606,12 @@ static int pt_detect(void) ...@@ -605,6 +606,12 @@ static int pt_detect(void)
printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major); printk("%s: %s version %s, major %d\n", name, name, PT_VERSION, major);
par_drv = pi_register_driver(name);
if (!par_drv) {
pr_err("failed to register %s driver\n", name);
return -1;
}
specified = 0; specified = 0;
for (unit = 0; unit < PT_UNITS; unit++) { for (unit = 0; unit < PT_UNITS; unit++) {
struct pt_unit *tape = &pt[unit]; struct pt_unit *tape = &pt[unit];
...@@ -644,6 +651,7 @@ static int pt_detect(void) ...@@ -644,6 +651,7 @@ static int pt_detect(void)
if (found) if (found)
return 0; return 0;
pi_unregister_driver(par_drv);
printk("%s: No ATAPI tape drive detected\n", name); printk("%s: No ATAPI tape drive detected\n", name);
return -1; return -1;
} }
......
...@@ -590,14 +590,6 @@ config DEVPORT ...@@ -590,14 +590,6 @@ config DEVPORT
source "drivers/s390/char/Kconfig" source "drivers/s390/char/Kconfig"
config MSM_SMD_PKT
bool "Enable device interface for some SMD packet ports"
default n
depends on MSM_SMD
help
Enables userspace clients to read and write to some packet SMD
ports via device interface for MSM chipset.
config TILE_SROM config TILE_SROM
bool "Character-device access via hypervisor to the Tilera SPI ROM" bool "Character-device access via hypervisor to the Tilera SPI ROM"
depends on TILE depends on TILE
......
...@@ -9,7 +9,6 @@ obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o ...@@ -9,7 +9,6 @@ obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o
obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_RAW_DRIVER) += raw.o
obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o
obj-$(CONFIG_MSM_SMD_PKT) += msm_smd_pkt.o
obj-$(CONFIG_MSPEC) += mspec.o obj-$(CONFIG_MSPEC) += mspec.o
obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_MMTIMER) += mmtimer.o
obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o obj-$(CONFIG_UV_MMTIMER) += uv_mmtimer.o
...@@ -36,7 +35,6 @@ else ...@@ -36,7 +35,6 @@ else
obj-$(CONFIG_NVRAM) += nvram.o obj-$(CONFIG_NVRAM) += nvram.o
endif endif
obj-$(CONFIG_TOSHIBA) += toshiba.o obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_HW_RANDOM) += hw_random/ obj-$(CONFIG_HW_RANDOM) += hw_random/
obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_PPDEV) += ppdev.o
......
...@@ -186,12 +186,13 @@ int misc_register(struct miscdevice * misc) ...@@ -186,12 +186,13 @@ int misc_register(struct miscdevice * misc)
{ {
dev_t dev; dev_t dev;
int err = 0; int err = 0;
bool is_dynamic = (misc->minor == MISC_DYNAMIC_MINOR);
INIT_LIST_HEAD(&misc->list); INIT_LIST_HEAD(&misc->list);
mutex_lock(&misc_mtx); mutex_lock(&misc_mtx);
if (misc->minor == MISC_DYNAMIC_MINOR) { if (is_dynamic) {
int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);
if (i >= DYNAMIC_MINORS) { if (i >= DYNAMIC_MINORS) {
err = -EBUSY; err = -EBUSY;
...@@ -216,9 +217,13 @@ int misc_register(struct miscdevice * misc) ...@@ -216,9 +217,13 @@ int misc_register(struct miscdevice * misc)
device_create_with_groups(misc_class, misc->parent, dev, device_create_with_groups(misc_class, misc->parent, dev,
misc, misc->groups, "%s", misc->name); misc, misc->groups, "%s", misc->name);
if (IS_ERR(misc->this_device)) { if (IS_ERR(misc->this_device)) {
if (is_dynamic) {
int i = DYNAMIC_MINORS - misc->minor - 1; int i = DYNAMIC_MINORS - misc->minor - 1;
if (i < DYNAMIC_MINORS && i >= 0) if (i < DYNAMIC_MINORS && i >= 0)
clear_bit(i, misc_minors); clear_bit(i, misc_minors);
misc->minor = MISC_DYNAMIC_MINOR;
}
err = PTR_ERR(misc->this_device); err = PTR_ERR(misc->this_device);
goto out; goto out;
} }
......
This diff is collapsed.
...@@ -437,7 +437,7 @@ static int mgslpc_device_count = 0; ...@@ -437,7 +437,7 @@ static int mgslpc_device_count = 0;
* .text section address and breakpoint on module load. * .text section address and breakpoint on module load.
* This is useful for use with gdb and add-symbol-file command. * This is useful for use with gdb and add-symbol-file command.
*/ */
static bool break_on_load=0; static bool break_on_load;
/* /*
* Driver major number, defaults to zero to get auto * Driver major number, defaults to zero to get auto
......
...@@ -198,7 +198,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) ...@@ -198,7 +198,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
add_wait_queue(&sd->sd_rq, &wait); add_wait_queue(&sd->sd_rq, &wait);
spin_unlock_irqrestore(&sd->sd_rlock, flags); spin_unlock_irqrestore(&sd->sd_rlock, flags);
schedule_timeout(SCDRV_TIMEOUT); schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT));
remove_wait_queue(&sd->sd_rq, &wait); remove_wait_queue(&sd->sd_rq, &wait);
if (signal_pending(current)) { if (signal_pending(current)) {
...@@ -294,7 +294,7 @@ scdrv_write(struct file *file, const char __user *buf, ...@@ -294,7 +294,7 @@ scdrv_write(struct file *file, const char __user *buf,
add_wait_queue(&sd->sd_wq, &wait); add_wait_queue(&sd->sd_wq, &wait);
spin_unlock_irqrestore(&sd->sd_wlock, flags); spin_unlock_irqrestore(&sd->sd_wlock, flags);
schedule_timeout(SCDRV_TIMEOUT); schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT));
remove_wait_queue(&sd->sd_wq, &wait); remove_wait_queue(&sd->sd_wq, &wait);
if (signal_pending(current)) { if (signal_pending(current)) {
......
...@@ -1492,7 +1492,7 @@ static int add_port(struct ports_device *portdev, u32 id) ...@@ -1492,7 +1492,7 @@ static int add_port(struct ports_device *portdev, u32 id)
* Finally, create the debugfs file that we can use to * Finally, create the debugfs file that we can use to
* inspect a port's state at any time * inspect a port's state at any time
*/ */
sprintf(debugfs_name, "vport%up%u", snprintf(debugfs_name, sizeof(debugfs_name), "vport%up%u",
port->portdev->vdev->index, id); port->portdev->vdev->index, id);
port->debugfs_file = debugfs_create_file(debugfs_name, 0444, port->debugfs_file = debugfs_create_file(debugfs_name, 0444,
pdrvdata.debugfs_dir, pdrvdata.debugfs_dir,
......
...@@ -270,7 +270,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, ...@@ -270,7 +270,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
int status; int status;
s32 buffer_count = 0; s32 buffer_count = 0;
s32 num_writes = 0; s32 num_writes = 0;
bool dirty = 0; bool dirty = false;
u32 i; u32 i;
void __iomem *base_address = drvdata->base_address; void __iomem *base_address = drvdata->base_address;
...@@ -279,7 +279,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, ...@@ -279,7 +279,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
/* Copy data to bram */ /* Copy data to bram */
buffer_icap_set_bram(base_address, buffer_count, data[i]); buffer_icap_set_bram(base_address, buffer_count, data[i]);
dirty = 1; dirty = true;
if (buffer_count < XHI_MAX_BUFFER_INTS - 1) { if (buffer_count < XHI_MAX_BUFFER_INTS - 1) {
buffer_count++; buffer_count++;
...@@ -299,7 +299,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data, ...@@ -299,7 +299,7 @@ int buffer_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *data,
buffer_count = 0; buffer_count = 0;
num_writes++; num_writes++;
dirty = 0; dirty = false;
} }
/* Write unwritten data to ICAP */ /* Write unwritten data to ICAP */
......
...@@ -24,7 +24,7 @@ config XILLYBUS_PCIE ...@@ -24,7 +24,7 @@ config XILLYBUS_PCIE
config XILLYBUS_OF config XILLYBUS_OF
tristate "Xillybus over Device Tree" tristate "Xillybus over Device Tree"
depends on OF_ADDRESS && OF_IRQ depends on OF_ADDRESS && OF_IRQ && HAS_DMA
help help
Set to M if you want Xillybus to find its resources from the Set to M if you want Xillybus to find its resources from the
Open Firmware Flattened Device Tree. If the target is an embedded Open Firmware Flattened Device Tree. If the target is an embedded
......
...@@ -28,15 +28,22 @@ config EXTCON_ARIZONA ...@@ -28,15 +28,22 @@ config EXTCON_ARIZONA
with Wolfson Arizona devices. These are audio CODECs with with Wolfson Arizona devices. These are audio CODECs with
advanced audio accessory detection support. advanced audio accessory detection support.
config EXTCON_AXP288
tristate "X-Power AXP288 EXTCON support"
depends on MFD_AXP20X && USB_PHY
help
Say Y here to enable support for USB peripheral detection
and USB MUX switching by X-Power AXP288 PMIC.
config EXTCON_GPIO config EXTCON_GPIO
tristate "GPIO extcon support" tristate "GPIO extcon support"
depends on GPIOLIB depends on GPIOLIB || COMPILE_TEST
help help
Say Y here to enable GPIO based extcon support. Note that GPIO Say Y here to enable GPIO based extcon support. Note that GPIO
extcon supports single state per extcon instance. extcon supports single state per extcon instance.
config EXTCON_MAX14577 config EXTCON_MAX14577
tristate "MAX14577/77836 EXTCON Support" tristate "Maxim MAX14577/77836 EXTCON Support"
depends on MFD_MAX14577 depends on MFD_MAX14577
select IRQ_DOMAIN select IRQ_DOMAIN
select REGMAP_I2C select REGMAP_I2C
...@@ -46,7 +53,7 @@ config EXTCON_MAX14577 ...@@ -46,7 +53,7 @@ config EXTCON_MAX14577
detector and switch. detector and switch.
config EXTCON_MAX77693 config EXTCON_MAX77693
tristate "MAX77693 EXTCON Support" tristate "Maxim MAX77693 EXTCON Support"
depends on MFD_MAX77693 && INPUT depends on MFD_MAX77693 && INPUT
select IRQ_DOMAIN select IRQ_DOMAIN
select REGMAP_I2C select REGMAP_I2C
...@@ -56,7 +63,7 @@ config EXTCON_MAX77693 ...@@ -56,7 +63,7 @@ config EXTCON_MAX77693
detector and switch. detector and switch.
config EXTCON_MAX77843 config EXTCON_MAX77843
tristate "MAX77843 EXTCON Support" tristate "Maxim MAX77843 EXTCON Support"
depends on MFD_MAX77843 depends on MFD_MAX77843
select IRQ_DOMAIN select IRQ_DOMAIN
select REGMAP_I2C select REGMAP_I2C
...@@ -66,7 +73,7 @@ config EXTCON_MAX77843 ...@@ -66,7 +73,7 @@ config EXTCON_MAX77843
detector add switch. detector add switch.
config EXTCON_MAX8997 config EXTCON_MAX8997
tristate "MAX8997 EXTCON Support" tristate "Maxim MAX8997 EXTCON Support"
depends on MFD_MAX8997 && IRQ_DOMAIN depends on MFD_MAX8997 && IRQ_DOMAIN
help help
If you say yes here you get support for the MUIC device of If you say yes here you get support for the MUIC device of
...@@ -81,7 +88,7 @@ config EXTCON_PALMAS ...@@ -81,7 +88,7 @@ config EXTCON_PALMAS
detection by palmas usb. detection by palmas usb.
config EXTCON_RT8973A config EXTCON_RT8973A
tristate "RT8973A EXTCON support" tristate "Richtek RT8973A EXTCON support"
depends on I2C depends on I2C
select IRQ_DOMAIN select IRQ_DOMAIN
select REGMAP_I2C select REGMAP_I2C
...@@ -93,7 +100,7 @@ config EXTCON_RT8973A ...@@ -93,7 +100,7 @@ config EXTCON_RT8973A
from abnormal high input voltage (up to 28V). from abnormal high input voltage (up to 28V).
config EXTCON_SM5502 config EXTCON_SM5502
tristate "SM5502 EXTCON support" tristate "Silicon Mitus SM5502 EXTCON support"
depends on I2C depends on I2C
select IRQ_DOMAIN select IRQ_DOMAIN
select REGMAP_I2C select REGMAP_I2C
...@@ -105,9 +112,9 @@ config EXTCON_SM5502 ...@@ -105,9 +112,9 @@ config EXTCON_SM5502
config EXTCON_USB_GPIO config EXTCON_USB_GPIO
tristate "USB GPIO extcon support" tristate "USB GPIO extcon support"
depends on GPIOLIB depends on GPIOLIB || COMPILE_TEST
help help
Say Y here to enable GPIO based USB cable detection extcon support. Say Y here to enable GPIO based USB cable detection extcon support.
Used typically if GPIO is used for USB ID pin detection. Used typically if GPIO is used for USB ID pin detection.
endif # MULTISTATE_SWITCH endif
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
obj-$(CONFIG_EXTCON) += extcon.o obj-$(CONFIG_EXTCON) += extcon.o
obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o
obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
obj-$(CONFIG_EXTCON_AXP288) += extcon-axp288.o
obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o
obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
......
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
* struct adc_jack_data - internal data for adc_jack device driver * struct adc_jack_data - internal data for adc_jack device driver
* @edev: extcon device. * @edev: extcon device.
* @cable_names: list of supported cables. * @cable_names: list of supported cables.
* @num_cables: size of cable_names.
* @adc_conditions: list of adc value conditions. * @adc_conditions: list of adc value conditions.
* @num_conditions: size of adc_conditions. * @num_conditions: size of adc_conditions.
* @irq: irq number of attach/detach event (0 if not exist). * @irq: irq number of attach/detach event (0 if not exist).
...@@ -41,8 +40,7 @@ ...@@ -41,8 +40,7 @@
struct adc_jack_data { struct adc_jack_data {
struct extcon_dev *edev; struct extcon_dev *edev;
const char **cable_names; const unsigned int **cable_names;
int num_cables;
struct adc_jack_cond *adc_conditions; struct adc_jack_cond *adc_conditions;
int num_conditions; int num_conditions;
...@@ -112,17 +110,6 @@ static int adc_jack_probe(struct platform_device *pdev) ...@@ -112,17 +110,6 @@ static int adc_jack_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate extcon device\n"); dev_err(&pdev->dev, "failed to allocate extcon device\n");
return -ENOMEM; return -ENOMEM;
} }
data->edev->name = pdata->name;
/* Check the length of array and set num_cables */
for (i = 0; data->edev->supported_cable[i]; i++)
;
if (i == 0 || i > SUPPORTED_CABLE_MAX) {
dev_err(&pdev->dev, "error: pdata->cable_names size = %d\n",
i - 1);
return -EINVAL;
}
data->num_cables = i;
if (!pdata->adc_conditions || if (!pdata->adc_conditions ||
!pdata->adc_conditions[0].state) { !pdata->adc_conditions[0].state) {
......
...@@ -32,13 +32,10 @@ ...@@ -32,13 +32,10 @@
#include <linux/mfd/arizona/core.h> #include <linux/mfd/arizona/core.h>
#include <linux/mfd/arizona/pdata.h> #include <linux/mfd/arizona/pdata.h>
#include <linux/mfd/arizona/registers.h> #include <linux/mfd/arizona/registers.h>
#include <dt-bindings/mfd/arizona.h>
#define ARIZONA_MAX_MICD_RANGE 8 #define ARIZONA_MAX_MICD_RANGE 8
#define ARIZONA_ACCDET_MODE_MIC 0
#define ARIZONA_ACCDET_MODE_HPL 1
#define ARIZONA_ACCDET_MODE_HPR 2
#define ARIZONA_MICD_CLAMP_MODE_JDL 0x4 #define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
#define ARIZONA_MICD_CLAMP_MODE_JDH 0x5 #define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9 #define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
...@@ -94,7 +91,7 @@ struct arizona_extcon_info { ...@@ -94,7 +91,7 @@ struct arizona_extcon_info {
bool detecting; bool detecting;
int jack_flips; int jack_flips;
int hpdet_ip; int hpdet_ip_version;
struct extcon_dev *edev; struct extcon_dev *edev;
}; };
...@@ -121,17 +118,12 @@ static const int arizona_micd_levels[] = { ...@@ -121,17 +118,12 @@ static const int arizona_micd_levels[] = {
1257, 1257,
}; };
#define ARIZONA_CABLE_MECHANICAL 0 static const unsigned int arizona_cable[] = {
#define ARIZONA_CABLE_MICROPHONE 1 EXTCON_MECHANICAL,
#define ARIZONA_CABLE_HEADPHONE 2 EXTCON_MICROPHONE,
#define ARIZONA_CABLE_LINEOUT 3 EXTCON_HEADPHONE,
EXTCON_LINE_OUT,
static const char *arizona_cable[] = { EXTCON_NONE,
"Mechanical",
"Microphone",
"Headphone",
"Line-out",
NULL,
}; };
static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info); static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info);
...@@ -145,6 +137,7 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, ...@@ -145,6 +137,7 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info,
switch (arizona->type) { switch (arizona->type) {
case WM5110: case WM5110:
case WM8280:
mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR | mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR |
ARIZONA_HP1L_SHRTI; ARIZONA_HP1L_SHRTI;
if (clamp) if (clamp)
...@@ -380,7 +373,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) ...@@ -380,7 +373,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
return ret; return ret;
} }
switch (info->hpdet_ip) { switch (info->hpdet_ip_version) {
case 0: case 0:
if (!(val & ARIZONA_HP_DONE)) { if (!(val & ARIZONA_HP_DONE)) {
dev_err(arizona->dev, "HPDET did not complete: %x\n", dev_err(arizona->dev, "HPDET did not complete: %x\n",
...@@ -441,7 +434,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info) ...@@ -441,7 +434,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
default: default:
dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n", dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
info->hpdet_ip); info->hpdet_ip_version);
case 2: case 2:
if (!(val & ARIZONA_HP_DONE_B)) { if (!(val & ARIZONA_HP_DONE_B)) {
dev_err(arizona->dev, "HPDET did not complete: %x\n", dev_err(arizona->dev, "HPDET did not complete: %x\n",
...@@ -559,7 +552,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) ...@@ -559,7 +552,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
struct arizona_extcon_info *info = data; struct arizona_extcon_info *info = data;
struct arizona *arizona = info->arizona; struct arizona *arizona = info->arizona;
int id_gpio = arizona->pdata.hpdet_id_gpio; int id_gpio = arizona->pdata.hpdet_id_gpio;
int report = ARIZONA_CABLE_HEADPHONE; unsigned int report = EXTCON_HEADPHONE;
int ret, reading; int ret, reading;
bool mic = false; bool mic = false;
...@@ -573,7 +566,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) ...@@ -573,7 +566,7 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
} }
/* If the cable was removed while measuring ignore the result */ /* If the cable was removed while measuring ignore the result */
ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL); ret = extcon_get_cable_state_(info->edev, EXTCON_MECHANICAL);
if (ret < 0) { if (ret < 0) {
dev_err(arizona->dev, "Failed to check cable state: %d\n", dev_err(arizona->dev, "Failed to check cable state: %d\n",
ret); ret);
...@@ -604,9 +597,9 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data) ...@@ -604,9 +597,9 @@ static irqreturn_t arizona_hpdet_irq(int irq, void *data)
/* Report high impedence cables as line outputs */ /* Report high impedence cables as line outputs */
if (reading >= 5000) if (reading >= 5000)
report = ARIZONA_CABLE_LINEOUT; report = EXTCON_LINE_OUT;
else else
report = ARIZONA_CABLE_HEADPHONE; report = EXTCON_HEADPHONE;
ret = extcon_set_cable_state_(info->edev, report, true); ret = extcon_set_cable_state_(info->edev, report, true);
if (ret != 0) if (ret != 0)
...@@ -670,9 +663,9 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) ...@@ -670,9 +663,9 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
ret = regmap_update_bits(arizona->regmap, ret = regmap_update_bits(arizona->regmap,
ARIZONA_ACCESSORY_DETECT_MODE_1, ARIZONA_ACCESSORY_DETECT_MODE_1,
ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MASK,
ARIZONA_ACCDET_MODE_HPL); arizona->pdata.hpdet_channel);
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret); dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
goto err; goto err;
} }
...@@ -691,8 +684,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info) ...@@ -691,8 +684,7 @@ static void arizona_identify_headphone(struct arizona_extcon_info *info)
ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
/* Just report headphone */ /* Just report headphone */
ret = extcon_set_cable_state_(info->edev, ret = extcon_set_cable_state_(info->edev, EXTCON_HEADPHONE, true);
ARIZONA_CABLE_HEADPHONE, true);
if (ret != 0) if (ret != 0)
dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
...@@ -722,9 +714,9 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) ...@@ -722,9 +714,9 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
ARIZONA_ACCESSORY_DETECT_MODE_1, ARIZONA_ACCESSORY_DETECT_MODE_1,
ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_SRC | ARIZONA_ACCDET_MODE_MASK,
info->micd_modes[0].src | info->micd_modes[0].src |
ARIZONA_ACCDET_MODE_HPL); arizona->pdata.hpdet_channel);
if (ret != 0) { if (ret != 0) {
dev_err(arizona->dev, "Failed to set HPDETL mode: %d\n", ret); dev_err(arizona->dev, "Failed to set HPDET mode: %d\n", ret);
goto err; goto err;
} }
...@@ -749,8 +741,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info) ...@@ -749,8 +741,7 @@ static void arizona_start_hpdet_acc_id(struct arizona_extcon_info *info)
ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
/* Just report headphone */ /* Just report headphone */
ret = extcon_set_cable_state_(info->edev, ret = extcon_set_cable_state_(info->edev, EXTCON_HEADPHONE, true);
ARIZONA_CABLE_HEADPHONE, true);
if (ret != 0) if (ret != 0)
dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
...@@ -789,7 +780,7 @@ static void arizona_micd_detect(struct work_struct *work) ...@@ -789,7 +780,7 @@ static void arizona_micd_detect(struct work_struct *work)
mutex_lock(&info->lock); mutex_lock(&info->lock);
/* If the cable was removed while measuring ignore the result */ /* If the cable was removed while measuring ignore the result */
ret = extcon_get_cable_state_(info->edev, ARIZONA_CABLE_MECHANICAL); ret = extcon_get_cable_state_(info->edev, EXTCON_MECHANICAL);
if (ret < 0) { if (ret < 0) {
dev_err(arizona->dev, "Failed to check cable state: %d\n", dev_err(arizona->dev, "Failed to check cable state: %d\n",
ret); ret);
...@@ -838,8 +829,7 @@ static void arizona_micd_detect(struct work_struct *work) ...@@ -838,8 +829,7 @@ static void arizona_micd_detect(struct work_struct *work)
arizona_identify_headphone(info); arizona_identify_headphone(info);
ret = extcon_set_cable_state_(info->edev, ret = extcon_set_cable_state_(info->edev,
ARIZONA_CABLE_MICROPHONE, true); EXTCON_MICROPHONE, true);
if (ret != 0) if (ret != 0)
dev_err(arizona->dev, "Headset report failed: %d\n", dev_err(arizona->dev, "Headset report failed: %d\n",
ret); ret);
...@@ -1030,7 +1020,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data) ...@@ -1030,7 +1020,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
if (info->last_jackdet == present) { if (info->last_jackdet == present) {
dev_dbg(arizona->dev, "Detected jack\n"); dev_dbg(arizona->dev, "Detected jack\n");
ret = extcon_set_cable_state_(info->edev, ret = extcon_set_cable_state_(info->edev,
ARIZONA_CABLE_MECHANICAL, true); EXTCON_MECHANICAL, true);
if (ret != 0) if (ret != 0)
dev_err(arizona->dev, "Mechanical report failed: %d\n", dev_err(arizona->dev, "Mechanical report failed: %d\n",
...@@ -1120,6 +1110,26 @@ static void arizona_micd_set_level(struct arizona *arizona, int index, ...@@ -1120,6 +1110,26 @@ static void arizona_micd_set_level(struct arizona *arizona, int index,
regmap_update_bits(arizona->regmap, reg, mask, level); regmap_update_bits(arizona->regmap, reg, mask, level);
} }
static int arizona_extcon_of_get_pdata(struct arizona *arizona)
{
struct arizona_pdata *pdata = &arizona->pdata;
unsigned int val = ARIZONA_ACCDET_MODE_HPL;
of_property_read_u32(arizona->dev->of_node, "wlf,hpdet-channel", &val);
switch (val) {
case ARIZONA_ACCDET_MODE_HPL:
case ARIZONA_ACCDET_MODE_HPR:
pdata->hpdet_channel = val;
break;
default:
dev_err(arizona->dev,
"Wrong wlf,hpdet-channel DT value %d\n", val);
pdata->hpdet_channel = ARIZONA_ACCDET_MODE_HPL;
}
return 0;
}
static int arizona_extcon_probe(struct platform_device *pdev) static int arizona_extcon_probe(struct platform_device *pdev)
{ {
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
...@@ -1137,6 +1147,11 @@ static int arizona_extcon_probe(struct platform_device *pdev) ...@@ -1137,6 +1147,11 @@ static int arizona_extcon_probe(struct platform_device *pdev)
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;
if (IS_ENABLED(CONFIG_OF)) {
if (!dev_get_platdata(arizona->dev))
arizona_extcon_of_get_pdata(arizona);
}
info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD"); info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
if (IS_ERR(info->micvdd)) { if (IS_ERR(info->micvdd)) {
ret = PTR_ERR(info->micvdd); ret = PTR_ERR(info->micvdd);
...@@ -1161,7 +1176,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) ...@@ -1161,7 +1176,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
break; break;
default: default:
info->micd_clamp = true; info->micd_clamp = true;
info->hpdet_ip = 1; info->hpdet_ip_version = 1;
break; break;
} }
break; break;
...@@ -1172,7 +1187,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) ...@@ -1172,7 +1187,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
break; break;
default: default:
info->micd_clamp = true; info->micd_clamp = true;
info->hpdet_ip = 2; info->hpdet_ip_version = 2;
break; break;
} }
break; break;
...@@ -1185,7 +1200,6 @@ static int arizona_extcon_probe(struct platform_device *pdev) ...@@ -1185,7 +1200,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate extcon device\n"); dev_err(&pdev->dev, "failed to allocate extcon device\n");
return -ENOMEM; return -ENOMEM;
} }
info->edev->name = "Headset Jack";
ret = devm_extcon_dev_register(&pdev->dev, info->edev); ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret < 0) { if (ret < 0) {
......
This diff is collapsed.
...@@ -104,7 +104,6 @@ static int gpio_extcon_probe(struct platform_device *pdev) ...@@ -104,7 +104,6 @@ static int gpio_extcon_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate extcon device\n"); dev_err(&pdev->dev, "failed to allocate extcon device\n");
return -ENOMEM; return -ENOMEM;
} }
extcon_data->edev->name = pdata->name;
extcon_data->gpio = pdata->gpio; extcon_data->gpio = pdata->gpio;
extcon_data->gpio_active_low = pdata->gpio_active_low; extcon_data->gpio_active_low = pdata->gpio_active_low;
......
...@@ -148,33 +148,14 @@ enum max14577_muic_acc_type { ...@@ -148,33 +148,14 @@ enum max14577_muic_acc_type {
MAX14577_MUIC_ADC_OPEN, MAX14577_MUIC_ADC_OPEN,
}; };
/* max14577 MUIC device support below list of accessories(external connector) */ static const unsigned int max14577_extcon_cable[] = {
enum { EXTCON_USB,
EXTCON_CABLE_USB = 0, EXTCON_TA,
EXTCON_CABLE_TA, EXTCON_FAST_CHARGER,
EXTCON_CABLE_FAST_CHARGER, EXTCON_SLOW_CHARGER,
EXTCON_CABLE_SLOW_CHARGER, EXTCON_CHARGE_DOWNSTREAM,
EXTCON_CABLE_CHARGE_DOWNSTREAM, EXTCON_JIG,
EXTCON_CABLE_JIG_USB_ON, EXTCON_NONE,
EXTCON_CABLE_JIG_USB_OFF,
EXTCON_CABLE_JIG_UART_OFF,
EXTCON_CABLE_JIG_UART_ON,
_EXTCON_CABLE_NUM,
};
static const char *max14577_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_TA] = "TA",
[EXTCON_CABLE_FAST_CHARGER] = "Fast-charger",
[EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger",
[EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream",
[EXTCON_CABLE_JIG_USB_ON] = "JIG-USB-ON",
[EXTCON_CABLE_JIG_USB_OFF] = "JIG-USB-OFF",
[EXTCON_CABLE_JIG_UART_OFF] = "JIG-UART-OFF",
[EXTCON_CABLE_JIG_UART_ON] = "JIG-UART-ON",
NULL,
}; };
/* /*
...@@ -348,7 +329,6 @@ static int max14577_muic_get_cable_type(struct max14577_muic_info *info, ...@@ -348,7 +329,6 @@ static int max14577_muic_get_cable_type(struct max14577_muic_info *info,
static int max14577_muic_jig_handler(struct max14577_muic_info *info, static int max14577_muic_jig_handler(struct max14577_muic_info *info,
int cable_type, bool attached) int cable_type, bool attached)
{ {
char cable_name[32];
int ret = 0; int ret = 0;
u8 path = CTRL1_SW_OPEN; u8 path = CTRL1_SW_OPEN;
...@@ -358,18 +338,12 @@ static int max14577_muic_jig_handler(struct max14577_muic_info *info, ...@@ -358,18 +338,12 @@ static int max14577_muic_jig_handler(struct max14577_muic_info *info,
switch (cable_type) { switch (cable_type) {
case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */ case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
/* PATH:AP_USB */
strcpy(cable_name, "JIG-USB-OFF");
path = CTRL1_SW_USB;
break;
case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */ case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
/* PATH:AP_USB */ /* PATH:AP_USB */
strcpy(cable_name, "JIG-USB-ON");
path = CTRL1_SW_USB; path = CTRL1_SW_USB;
break; break;
case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */ case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
/* PATH:AP_UART */ /* PATH:AP_UART */
strcpy(cable_name, "JIG-UART-OFF");
path = CTRL1_SW_UART; path = CTRL1_SW_UART;
break; break;
default: default:
...@@ -382,7 +356,7 @@ static int max14577_muic_jig_handler(struct max14577_muic_info *info, ...@@ -382,7 +356,7 @@ static int max14577_muic_jig_handler(struct max14577_muic_info *info,
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, cable_name, attached); extcon_set_cable_state_(info->edev, EXTCON_JIG, attached);
return 0; return 0;
} }
...@@ -479,20 +453,22 @@ static int max14577_muic_chg_handler(struct max14577_muic_info *info) ...@@ -479,20 +453,22 @@ static int max14577_muic_chg_handler(struct max14577_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "USB", attached); extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
break; break;
case MAX14577_CHARGER_TYPE_DEDICATED_CHG: case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
extcon_set_cable_state(info->edev, "TA", attached); extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
break; break;
case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT: case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM,
"Charge-downstream", attached); attached);
break; break;
case MAX14577_CHARGER_TYPE_SPECIAL_500MA: case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
extcon_set_cable_state(info->edev, "Slow-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER,
attached);
break; break;
case MAX14577_CHARGER_TYPE_SPECIAL_1A: case MAX14577_CHARGER_TYPE_SPECIAL_1A:
extcon_set_cable_state(info->edev, "Fast-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER,
attached);
break; break;
case MAX14577_CHARGER_TYPE_NONE: case MAX14577_CHARGER_TYPE_NONE:
case MAX14577_CHARGER_TYPE_DEAD_BATTERY: case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
...@@ -742,8 +718,6 @@ static int max14577_muic_probe(struct platform_device *pdev) ...@@ -742,8 +718,6 @@ static int max14577_muic_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
info->edev->name = dev_name(&pdev->dev);
ret = devm_extcon_dev_register(&pdev->dev, info->edev); ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register extcon device\n"); dev_err(&pdev->dev, "failed to register extcon device\n");
......
...@@ -200,44 +200,17 @@ enum max77693_muic_acc_type { ...@@ -200,44 +200,17 @@ enum max77693_muic_acc_type {
/* /*
* MAX77693 MUIC device support below list of accessories(external connector) * MAX77693 MUIC device support below list of accessories(external connector)
*/ */
enum { static const unsigned int max77693_extcon_cable[] = {
EXTCON_CABLE_USB = 0, EXTCON_USB,
EXTCON_CABLE_USB_HOST, EXTCON_USB_HOST,
EXTCON_CABLE_TA, EXTCON_TA,
EXTCON_CABLE_FAST_CHARGER, EXTCON_FAST_CHARGER,
EXTCON_CABLE_SLOW_CHARGER, EXTCON_SLOW_CHARGER,
EXTCON_CABLE_CHARGE_DOWNSTREAM, EXTCON_CHARGE_DOWNSTREAM,
EXTCON_CABLE_MHL, EXTCON_MHL,
EXTCON_CABLE_MHL_TA, EXTCON_JIG,
EXTCON_CABLE_JIG_USB_ON, EXTCON_DOCK,
EXTCON_CABLE_JIG_USB_OFF, EXTCON_NONE,
EXTCON_CABLE_JIG_UART_OFF,
EXTCON_CABLE_JIG_UART_ON,
EXTCON_CABLE_DOCK_SMART,
EXTCON_CABLE_DOCK_DESK,
EXTCON_CABLE_DOCK_AUDIO,
_EXTCON_CABLE_NUM,
};
static const char *max77693_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_USB_HOST] = "USB-Host",
[EXTCON_CABLE_TA] = "TA",
[EXTCON_CABLE_FAST_CHARGER] = "Fast-charger",
[EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger",
[EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream",
[EXTCON_CABLE_MHL] = "MHL",
[EXTCON_CABLE_MHL_TA] = "MHL-TA",
[EXTCON_CABLE_JIG_USB_ON] = "JIG-USB-ON",
[EXTCON_CABLE_JIG_USB_OFF] = "JIG-USB-OFF",
[EXTCON_CABLE_JIG_UART_OFF] = "JIG-UART-OFF",
[EXTCON_CABLE_JIG_UART_ON] = "JIG-UART-ON",
[EXTCON_CABLE_DOCK_SMART] = "Dock-Smart",
[EXTCON_CABLE_DOCK_DESK] = "Dock-Desk",
[EXTCON_CABLE_DOCK_AUDIO] = "Dock-Audio",
NULL,
}; };
/* /*
...@@ -484,7 +457,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, ...@@ -484,7 +457,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
int ret = 0; int ret = 0;
int vbvolt; int vbvolt;
bool cable_attached; bool cable_attached;
char dock_name[CABLE_NAME_MAX]; unsigned int dock_id;
dev_info(info->dev, dev_info(info->dev,
"external connector is %s (adc:0x%02x)\n", "external connector is %s (adc:0x%02x)\n",
...@@ -507,15 +480,15 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, ...@@ -507,15 +480,15 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
} }
/* /*
* Notify Dock-Smart/MHL state. * Notify Dock/MHL state.
* - Dock-Smart device include three type of cable which * - Dock device include three type of cable which
* are HDMI, USB for mouse/keyboard and micro-usb port * are HDMI, USB for mouse/keyboard and micro-usb port
* for USB/TA cable. Dock-Smart device need always exteranl * for USB/TA cable. Dock device need always exteranl
* power supply(USB/TA cable through micro-usb cable). Dock- * power supply(USB/TA cable through micro-usb cable). Dock
* Smart device support screen output of target to separate * device support screen output of target to separate
* monitor and mouse/keyboard for desktop mode. * monitor and mouse/keyboard for desktop mode.
* *
* Features of 'USB/TA cable with Dock-Smart device' * Features of 'USB/TA cable with Dock device'
* - Support MHL * - Support MHL
* - Support external output feature of audio * - Support external output feature of audio
* - Support charging through micro-usb port without data * - Support charging through micro-usb port without data
...@@ -529,16 +502,16 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, ...@@ -529,16 +502,16 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "Dock-Smart", attached); extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached);
extcon_set_cable_state(info->edev, "MHL", attached); extcon_set_cable_state_(info->edev, EXTCON_MHL, attached);
goto out; goto out;
case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */ case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */
strcpy(dock_name, "Dock-Desk"); dock_id = EXTCON_DOCK;
break; break;
case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */ case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */
strcpy(dock_name, "Dock-Audio"); dock_id = EXTCON_DOCK;
if (!attached) if (!attached)
extcon_set_cable_state(info->edev, "USB", false); extcon_set_cable_state_(info->edev, EXTCON_USB, false);
break; break;
default: default:
dev_err(info->dev, "failed to detect %s dock device\n", dev_err(info->dev, "failed to detect %s dock device\n",
...@@ -550,7 +523,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info, ...@@ -550,7 +523,7 @@ static int max77693_muic_dock_handler(struct max77693_muic_info *info,
ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached); ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, dock_name, attached); extcon_set_cable_state_(info->edev, dock_id, attached);
out: out:
return 0; return 0;
...@@ -615,20 +588,19 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info) ...@@ -615,20 +588,19 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)
ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached); ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "USB-Host", attached); extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached);
break; break;
case MAX77693_MUIC_GND_AV_CABLE_LOAD: case MAX77693_MUIC_GND_AV_CABLE_LOAD:
/* Audio Video Cable with load, PATH:AUDIO */ /* Audio Video Cable with load, PATH:AUDIO */
ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached); ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
"Audio-video-load", attached);
break; break;
case MAX77693_MUIC_GND_MHL: case MAX77693_MUIC_GND_MHL:
case MAX77693_MUIC_GND_MHL_VB: case MAX77693_MUIC_GND_MHL_VB:
/* MHL or MHL with USB/TA cable */ /* MHL or MHL with USB/TA cable */
extcon_set_cable_state(info->edev, "MHL", attached); extcon_set_cable_state_(info->edev, EXTCON_MHL, attached);
break; break;
default: default:
dev_err(info->dev, "failed to detect %s cable of gnd type\n", dev_err(info->dev, "failed to detect %s cable of gnd type\n",
...@@ -642,7 +614,6 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info) ...@@ -642,7 +614,6 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)
static int max77693_muic_jig_handler(struct max77693_muic_info *info, static int max77693_muic_jig_handler(struct max77693_muic_info *info,
int cable_type, bool attached) int cable_type, bool attached)
{ {
char cable_name[32];
int ret = 0; int ret = 0;
u8 path = CONTROL1_SW_OPEN; u8 path = CONTROL1_SW_OPEN;
...@@ -652,23 +623,13 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info, ...@@ -652,23 +623,13 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info,
switch (cable_type) { switch (cable_type) {
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */ case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
/* PATH:AP_USB */
strcpy(cable_name, "JIG-USB-OFF");
path = CONTROL1_SW_USB;
break;
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */ case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
/* PATH:AP_USB */ /* PATH:AP_USB */
strcpy(cable_name, "JIG-USB-ON");
path = CONTROL1_SW_USB; path = CONTROL1_SW_USB;
break; break;
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */ case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
/* PATH:AP_UART */
strcpy(cable_name, "JIG-UART-OFF");
path = CONTROL1_SW_UART;
break;
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* ADC_JIG_UART_ON */ case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* ADC_JIG_UART_ON */
/* PATH:AP_UART */ /* PATH:AP_UART */
strcpy(cable_name, "JIG-UART-ON");
path = CONTROL1_SW_UART; path = CONTROL1_SW_UART;
break; break;
default: default:
...@@ -681,7 +642,7 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info, ...@@ -681,7 +642,7 @@ static int max77693_muic_jig_handler(struct max77693_muic_info *info,
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, cable_name, attached); extcon_set_cable_state_(info->edev, EXTCON_JIG, attached);
return 0; return 0;
} }
...@@ -823,22 +784,22 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) ...@@ -823,22 +784,22 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
case MAX77693_MUIC_GND_MHL: case MAX77693_MUIC_GND_MHL:
case MAX77693_MUIC_GND_MHL_VB: case MAX77693_MUIC_GND_MHL_VB:
/* /*
* MHL cable with MHL-TA(USB/TA) cable * MHL cable with USB/TA cable
* - MHL cable include two port(HDMI line and separate * - MHL cable include two port(HDMI line and separate
* micro-usb port. When the target connect MHL cable, * micro-usb port. When the target connect MHL cable,
* extcon driver check whether MHL-TA(USB/TA) cable is * extcon driver check whether USB/TA cable is
* connected. If MHL-TA cable is connected, extcon * connected. If USB/TA cable is connected, extcon
* driver notify state to notifiee for charging battery. * driver notify state to notifiee for charging battery.
* *
* Features of 'MHL-TA(USB/TA) with MHL cable' * Features of 'USB/TA with MHL cable'
* - Support MHL * - Support MHL
* - Support charging through micro-usb port without * - Support charging through micro-usb port without
* data connection * data connection
*/ */
extcon_set_cable_state(info->edev, "MHL-TA", attached); extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
if (!cable_attached) if (!cable_attached)
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_MHL,
"MHL", cable_attached); cable_attached);
break; break;
} }
...@@ -861,10 +822,11 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) ...@@ -861,10 +822,11 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
* - Support charging through micro-usb port without * - Support charging through micro-usb port without
* data connection. * data connection.
*/ */
extcon_set_cable_state(info->edev, "USB", attached); extcon_set_cable_state_(info->edev, EXTCON_USB,
attached);
if (!cable_attached) if (!cable_attached)
extcon_set_cable_state(info->edev, "Dock-Audio", extcon_set_cable_state_(info->edev, EXTCON_DOCK,
cable_attached); cable_attached);
break; break;
case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */ case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */
...@@ -893,10 +855,10 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) ...@@ -893,10 +855,10 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "Dock-Smart", extcon_set_cable_state_(info->edev, EXTCON_DOCK,
attached);
extcon_set_cable_state_(info->edev, EXTCON_MHL,
attached); attached);
extcon_set_cable_state(info->edev, "MHL", attached);
break; break;
} }
...@@ -929,23 +891,26 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info) ...@@ -929,23 +891,26 @@ static int max77693_muic_chg_handler(struct max77693_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "USB", attached); extcon_set_cable_state_(info->edev, EXTCON_USB,
attached);
break; break;
case MAX77693_CHARGER_TYPE_DEDICATED_CHG: case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
/* Only TA cable */ /* Only TA cable */
extcon_set_cable_state(info->edev, "TA", attached); extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
break; break;
} }
break; break;
case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT: case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM,
"Charge-downstream", attached); attached);
break; break;
case MAX77693_CHARGER_TYPE_APPLE_500MA: case MAX77693_CHARGER_TYPE_APPLE_500MA:
extcon_set_cable_state(info->edev, "Slow-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER,
attached);
break; break;
case MAX77693_CHARGER_TYPE_APPLE_1A_2A: case MAX77693_CHARGER_TYPE_APPLE_1A_2A:
extcon_set_cable_state(info->edev, "Fast-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER,
attached);
break; break;
case MAX77693_CHARGER_TYPE_DEAD_BATTERY: case MAX77693_CHARGER_TYPE_DEAD_BATTERY:
break; break;
...@@ -1182,7 +1147,6 @@ static int max77693_muic_probe(struct platform_device *pdev) ...@@ -1182,7 +1147,6 @@ static int max77693_muic_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
return -ENOMEM; return -ENOMEM;
} }
info->edev->name = DEV_NAME;
ret = devm_extcon_dev_register(&pdev->dev, info->edev); ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret) { if (ret) {
......
...@@ -118,36 +118,16 @@ enum max77843_muic_charger_type { ...@@ -118,36 +118,16 @@ enum max77843_muic_charger_type {
MAX77843_MUIC_CHG_GND, MAX77843_MUIC_CHG_GND,
}; };
enum { static const unsigned int max77843_extcon_cable[] = {
MAX77843_CABLE_USB = 0, EXTCON_USB,
MAX77843_CABLE_USB_HOST, EXTCON_USB_HOST,
MAX77843_CABLE_TA, EXTCON_TA,
MAX77843_CABLE_CHARGE_DOWNSTREAM, EXTCON_CHARGE_DOWNSTREAM,
MAX77843_CABLE_FAST_CHARGER, EXTCON_FAST_CHARGER,
MAX77843_CABLE_SLOW_CHARGER, EXTCON_SLOW_CHARGER,
MAX77843_CABLE_MHL, EXTCON_MHL,
MAX77843_CABLE_MHL_TA, EXTCON_JIG,
MAX77843_CABLE_JIG_USB_ON, EXTCON_NONE,
MAX77843_CABLE_JIG_USB_OFF,
MAX77843_CABLE_JIG_UART_ON,
MAX77843_CABLE_JIG_UART_OFF,
MAX77843_CABLE_NUM,
};
static const char *max77843_extcon_cable[] = {
[MAX77843_CABLE_USB] = "USB",
[MAX77843_CABLE_USB_HOST] = "USB-HOST",
[MAX77843_CABLE_TA] = "TA",
[MAX77843_CABLE_CHARGE_DOWNSTREAM] = "CHARGER-DOWNSTREAM",
[MAX77843_CABLE_FAST_CHARGER] = "FAST-CHARGER",
[MAX77843_CABLE_SLOW_CHARGER] = "SLOW-CHARGER",
[MAX77843_CABLE_MHL] = "MHL",
[MAX77843_CABLE_MHL_TA] = "MHL-TA",
[MAX77843_CABLE_JIG_USB_ON] = "JIG-USB-ON",
[MAX77843_CABLE_JIG_USB_OFF] = "JIG-USB-OFF",
[MAX77843_CABLE_JIG_UART_ON] = "JIG-UART-ON",
[MAX77843_CABLE_JIG_UART_OFF] = "JIG-UART-OFF",
}; };
struct max77843_muic_irq { struct max77843_muic_irq {
...@@ -362,7 +342,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) ...@@ -362,7 +342,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "USB-HOST", attached); extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached);
break; break;
case MAX77843_MUIC_GND_MHL_VB: case MAX77843_MUIC_GND_MHL_VB:
case MAX77843_MUIC_GND_MHL: case MAX77843_MUIC_GND_MHL:
...@@ -370,7 +350,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info) ...@@ -370,7 +350,7 @@ static int max77843_muic_adc_gnd_handler(struct max77843_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "MHL", attached); extcon_set_cable_state_(info->edev, EXTCON_MHL, attached);
break; break;
default: default:
dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n", dev_err(info->dev, "failed to detect %s accessory(gnd:0x%x)\n",
...@@ -385,35 +365,28 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info, ...@@ -385,35 +365,28 @@ static int max77843_muic_jig_handler(struct max77843_muic_info *info,
int cable_type, bool attached) int cable_type, bool attached)
{ {
int ret; int ret;
u8 path = CONTROL1_SW_OPEN;
dev_dbg(info->dev, "external connector is %s (adc:0x%02x)\n", dev_dbg(info->dev, "external connector is %s (adc:0x%02x)\n",
attached ? "attached" : "detached", cable_type); attached ? "attached" : "detached", cable_type);
switch (cable_type) { switch (cable_type) {
case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF: case MAX77843_MUIC_ADC_FACTORY_MODE_USB_OFF:
ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached);
if (ret < 0)
return ret;
extcon_set_cable_state(info->edev, "JIG-USB-OFF", attached);
break;
case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON: case MAX77843_MUIC_ADC_FACTORY_MODE_USB_ON:
ret = max77843_muic_set_path(info, CONTROL1_SW_USB, attached); path = CONTROL1_SW_USB;
if (ret < 0)
return ret;
extcon_set_cable_state(info->edev, "JIG-USB-ON", attached);
break; break;
case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF: case MAX77843_MUIC_ADC_FACTORY_MODE_UART_OFF:
ret = max77843_muic_set_path(info, CONTROL1_SW_UART, attached); path = CONTROL1_SW_UART;
if (ret < 0)
return ret;
extcon_set_cable_state(info->edev, "JIG-UART-OFF", attached);
break; break;
default: default:
ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); return -EINVAL;
}
ret = max77843_muic_set_path(info, path, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
break;
} extcon_set_cable_state_(info->edev, EXTCON_JIG, attached);
return 0; return 0;
} }
...@@ -505,36 +478,38 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) ...@@ -505,36 +478,38 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "USB", attached); extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
break; break;
case MAX77843_MUIC_CHG_DOWNSTREAM: case MAX77843_MUIC_CHG_DOWNSTREAM:
ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM,
"CHARGER-DOWNSTREAM", attached); attached);
break; break;
case MAX77843_MUIC_CHG_DEDICATED: case MAX77843_MUIC_CHG_DEDICATED:
ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "TA", attached); extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
break; break;
case MAX77843_MUIC_CHG_SPECIAL_500MA: case MAX77843_MUIC_CHG_SPECIAL_500MA:
ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "SLOW-CHAREGER", attached); extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER,
attached);
break; break;
case MAX77843_MUIC_CHG_SPECIAL_1A: case MAX77843_MUIC_CHG_SPECIAL_1A:
ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached); ret = max77843_muic_set_path(info, CONTROL1_SW_OPEN, attached);
if (ret < 0) if (ret < 0)
return ret; return ret;
extcon_set_cable_state(info->edev, "FAST-CHARGER", attached); extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER,
attached);
break; break;
case MAX77843_MUIC_CHG_GND: case MAX77843_MUIC_CHG_GND:
gnd_type = max77843_muic_get_cable_type(info, gnd_type = max77843_muic_get_cable_type(info,
...@@ -542,9 +517,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info) ...@@ -542,9 +517,9 @@ static int max77843_muic_chg_handler(struct max77843_muic_info *info)
/* Charger cable on MHL accessory is attach or detach */ /* Charger cable on MHL accessory is attach or detach */
if (gnd_type == MAX77843_MUIC_GND_MHL_VB) if (gnd_type == MAX77843_MUIC_GND_MHL_VB)
extcon_set_cable_state(info->edev, "MHL-TA", true); extcon_set_cable_state_(info->edev, EXTCON_TA, true);
else if (gnd_type == MAX77843_MUIC_GND_MHL) else if (gnd_type == MAX77843_MUIC_GND_MHL)
extcon_set_cable_state(info->edev, "MHL-TA", false); extcon_set_cable_state_(info->edev, EXTCON_TA, false);
break; break;
case MAX77843_MUIC_CHG_NONE: case MAX77843_MUIC_CHG_NONE:
break; break;
......
...@@ -145,34 +145,17 @@ struct max8997_muic_info { ...@@ -145,34 +145,17 @@ struct max8997_muic_info {
int path_uart; int path_uart;
}; };
enum { static const unsigned int max8997_extcon_cable[] = {
EXTCON_CABLE_USB = 0, EXTCON_USB,
EXTCON_CABLE_USB_HOST, EXTCON_USB_HOST,
EXTCON_CABLE_TA, EXTCON_TA,
EXTCON_CABLE_FAST_CHARGER, EXTCON_FAST_CHARGER,
EXTCON_CABLE_SLOW_CHARGER, EXTCON_SLOW_CHARGER,
EXTCON_CABLE_CHARGE_DOWNSTREAM, EXTCON_CHARGE_DOWNSTREAM,
EXTCON_CABLE_MHL, EXTCON_MHL,
EXTCON_CABLE_DOCK_DESK, EXTCON_DOCK,
EXTCON_CABLE_DOCK_CARD, EXTCON_JIG,
EXTCON_CABLE_JIG, EXTCON_NONE,
_EXTCON_CABLE_NUM,
};
static const char *max8997_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_USB_HOST] = "USB-Host",
[EXTCON_CABLE_TA] = "TA",
[EXTCON_CABLE_FAST_CHARGER] = "Fast-charger",
[EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger",
[EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream",
[EXTCON_CABLE_MHL] = "MHL",
[EXTCON_CABLE_DOCK_DESK] = "Dock-Desk",
[EXTCON_CABLE_DOCK_CARD] = "Dock-Card",
[EXTCON_CABLE_JIG] = "JIG",
NULL,
}; };
/* /*
...@@ -347,10 +330,10 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info, ...@@ -347,10 +330,10 @@ static int max8997_muic_handle_usb(struct max8997_muic_info *info,
switch (usb_type) { switch (usb_type) {
case MAX8997_USB_HOST: case MAX8997_USB_HOST:
extcon_set_cable_state(info->edev, "USB-Host", attached); extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, attached);
break; break;
case MAX8997_USB_DEVICE: case MAX8997_USB_DEVICE:
extcon_set_cable_state(info->edev, "USB", attached); extcon_set_cable_state_(info->edev, EXTCON_USB, attached);
break; break;
default: default:
dev_err(info->dev, "failed to detect %s usb cable\n", dev_err(info->dev, "failed to detect %s usb cable\n",
...@@ -374,10 +357,8 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info, ...@@ -374,10 +357,8 @@ static int max8997_muic_handle_dock(struct max8997_muic_info *info,
switch (cable_type) { switch (cable_type) {
case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD: case MAX8997_MUIC_ADC_AV_CABLE_NOLOAD:
extcon_set_cable_state(info->edev, "Dock-desk", attached);
break;
case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON: case MAX8997_MUIC_ADC_FACTORY_MODE_UART_ON:
extcon_set_cable_state(info->edev, "Dock-card", attached); extcon_set_cable_state_(info->edev, EXTCON_DOCK, attached);
break; break;
default: default:
dev_err(info->dev, "failed to detect %s dock device\n", dev_err(info->dev, "failed to detect %s dock device\n",
...@@ -400,7 +381,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, ...@@ -400,7 +381,7 @@ static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
return ret; return ret;
} }
extcon_set_cable_state(info->edev, "JIG", attached); extcon_set_cable_state_(info->edev, EXTCON_JIG, attached);
return 0; return 0;
} }
...@@ -422,7 +403,7 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info) ...@@ -422,7 +403,7 @@ static int max8997_muic_adc_handler(struct max8997_muic_info *info)
return ret; return ret;
break; break;
case MAX8997_MUIC_ADC_MHL: case MAX8997_MUIC_ADC_MHL:
extcon_set_cable_state(info->edev, "MHL", attached); extcon_set_cable_state_(info->edev, EXTCON_MHL, attached);
break; break;
case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF: case MAX8997_MUIC_ADC_FACTORY_MODE_USB_OFF:
case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON: case MAX8997_MUIC_ADC_FACTORY_MODE_USB_ON:
...@@ -505,17 +486,19 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info) ...@@ -505,17 +486,19 @@ static int max8997_muic_chg_handler(struct max8997_muic_info *info)
} }
break; break;
case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_CHARGE_DOWNSTREAM,
"Charge-downstream", attached); attached);
break; break;
case MAX8997_CHARGER_TYPE_DEDICATED_CHG: case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
extcon_set_cable_state(info->edev, "TA", attached); extcon_set_cable_state_(info->edev, EXTCON_TA, attached);
break; break;
case MAX8997_CHARGER_TYPE_500MA: case MAX8997_CHARGER_TYPE_500MA:
extcon_set_cable_state(info->edev, "Slow-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_SLOW_CHARGER,
attached);
break; break;
case MAX8997_CHARGER_TYPE_1A: case MAX8997_CHARGER_TYPE_1A:
extcon_set_cable_state(info->edev, "Fast-charger", attached); extcon_set_cable_state_(info->edev, EXTCON_FAST_CHARGER,
attached);
break; break;
default: default:
dev_err(info->dev, dev_err(info->dev,
...@@ -700,7 +683,6 @@ static int max8997_muic_probe(struct platform_device *pdev) ...@@ -700,7 +683,6 @@ static int max8997_muic_probe(struct platform_device *pdev)
ret = -ENOMEM; ret = -ENOMEM;
goto err_irq; goto err_irq;
} }
info->edev->name = DEV_NAME;
ret = devm_extcon_dev_register(&pdev->dev, info->edev); ret = devm_extcon_dev_register(&pdev->dev, info->edev);
if (ret) { if (ret) {
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
static const char *palmas_extcon_cable[] = { static const unsigned int palmas_extcon_cable[] = {
[0] = "USB", EXTCON_USB,
[1] = "USB-HOST", EXTCON_USB_HOST,
NULL, EXTCON_NONE,
}; };
static const int mutually_exclusive[] = {0x3, 0x0}; static const int mutually_exclusive[] = {0x3, 0x0};
...@@ -49,6 +49,7 @@ static void palmas_usb_wakeup(struct palmas *palmas, int enable) ...@@ -49,6 +49,7 @@ static void palmas_usb_wakeup(struct palmas *palmas, int enable)
static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
{ {
struct palmas_usb *palmas_usb = _palmas_usb; struct palmas_usb *palmas_usb = _palmas_usb;
struct extcon_dev *edev = palmas_usb->edev;
unsigned int vbus_line_state; unsigned int vbus_line_state;
palmas_read(palmas_usb->palmas, PALMAS_INTERRUPT_BASE, palmas_read(palmas_usb->palmas, PALMAS_INTERRUPT_BASE,
...@@ -57,7 +58,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) ...@@ -57,7 +58,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) { if (vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS) {
if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) { if (palmas_usb->linkstat != PALMAS_USB_STATE_VBUS) {
palmas_usb->linkstat = PALMAS_USB_STATE_VBUS; palmas_usb->linkstat = PALMAS_USB_STATE_VBUS;
extcon_set_cable_state(palmas_usb->edev, "USB", true); extcon_set_cable_state_(edev, EXTCON_USB, true);
dev_info(palmas_usb->dev, "USB cable is attached\n"); dev_info(palmas_usb->dev, "USB cable is attached\n");
} else { } else {
dev_dbg(palmas_usb->dev, dev_dbg(palmas_usb->dev,
...@@ -66,7 +67,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb) ...@@ -66,7 +67,7 @@ static irqreturn_t palmas_vbus_irq_handler(int irq, void *_palmas_usb)
} else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) { } else if (!(vbus_line_state & PALMAS_INT3_LINE_STATE_VBUS)) {
if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) { if (palmas_usb->linkstat == PALMAS_USB_STATE_VBUS) {
palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
extcon_set_cable_state(palmas_usb->edev, "USB", false); extcon_set_cable_state_(edev, EXTCON_USB, false);
dev_info(palmas_usb->dev, "USB cable is detached\n"); dev_info(palmas_usb->dev, "USB cable is detached\n");
} else { } else {
dev_dbg(palmas_usb->dev, dev_dbg(palmas_usb->dev,
...@@ -81,6 +82,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) ...@@ -81,6 +82,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
{ {
unsigned int set, id_src; unsigned int set, id_src;
struct palmas_usb *palmas_usb = _palmas_usb; struct palmas_usb *palmas_usb = _palmas_usb;
struct extcon_dev *edev = palmas_usb->edev;
palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE, palmas_read(palmas_usb->palmas, PALMAS_USB_OTG_BASE,
PALMAS_USB_ID_INT_LATCH_SET, &set); PALMAS_USB_ID_INT_LATCH_SET, &set);
...@@ -93,7 +95,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) ...@@ -93,7 +95,7 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
PALMAS_USB_ID_INT_LATCH_CLR, PALMAS_USB_ID_INT_LATCH_CLR,
PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND); PALMAS_USB_ID_INT_EN_HI_CLR_ID_GND);
palmas_usb->linkstat = PALMAS_USB_STATE_ID; palmas_usb->linkstat = PALMAS_USB_STATE_ID;
extcon_set_cable_state(palmas_usb->edev, "USB-HOST", true); extcon_set_cable_state_(edev, EXTCON_USB_HOST, true);
dev_info(palmas_usb->dev, "USB-HOST cable is attached\n"); dev_info(palmas_usb->dev, "USB-HOST cable is attached\n");
} else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) && } else if ((set & PALMAS_USB_ID_INT_SRC_ID_FLOAT) &&
(id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) { (id_src & PALMAS_USB_ID_INT_SRC_ID_FLOAT)) {
...@@ -101,17 +103,17 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb) ...@@ -101,17 +103,17 @@ static irqreturn_t palmas_id_irq_handler(int irq, void *_palmas_usb)
PALMAS_USB_ID_INT_LATCH_CLR, PALMAS_USB_ID_INT_LATCH_CLR,
PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT); PALMAS_USB_ID_INT_EN_HI_CLR_ID_FLOAT);
palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
extcon_set_cable_state(palmas_usb->edev, "USB-HOST", false); extcon_set_cable_state_(edev, EXTCON_USB_HOST, false);
dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
} else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) && } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_ID) &&
(!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) { (!(set & PALMAS_USB_ID_INT_SRC_ID_GND))) {
palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT; palmas_usb->linkstat = PALMAS_USB_STATE_DISCONNECT;
extcon_set_cable_state(palmas_usb->edev, "USB-HOST", false); extcon_set_cable_state_(edev, EXTCON_USB_HOST, false);
dev_info(palmas_usb->dev, "USB-HOST cable is detached\n"); dev_info(palmas_usb->dev, "USB-HOST cable is detached\n");
} else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) && } else if ((palmas_usb->linkstat == PALMAS_USB_STATE_DISCONNECT) &&
(id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) { (id_src & PALMAS_USB_ID_INT_SRC_ID_GND)) {
palmas_usb->linkstat = PALMAS_USB_STATE_ID; palmas_usb->linkstat = PALMAS_USB_STATE_ID;
extcon_set_cable_state(palmas_usb->edev, "USB-HOST", true); extcon_set_cable_state_(edev, EXTCON_USB_HOST, true);
dev_info(palmas_usb->dev, " USB-HOST cable is attached\n"); dev_info(palmas_usb->dev, " USB-HOST cable is attached\n");
} }
...@@ -193,7 +195,6 @@ static int palmas_usb_probe(struct platform_device *pdev) ...@@ -193,7 +195,6 @@ static int palmas_usb_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failed to allocate extcon device\n"); dev_err(&pdev->dev, "failed to allocate extcon device\n");
return -ENOMEM; return -ENOMEM;
} }
palmas_usb->edev->name = kstrdup(node->name, GFP_KERNEL);
palmas_usb->edev->mutually_exclusive = mutually_exclusive; palmas_usb->edev->mutually_exclusive = mutually_exclusive;
status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev); status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev);
......
...@@ -90,27 +90,12 @@ static struct reg_data rt8973a_reg_data[] = { ...@@ -90,27 +90,12 @@ static struct reg_data rt8973a_reg_data[] = {
}; };
/* List of detectable cables */ /* List of detectable cables */
enum { static const unsigned int rt8973a_extcon_cable[] = {
EXTCON_CABLE_USB = 0, EXTCON_USB,
EXTCON_CABLE_USB_HOST, EXTCON_USB_HOST,
EXTCON_CABLE_TA, EXTCON_TA,
EXTCON_CABLE_JIG_OFF_USB, EXTCON_JIG,
EXTCON_CABLE_JIG_ON_USB, EXTCON_NONE,
EXTCON_CABLE_JIG_OFF_UART,
EXTCON_CABLE_JIG_ON_UART,
EXTCON_CABLE_END,
};
static const char *rt8973a_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_USB_HOST] = "USB-Host",
[EXTCON_CABLE_TA] = "TA",
[EXTCON_CABLE_JIG_OFF_USB] = "JIG-USB-OFF",
[EXTCON_CABLE_JIG_ON_USB] = "JIG-USB-ON",
[EXTCON_CABLE_JIG_OFF_UART] = "JIG-UART-OFF",
[EXTCON_CABLE_JIG_ON_UART] = "JIG-UART-ON",
NULL,
}; };
/* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */ /* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */
...@@ -313,14 +298,11 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, ...@@ -313,14 +298,11 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
enum rt8973a_event_type event) enum rt8973a_event_type event)
{ {
static unsigned int prev_cable_type; static unsigned int prev_cable_type;
const char **cable_names = info->edev->supported_cable;
unsigned int con_sw = DM_DP_SWITCH_UART; unsigned int con_sw = DM_DP_SWITCH_UART;
int ret, idx = 0, cable_type; int ret, cable_type;
unsigned int id;
bool attached = false; bool attached = false;
if (!cable_names)
return 0;
switch (event) { switch (event) {
case RT8973A_EVENT_ATTACH: case RT8973A_EVENT_ATTACH:
cable_type = rt8973a_muic_get_cable_type(info); cable_type = rt8973a_muic_get_cable_type(info);
...@@ -347,31 +329,25 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, ...@@ -347,31 +329,25 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
switch (cable_type) { switch (cable_type) {
case RT8973A_MUIC_ADC_OTG: case RT8973A_MUIC_ADC_OTG:
idx = EXTCON_CABLE_USB_HOST; id = EXTCON_USB_HOST;
con_sw = DM_DP_SWITCH_USB; con_sw = DM_DP_SWITCH_USB;
break; break;
case RT8973A_MUIC_ADC_TA: case RT8973A_MUIC_ADC_TA:
idx = EXTCON_CABLE_TA; id = EXTCON_TA;
con_sw = DM_DP_SWITCH_OPEN; con_sw = DM_DP_SWITCH_OPEN;
break; break;
case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB: case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
idx = EXTCON_CABLE_JIG_OFF_USB;
con_sw = DM_DP_SWITCH_UART;
break;
case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB: case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
idx = EXTCON_CABLE_JIG_ON_USB; id = EXTCON_JIG;
con_sw = DM_DP_SWITCH_UART; con_sw = DM_DP_SWITCH_USB;
break; break;
case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART: case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
idx = EXTCON_CABLE_JIG_OFF_UART;
con_sw = DM_DP_SWITCH_UART;
break;
case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART: case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
idx = EXTCON_CABLE_JIG_ON_UART; id = EXTCON_JIG;
con_sw = DM_DP_SWITCH_UART; con_sw = DM_DP_SWITCH_UART;
break; break;
case RT8973A_MUIC_ADC_USB: case RT8973A_MUIC_ADC_USB:
idx = EXTCON_CABLE_USB; id = EXTCON_USB;
con_sw = DM_DP_SWITCH_USB; con_sw = DM_DP_SWITCH_USB;
break; break;
case RT8973A_MUIC_ADC_OPEN: case RT8973A_MUIC_ADC_OPEN:
...@@ -421,7 +397,7 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info, ...@@ -421,7 +397,7 @@ static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
return ret; return ret;
/* Change the state of external accessory */ /* Change the state of external accessory */
extcon_set_cable_state(info->edev, cable_names[idx], attached); extcon_set_cable_state_(info->edev, id, attached);
return 0; return 0;
} }
...@@ -643,7 +619,6 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c, ...@@ -643,7 +619,6 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c,
dev_err(info->dev, "failed to allocate memory for extcon\n"); dev_err(info->dev, "failed to allocate memory for extcon\n");
return -ENOMEM; return -ENOMEM;
} }
info->edev->name = np->name;
/* Register extcon device */ /* Register extcon device */
ret = devm_extcon_dev_register(info->dev, info->edev); ret = devm_extcon_dev_register(info->dev, info->edev);
......
...@@ -92,19 +92,11 @@ static struct reg_data sm5502_reg_data[] = { ...@@ -92,19 +92,11 @@ static struct reg_data sm5502_reg_data[] = {
}; };
/* List of detectable cables */ /* List of detectable cables */
enum { static const unsigned int sm5502_extcon_cable[] = {
EXTCON_CABLE_USB = 0, EXTCON_USB,
EXTCON_CABLE_USB_HOST, EXTCON_USB_HOST,
EXTCON_CABLE_TA, EXTCON_TA,
EXTCON_NONE,
EXTCON_CABLE_END,
};
static const char *sm5502_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_USB_HOST] = "USB-Host",
[EXTCON_CABLE_TA] = "TA",
NULL,
}; };
/* Define supported accessory type */ /* Define supported accessory type */
...@@ -377,16 +369,12 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, ...@@ -377,16 +369,12 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
bool attached) bool attached)
{ {
static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND; static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND;
const char **cable_names = info->edev->supported_cable;
unsigned int cable_type = SM5502_MUIC_ADC_GROUND; unsigned int cable_type = SM5502_MUIC_ADC_GROUND;
unsigned int con_sw = DM_DP_SWITCH_OPEN; unsigned int con_sw = DM_DP_SWITCH_OPEN;
unsigned int vbus_sw = VBUSIN_SWITCH_OPEN; unsigned int vbus_sw = VBUSIN_SWITCH_OPEN;
unsigned int idx = 0; unsigned int id;
int ret; int ret;
if (!cable_names)
return 0;
/* Get the type of attached or detached cable */ /* Get the type of attached or detached cable */
if (attached) if (attached)
cable_type = sm5502_muic_get_cable_type(info); cable_type = sm5502_muic_get_cable_type(info);
...@@ -396,17 +384,17 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, ...@@ -396,17 +384,17 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
switch (cable_type) { switch (cable_type) {
case SM5502_MUIC_ADC_OPEN_USB: case SM5502_MUIC_ADC_OPEN_USB:
idx = EXTCON_CABLE_USB; id = EXTCON_USB;
con_sw = DM_DP_SWITCH_USB; con_sw = DM_DP_SWITCH_USB;
vbus_sw = VBUSIN_SWITCH_VBUSOUT_WITH_USB; vbus_sw = VBUSIN_SWITCH_VBUSOUT_WITH_USB;
break; break;
case SM5502_MUIC_ADC_OPEN_TA: case SM5502_MUIC_ADC_OPEN_TA:
idx = EXTCON_CABLE_TA; id = EXTCON_TA;
con_sw = DM_DP_SWITCH_OPEN; con_sw = DM_DP_SWITCH_OPEN;
vbus_sw = VBUSIN_SWITCH_VBUSOUT; vbus_sw = VBUSIN_SWITCH_VBUSOUT;
break; break;
case SM5502_MUIC_ADC_OPEN_USB_OTG: case SM5502_MUIC_ADC_OPEN_USB_OTG:
idx = EXTCON_CABLE_USB_HOST; id = EXTCON_USB_HOST;
con_sw = DM_DP_SWITCH_USB; con_sw = DM_DP_SWITCH_USB;
vbus_sw = VBUSIN_SWITCH_OPEN; vbus_sw = VBUSIN_SWITCH_OPEN;
break; break;
...@@ -422,7 +410,7 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info, ...@@ -422,7 +410,7 @@ static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
return ret; return ret;
/* Change the state of external accessory */ /* Change the state of external accessory */
extcon_set_cable_state(info->edev, cable_names[idx], attached); extcon_set_cable_state_(info->edev, id, attached);
return 0; return 0;
} }
...@@ -623,7 +611,6 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c, ...@@ -623,7 +611,6 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
dev_err(info->dev, "failed to allocate memory for extcon\n"); dev_err(info->dev, "failed to allocate memory for extcon\n");
return -ENOMEM; return -ENOMEM;
} }
info->edev->name = np->name;
/* Register extcon device */ /* Register extcon device */
ret = devm_extcon_dev_register(info->dev, info->edev); ret = devm_extcon_dev_register(info->dev, info->edev);
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <linux/extcon.h> #include <linux/extcon.h>
#include <linux/gpio/consumer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irq.h> #include <linux/irq.h>
...@@ -38,18 +39,10 @@ struct usb_extcon_info { ...@@ -38,18 +39,10 @@ struct usb_extcon_info {
struct delayed_work wq_detcable; struct delayed_work wq_detcable;
}; };
/* List of detectable cables */ static const unsigned int usb_extcon_cable[] = {
enum { EXTCON_USB,
EXTCON_CABLE_USB = 0, EXTCON_USB_HOST,
EXTCON_CABLE_USB_HOST, EXTCON_NONE,
EXTCON_CABLE_END,
};
static const char *usb_extcon_cable[] = {
[EXTCON_CABLE_USB] = "USB",
[EXTCON_CABLE_USB_HOST] = "USB-HOST",
NULL,
}; };
static void usb_extcon_detect_cable(struct work_struct *work) static void usb_extcon_detect_cable(struct work_struct *work)
...@@ -67,24 +60,16 @@ static void usb_extcon_detect_cable(struct work_struct *work) ...@@ -67,24 +60,16 @@ static void usb_extcon_detect_cable(struct work_struct *work)
* As we don't have event for USB peripheral cable attached, * As we don't have event for USB peripheral cable attached,
* we simulate USB peripheral attach here. * we simulate USB peripheral attach here.
*/ */
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, false);
usb_extcon_cable[EXTCON_CABLE_USB_HOST], extcon_set_cable_state_(info->edev, EXTCON_USB, true);
false);
extcon_set_cable_state(info->edev,
usb_extcon_cable[EXTCON_CABLE_USB],
true);
} else { } else {
/* /*
* ID = 0 means USB HOST cable attached. * ID = 0 means USB HOST cable attached.
* As we don't have event for USB peripheral cable detached, * As we don't have event for USB peripheral cable detached,
* we simulate USB peripheral detach here. * we simulate USB peripheral detach here.
*/ */
extcon_set_cable_state(info->edev, extcon_set_cable_state_(info->edev, EXTCON_USB, false);
usb_extcon_cable[EXTCON_CABLE_USB], extcon_set_cable_state_(info->edev, EXTCON_USB_HOST, true);
false);
extcon_set_cable_state(info->edev,
usb_extcon_cable[EXTCON_CABLE_USB_HOST],
true);
} }
} }
...@@ -113,7 +98,7 @@ static int usb_extcon_probe(struct platform_device *pdev) ...@@ -113,7 +98,7 @@ static int usb_extcon_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
info->dev = dev; info->dev = dev;
info->id_gpiod = devm_gpiod_get(&pdev->dev, "id"); info->id_gpiod = devm_gpiod_get(&pdev->dev, "id", GPIOD_IN);
if (IS_ERR(info->id_gpiod)) { if (IS_ERR(info->id_gpiod)) {
dev_err(dev, "failed to get ID GPIO\n"); dev_err(dev, "failed to get ID GPIO\n");
return PTR_ERR(info->id_gpiod); return PTR_ERR(info->id_gpiod);
......
This diff is collapsed.
...@@ -5,4 +5,4 @@ obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o ...@@ -5,4 +5,4 @@ obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o
hv_vmbus-y := vmbus_drv.o \ hv_vmbus-y := vmbus_drv.o \
hv.o connection.o channel.o \ hv.o connection.o channel.o \
channel_mgmt.o ring_buffer.o channel_mgmt.o ring_buffer.o
hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_fcopy.o hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_fcopy.o hv_utils_transport.o
...@@ -73,6 +73,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -73,6 +73,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
unsigned long flags; unsigned long flags;
int ret, err = 0; int ret, err = 0;
unsigned long t; unsigned long t;
struct page *page;
spin_lock_irqsave(&newchannel->lock, flags); spin_lock_irqsave(&newchannel->lock, flags);
if (newchannel->state == CHANNEL_OPEN_STATE) { if (newchannel->state == CHANNEL_OPEN_STATE) {
...@@ -87,8 +88,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -87,8 +88,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
newchannel->channel_callback_context = context; newchannel->channel_callback_context = context;
/* Allocate the ring buffer */ /* Allocate the ring buffer */
page = alloc_pages_node(cpu_to_node(newchannel->target_cpu),
GFP_KERNEL|__GFP_ZERO,
get_order(send_ringbuffer_size +
recv_ringbuffer_size));
if (!page)
out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, out = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
get_order(send_ringbuffer_size + recv_ringbuffer_size)); get_order(send_ringbuffer_size +
recv_ringbuffer_size));
else
out = (void *)page_address(page);
if (!out) { if (!out) {
err = -ENOMEM; err = -ENOMEM;
...@@ -178,19 +188,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, ...@@ -178,19 +188,18 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
goto error1; goto error1;
} }
if (open_info->response.open_result.status)
err = open_info->response.open_result.status;
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
list_del(&open_info->msglistentry); list_del(&open_info->msglistentry);
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
if (err == 0) if (open_info->response.open_result.status) {
newchannel->state = CHANNEL_OPENED_STATE; err = -EAGAIN;
goto error_gpadl;
}
newchannel->state = CHANNEL_OPENED_STATE;
kfree(open_info); kfree(open_info);
return err; return 0;
error1: error1:
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
......
...@@ -32,6 +32,9 @@ ...@@ -32,6 +32,9 @@
#include "hyperv_vmbus.h" #include "hyperv_vmbus.h"
static void init_vp_index(struct vmbus_channel *channel,
const uuid_le *type_guid);
/** /**
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
* @icmsghdrp: Pointer to msg header structure * @icmsghdrp: Pointer to msg header structure
...@@ -205,6 +208,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) ...@@ -205,6 +208,7 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
primary_channel = channel->primary_channel; primary_channel = channel->primary_channel;
spin_lock_irqsave(&primary_channel->lock, flags); spin_lock_irqsave(&primary_channel->lock, flags);
list_del(&channel->sc_list); list_del(&channel->sc_list);
primary_channel->num_sc--;
spin_unlock_irqrestore(&primary_channel->lock, flags); spin_unlock_irqrestore(&primary_channel->lock, flags);
} }
free_channel(channel); free_channel(channel);
...@@ -212,11 +216,16 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid) ...@@ -212,11 +216,16 @@ void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid)
void vmbus_free_channels(void) void vmbus_free_channels(void)
{ {
struct vmbus_channel *channel; struct vmbus_channel *channel, *tmp;
list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list,
listentry) {
/* if we don't set rescind to true, vmbus_close_internal()
* won't invoke hv_process_channel_removal().
*/
channel->rescind = true;
list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
vmbus_device_unregister(channel->device_obj); vmbus_device_unregister(channel->device_obj);
free_channel(channel);
} }
} }
...@@ -228,7 +237,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -228,7 +237,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
{ {
struct vmbus_channel *channel; struct vmbus_channel *channel;
bool fnew = true; bool fnew = true;
bool enq = false;
unsigned long flags; unsigned long flags;
/* Make sure this is a new offer */ /* Make sure this is a new offer */
...@@ -244,25 +252,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -244,25 +252,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
} }
} }
if (fnew) { if (fnew)
list_add_tail(&newchannel->listentry, list_add_tail(&newchannel->listentry,
&vmbus_connection.chn_list); &vmbus_connection.chn_list);
enq = true;
}
spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
if (enq) {
if (newchannel->target_cpu != get_cpu()) {
put_cpu();
smp_call_function_single(newchannel->target_cpu,
percpu_channel_enq,
newchannel, true);
} else {
percpu_channel_enq(newchannel);
put_cpu();
}
}
if (!fnew) { if (!fnew) {
/* /*
* Check to see if this is a sub-channel. * Check to see if this is a sub-channel.
...@@ -274,7 +269,13 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -274,7 +269,13 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
newchannel->primary_channel = channel; newchannel->primary_channel = channel;
spin_lock_irqsave(&channel->lock, flags); spin_lock_irqsave(&channel->lock, flags);
list_add_tail(&newchannel->sc_list, &channel->sc_list); list_add_tail(&newchannel->sc_list, &channel->sc_list);
channel->num_sc++;
spin_unlock_irqrestore(&channel->lock, flags); spin_unlock_irqrestore(&channel->lock, flags);
} else
goto err_free_chan;
}
init_vp_index(newchannel, &newchannel->offermsg.offer.if_type);
if (newchannel->target_cpu != get_cpu()) { if (newchannel->target_cpu != get_cpu()) {
put_cpu(); put_cpu();
...@@ -286,17 +287,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -286,17 +287,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
put_cpu(); put_cpu();
} }
newchannel->state = CHANNEL_OPEN_STATE;
channel->num_sc++;
if (channel->sc_creation_callback != NULL)
channel->sc_creation_callback(newchannel);
return;
}
goto err_free_chan;
}
/* /*
* This state is used to indicate a successful open * This state is used to indicate a successful open
* so that when we do close the channel normally, we * so that when we do close the channel normally, we
...@@ -304,6 +294,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) ...@@ -304,6 +294,12 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
*/ */
newchannel->state = CHANNEL_OPEN_STATE; newchannel->state = CHANNEL_OPEN_STATE;
if (!fnew) {
if (channel->sc_creation_callback != NULL)
channel->sc_creation_callback(newchannel);
return;
}
/* /*
* Start the process of binding this offer to the driver * Start the process of binding this offer to the driver
* We need to set the DeviceObject field before calling * We need to set the DeviceObject field before calling
...@@ -374,23 +370,27 @@ static const struct hv_vmbus_device_id hp_devs[] = { ...@@ -374,23 +370,27 @@ static const struct hv_vmbus_device_id hp_devs[] = {
/* /*
* We use this state to statically distribute the channel interrupt load. * We use this state to statically distribute the channel interrupt load.
*/ */
static u32 next_vp; static int next_numa_node_id;
/* /*
* Starting with Win8, we can statically distribute the incoming * Starting with Win8, we can statically distribute the incoming
* channel interrupt load by binding a channel to VCPU. We * channel interrupt load by binding a channel to VCPU.
* implement here a simple round robin scheme for distributing * We do this in a hierarchical fashion:
* the interrupt load. * First distribute the primary channels across available NUMA nodes
* We will bind channels that are not performance critical to cpu 0 and * and then distribute the subchannels amongst the CPUs in the NUMA
* performance critical channels (IDE, SCSI and Network) will be uniformly * node assigned to the primary channel.
* distributed across all available CPUs. *
* For pre-win8 hosts or non-performance critical channels we assign the
* first CPU in the first NUMA node.
*/ */
static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid) static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_guid)
{ {
u32 cur_cpu; u32 cur_cpu;
int i; int i;
bool perf_chn = false; bool perf_chn = false;
u32 max_cpus = num_online_cpus(); struct vmbus_channel *primary = channel->primary_channel;
int next_node;
struct cpumask available_mask;
for (i = IDE; i < MAX_PERF_CHN; i++) { for (i = IDE; i < MAX_PERF_CHN; i++) {
if (!memcmp(type_guid->b, hp_devs[i].guid, if (!memcmp(type_guid->b, hp_devs[i].guid,
...@@ -407,15 +407,76 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui ...@@ -407,15 +407,76 @@ static void init_vp_index(struct vmbus_channel *channel, const uuid_le *type_gui
* Also if the channel is not a performance critical * Also if the channel is not a performance critical
* channel, bind it to cpu 0. * channel, bind it to cpu 0.
*/ */
channel->numa_node = 0;
cpumask_set_cpu(0, &channel->alloced_cpus_in_node);
channel->target_cpu = 0; channel->target_cpu = 0;
channel->target_vp = 0; channel->target_vp = hv_context.vp_index[0];
return; return;
} }
cur_cpu = (++next_vp % max_cpus);
/*
* We distribute primary channels evenly across all the available
* NUMA nodes and within the assigned NUMA node we will assign the
* first available CPU to the primary channel.
* The sub-channels will be assigned to the CPUs available in the
* NUMA node evenly.
*/
if (!primary) {
while (true) {
next_node = next_numa_node_id++;
if (next_node == nr_node_ids)
next_node = next_numa_node_id = 0;
if (cpumask_empty(cpumask_of_node(next_node)))
continue;
break;
}
channel->numa_node = next_node;
primary = channel;
}
if (cpumask_weight(&primary->alloced_cpus_in_node) ==
cpumask_weight(cpumask_of_node(primary->numa_node))) {
/*
* We have cycled through all the CPUs in the node;
* reset the alloced map.
*/
cpumask_clear(&primary->alloced_cpus_in_node);
}
cpumask_xor(&available_mask, &primary->alloced_cpus_in_node,
cpumask_of_node(primary->numa_node));
cur_cpu = cpumask_next(-1, &available_mask);
cpumask_set_cpu(cur_cpu, &primary->alloced_cpus_in_node);
channel->target_cpu = cur_cpu; channel->target_cpu = cur_cpu;
channel->target_vp = hv_context.vp_index[cur_cpu]; channel->target_vp = hv_context.vp_index[cur_cpu];
} }
/*
* vmbus_unload_response - Handler for the unload response.
*/
static void vmbus_unload_response(struct vmbus_channel_message_header *hdr)
{
/*
* This is a global event; just wakeup the waiting thread.
* Once we successfully unload, we can cleanup the monitor state.
*/
complete(&vmbus_connection.unload_event);
}
void vmbus_initiate_unload(void)
{
struct vmbus_channel_message_header hdr;
init_completion(&vmbus_connection.unload_event);
memset(&hdr, 0, sizeof(struct vmbus_channel_message_header));
hdr.msgtype = CHANNELMSG_UNLOAD;
vmbus_post_msg(&hdr, sizeof(struct vmbus_channel_message_header));
wait_for_completion(&vmbus_connection.unload_event);
}
/* /*
* vmbus_onoffer - Handler for channel offers from vmbus in parent partition. * vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
* *
...@@ -461,8 +522,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) ...@@ -461,8 +522,6 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
offer->connection_id; offer->connection_id;
} }
init_vp_index(newchannel, &offer->offer.if_type);
memcpy(&newchannel->offermsg, offer, memcpy(&newchannel->offermsg, offer,
sizeof(struct vmbus_channel_offer_channel)); sizeof(struct vmbus_channel_offer_channel));
newchannel->monitor_grp = (u8)offer->monitorid / 32; newchannel->monitor_grp = (u8)offer->monitorid / 32;
...@@ -712,6 +771,7 @@ struct vmbus_channel_message_table_entry ...@@ -712,6 +771,7 @@ struct vmbus_channel_message_table_entry
{CHANNELMSG_INITIATE_CONTACT, 0, NULL}, {CHANNELMSG_INITIATE_CONTACT, 0, NULL},
{CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response}, {CHANNELMSG_VERSION_RESPONSE, 1, vmbus_onversion_response},
{CHANNELMSG_UNLOAD, 0, NULL}, {CHANNELMSG_UNLOAD, 0, NULL},
{CHANNELMSG_UNLOAD_RESPONSE, 1, vmbus_unload_response},
}; };
/* /*
......
...@@ -58,6 +58,9 @@ static __u32 vmbus_get_next_version(__u32 current_version) ...@@ -58,6 +58,9 @@ static __u32 vmbus_get_next_version(__u32 current_version)
case (VERSION_WIN8_1): case (VERSION_WIN8_1):
return VERSION_WIN8; return VERSION_WIN8;
case (VERSION_WIN10):
return VERSION_WIN8_1;
case (VERSION_WS2008): case (VERSION_WS2008):
default: default:
return VERSION_INVAL; return VERSION_INVAL;
...@@ -80,7 +83,7 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, ...@@ -80,7 +83,7 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page); msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]); msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]); msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
if (version == VERSION_WIN8_1) { if (version >= VERSION_WIN8_1) {
msg->target_vcpu = hv_context.vp_index[get_cpu()]; msg->target_vcpu = hv_context.vp_index[get_cpu()];
put_cpu(); put_cpu();
} }
...@@ -227,6 +230,11 @@ int vmbus_connect(void) ...@@ -227,6 +230,11 @@ int vmbus_connect(void)
void vmbus_disconnect(void) void vmbus_disconnect(void)
{ {
/*
* First send the unload request to the host.
*/
vmbus_initiate_unload();
if (vmbus_connection.work_queue) { if (vmbus_connection.work_queue) {
drain_workqueue(vmbus_connection.work_queue); drain_workqueue(vmbus_connection.work_queue);
destroy_workqueue(vmbus_connection.work_queue); destroy_workqueue(vmbus_connection.work_queue);
...@@ -371,8 +379,7 @@ void vmbus_on_event(unsigned long data) ...@@ -371,8 +379,7 @@ void vmbus_on_event(unsigned long data)
int cpu = smp_processor_id(); int cpu = smp_processor_id();
union hv_synic_event_flags *event; union hv_synic_event_flags *event;
if ((vmbus_proto_version == VERSION_WS2008) || if (vmbus_proto_version < VERSION_WIN8) {
(vmbus_proto_version == VERSION_WIN7)) {
maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5; maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
recv_int_page = vmbus_connection.recv_int_page; recv_int_page = vmbus_connection.recv_int_page;
} else { } else {
......
...@@ -567,6 +567,8 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val, ...@@ -567,6 +567,8 @@ static int hv_memory_notifier(struct notifier_block *nb, unsigned long val,
case MEM_ONLINE: case MEM_ONLINE:
dm_device.num_pages_onlined += mem->nr_pages; dm_device.num_pages_onlined += mem->nr_pages;
case MEM_CANCEL_ONLINE: case MEM_CANCEL_ONLINE:
if (val == MEM_ONLINE ||
mutex_is_locked(&dm_device.ha_region_mutex))
mutex_unlock(&dm_device.ha_region_mutex); mutex_unlock(&dm_device.ha_region_mutex);
if (dm_device.ha_waiting) { if (dm_device.ha_waiting) {
dm_device.ha_waiting = false; dm_device.ha_waiting = false;
......
This diff is collapsed.
This diff is collapsed.
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/hyperv.h> #include <linux/hyperv.h>
#include "hyperv_vmbus.h"
#include "hv_utils_transport.h"
#define VSS_MAJOR 5 #define VSS_MAJOR 5
#define VSS_MINOR 0 #define VSS_MINOR 0
#define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR) #define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR)
...@@ -31,28 +34,39 @@ ...@@ -31,28 +34,39 @@
#define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000)) #define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000))
/* /*
* Global state maintained for transaction that is being processed. * Global state maintained for transaction that is being processed. For a class
* Note that only one transaction can be active at any point in time. * of integration services, including the "VSS service", the specified protocol
* is a "request/response" protocol which means that there can only be single
* outstanding transaction from the host at any given point in time. We use
* this to simplify memory management in this driver - we cache and process
* only one message at a time.
* *
* This state is set when we receive a request from the host; we * While the request/response protocol is guaranteed by the host, we further
* cleanup this state when the transaction is completed - when we respond * ensure this by serializing packet processing in this driver - we do not
* to the host with the key value. * read additional packets from the VMBUs until the current packet is fully
* handled.
*/ */
static struct { static struct {
bool active; /* transaction status - active or not */ int state; /* hvutil_device_state */
int recv_len; /* number of bytes received. */ int recv_len; /* number of bytes received. */
struct vmbus_channel *recv_channel; /* chn we got the request */ struct vmbus_channel *recv_channel; /* chn we got the request */
u64 recv_req_id; /* request ID. */ u64 recv_req_id; /* request ID. */
struct hv_vss_msg *msg; /* current message */ struct hv_vss_msg *msg; /* current message */
void *vss_context; /* for the channel callback */
} vss_transaction; } vss_transaction;
static void vss_respond_to_host(int error); static void vss_respond_to_host(int error);
static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL }; /*
static const char vss_name[] = "vss_kernel_module"; * This state maintains the version number registered by the daemon.
*/
static int dm_reg_value;
static const char vss_devname[] = "vmbus/hv_vss";
static __u8 *recv_buffer; static __u8 *recv_buffer;
static struct hvutil_transport *hvt;
static void vss_send_op(struct work_struct *dummy); static void vss_send_op(struct work_struct *dummy);
static void vss_timeout_func(struct work_struct *dummy); static void vss_timeout_func(struct work_struct *dummy);
...@@ -71,25 +85,69 @@ static void vss_timeout_func(struct work_struct *dummy) ...@@ -71,25 +85,69 @@ static void vss_timeout_func(struct work_struct *dummy)
*/ */
pr_warn("VSS: timeout waiting for daemon to reply\n"); pr_warn("VSS: timeout waiting for daemon to reply\n");
vss_respond_to_host(HV_E_FAIL); vss_respond_to_host(HV_E_FAIL);
/* Transaction is finished, reset the state. */
if (vss_transaction.state > HVUTIL_READY)
vss_transaction.state = HVUTIL_READY;
hv_poll_channel(vss_transaction.vss_context,
hv_vss_onchannelcallback);
} }
static void static int vss_handle_handshake(struct hv_vss_msg *vss_msg)
vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
{ {
struct hv_vss_msg *vss_msg; u32 our_ver = VSS_OP_REGISTER1;
vss_msg = (struct hv_vss_msg *)msg->data; switch (vss_msg->vss_hdr.operation) {
case VSS_OP_REGISTER:
/* Daemon doesn't expect us to reply */
dm_reg_value = VSS_OP_REGISTER;
break;
case VSS_OP_REGISTER1:
/* Daemon expects us to reply with our own version*/
if (hvutil_transport_send(hvt, &our_ver, sizeof(our_ver)))
return -EFAULT;
dm_reg_value = VSS_OP_REGISTER1;
break;
default:
return -EINVAL;
}
vss_transaction.state = HVUTIL_READY;
pr_debug("VSS: userspace daemon ver. %d registered\n", dm_reg_value);
return 0;
}
if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { static int vss_on_msg(void *msg, int len)
pr_info("VSS daemon registered\n"); {
vss_transaction.active = false; struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;
if (vss_transaction.recv_channel != NULL)
hv_vss_onchannelcallback(vss_transaction.recv_channel);
return;
} if (len != sizeof(*vss_msg))
if (cancel_delayed_work_sync(&vss_timeout_work)) return -EINVAL;
if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER ||
vss_msg->vss_hdr.operation == VSS_OP_REGISTER1) {
/*
* Don't process registration messages if we're in the middle
* of a transaction processing.
*/
if (vss_transaction.state > HVUTIL_READY)
return -EINVAL;
return vss_handle_handshake(vss_msg);
} else if (vss_transaction.state == HVUTIL_USERSPACE_REQ) {
vss_transaction.state = HVUTIL_USERSPACE_RECV;
if (cancel_delayed_work_sync(&vss_timeout_work)) {
vss_respond_to_host(vss_msg->error); vss_respond_to_host(vss_msg->error);
/* Transaction is finished, reset the state. */
vss_transaction.state = HVUTIL_READY;
hv_poll_channel(vss_transaction.vss_context,
hv_vss_onchannelcallback);
}
} else {
/* This is a spurious call! */
pr_warn("VSS: Transaction not active\n");
return -EINVAL;
}
return 0;
} }
...@@ -97,28 +155,29 @@ static void vss_send_op(struct work_struct *dummy) ...@@ -97,28 +155,29 @@ static void vss_send_op(struct work_struct *dummy)
{ {
int op = vss_transaction.msg->vss_hdr.operation; int op = vss_transaction.msg->vss_hdr.operation;
int rc; int rc;
struct cn_msg *msg;
struct hv_vss_msg *vss_msg; struct hv_vss_msg *vss_msg;
msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC); /* The transaction state is wrong. */
if (!msg) if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
return; return;
vss_msg = (struct hv_vss_msg *)msg->data; vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
if (!vss_msg)
msg->id.idx = CN_VSS_IDX; return;
msg->id.val = CN_VSS_VAL;
vss_msg->vss_hdr.operation = op; vss_msg->vss_hdr.operation = op;
msg->len = sizeof(struct hv_vss_msg);
rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC); vss_transaction.state = HVUTIL_USERSPACE_REQ;
rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg));
if (rc) { if (rc) {
pr_warn("VSS: failed to communicate to the daemon: %d\n", rc); pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
if (cancel_delayed_work_sync(&vss_timeout_work)) if (cancel_delayed_work_sync(&vss_timeout_work)) {
vss_respond_to_host(HV_E_FAIL); vss_respond_to_host(HV_E_FAIL);
vss_transaction.state = HVUTIL_READY;
}
} }
kfree(msg);
kfree(vss_msg);
return; return;
} }
...@@ -135,17 +194,6 @@ vss_respond_to_host(int error) ...@@ -135,17 +194,6 @@ vss_respond_to_host(int error)
struct vmbus_channel *channel; struct vmbus_channel *channel;
u64 req_id; u64 req_id;
/*
* If a transaction is not active; log and return.
*/
if (!vss_transaction.active) {
/*
* This is a spurious call!
*/
pr_warn("VSS: Transaction not active\n");
return;
}
/* /*
* Copy the global state for completing the transaction. Note that * Copy the global state for completing the transaction. Note that
* only one transaction can be active at a time. * only one transaction can be active at a time.
...@@ -154,7 +202,6 @@ vss_respond_to_host(int error) ...@@ -154,7 +202,6 @@ vss_respond_to_host(int error)
buf_len = vss_transaction.recv_len; buf_len = vss_transaction.recv_len;
channel = vss_transaction.recv_channel; channel = vss_transaction.recv_channel;
req_id = vss_transaction.recv_req_id; req_id = vss_transaction.recv_req_id;
vss_transaction.active = false;
icmsghdrp = (struct icmsg_hdr *) icmsghdrp = (struct icmsg_hdr *)
&recv_buffer[sizeof(struct vmbuspipe_hdr)]; &recv_buffer[sizeof(struct vmbuspipe_hdr)];
...@@ -191,14 +238,15 @@ void hv_vss_onchannelcallback(void *context) ...@@ -191,14 +238,15 @@ void hv_vss_onchannelcallback(void *context)
struct icmsg_hdr *icmsghdrp; struct icmsg_hdr *icmsghdrp;
struct icmsg_negotiate *negop = NULL; struct icmsg_negotiate *negop = NULL;
if (vss_transaction.active) { if (vss_transaction.state > HVUTIL_READY) {
/* /*
* We will defer processing this callback once * We will defer processing this callback once
* the current transaction is complete. * the current transaction is complete.
*/ */
vss_transaction.recv_channel = channel; vss_transaction.vss_context = context;
return; return;
} }
vss_transaction.vss_context = NULL;
vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen, vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
&requestid); &requestid);
...@@ -224,7 +272,6 @@ void hv_vss_onchannelcallback(void *context) ...@@ -224,7 +272,6 @@ void hv_vss_onchannelcallback(void *context)
vss_transaction.recv_len = recvlen; vss_transaction.recv_len = recvlen;
vss_transaction.recv_channel = channel; vss_transaction.recv_channel = channel;
vss_transaction.recv_req_id = requestid; vss_transaction.recv_req_id = requestid;
vss_transaction.active = true;
vss_transaction.msg = (struct hv_vss_msg *)vss_msg; vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
switch (vss_msg->vss_hdr.operation) { switch (vss_msg->vss_hdr.operation) {
...@@ -241,6 +288,12 @@ void hv_vss_onchannelcallback(void *context) ...@@ -241,6 +288,12 @@ void hv_vss_onchannelcallback(void *context)
*/ */
case VSS_OP_FREEZE: case VSS_OP_FREEZE:
case VSS_OP_THAW: case VSS_OP_THAW:
if (vss_transaction.state < HVUTIL_READY) {
/* Userspace is not registered yet */
vss_respond_to_host(HV_E_FAIL);
return;
}
vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
schedule_work(&vss_send_op_work); schedule_work(&vss_send_op_work);
schedule_delayed_work(&vss_timeout_work, schedule_delayed_work(&vss_timeout_work,
VSS_USERSPACE_TIMEOUT); VSS_USERSPACE_TIMEOUT);
...@@ -275,14 +328,16 @@ void hv_vss_onchannelcallback(void *context) ...@@ -275,14 +328,16 @@ void hv_vss_onchannelcallback(void *context)
} }
static void vss_on_reset(void)
{
if (cancel_delayed_work_sync(&vss_timeout_work))
vss_respond_to_host(HV_E_FAIL);
vss_transaction.state = HVUTIL_DEVICE_INIT;
}
int int
hv_vss_init(struct hv_util_service *srv) hv_vss_init(struct hv_util_service *srv)
{ {
int err;
err = cn_add_callback(&vss_id, vss_name, vss_cn_callback);
if (err)
return err;
recv_buffer = srv->recv_buffer; recv_buffer = srv->recv_buffer;
/* /*
...@@ -291,13 +346,20 @@ hv_vss_init(struct hv_util_service *srv) ...@@ -291,13 +346,20 @@ hv_vss_init(struct hv_util_service *srv)
* Defer processing channel callbacks until the daemon * Defer processing channel callbacks until the daemon
* has registered. * has registered.
*/ */
vss_transaction.active = true; vss_transaction.state = HVUTIL_DEVICE_INIT;
hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
vss_on_msg, vss_on_reset);
if (!hvt)
return -EFAULT;
return 0; return 0;
} }
void hv_vss_deinit(void) void hv_vss_deinit(void)
{ {
cn_del_callback(&vss_id); vss_transaction.state = HVUTIL_DEVICE_DYING;
cancel_delayed_work_sync(&vss_timeout_work); cancel_delayed_work_sync(&vss_timeout_work);
cancel_work_sync(&vss_send_op_work); cancel_work_sync(&vss_send_op_work);
hvutil_transport_destroy(hvt);
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -371,6 +371,17 @@ config SENSORS_DS1621 ...@@ -371,6 +371,17 @@ config SENSORS_DS1621
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called ds1621. will be called ds1621.
config SENSORS_DELL_SMM
tristate "Dell laptop SMM BIOS hwmon driver"
depends on X86
help
This hwmon driver adds support for reporting temperature of different
sensors and controls the fans on Dell laptops via System Management
Mode provided by Dell BIOS.
When option I8K is also enabled this driver provides legacy /proc/i8k
userspace interface for i8kutils package.
config SENSORS_DA9052_ADC config SENSORS_DA9052_ADC
tristate "Dialog DA9052/DA9053 ADC" tristate "Dialog DA9052/DA9053 ADC"
depends on PMIC_DA9052 depends on PMIC_DA9052
......
...@@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o ...@@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o
obj-$(CONFIG_SENSORS_DELL_SMM) += dell-smm-hwmon.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
obj-$(CONFIG_SENSORS_DS620) += ds620.o obj-$(CONFIG_SENSORS_DS620) += ds620.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
......
This diff is collapsed.
...@@ -9,3 +9,5 @@ obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o ...@@ -9,3 +9,5 @@ obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \ obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
coresight-replicator.o coresight-replicator.o
obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o
obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o
obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o
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.
...@@ -520,7 +520,6 @@ source "drivers/misc/eeprom/Kconfig" ...@@ -520,7 +520,6 @@ source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig" source "drivers/misc/cb710/Kconfig"
source "drivers/misc/ti-st/Kconfig" source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/altera-stapl/Kconfig"
source "drivers/misc/mei/Kconfig" source "drivers/misc/mei/Kconfig"
source "drivers/misc/vmw_vmci/Kconfig" source "drivers/misc/vmw_vmci/Kconfig"
......
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.
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