Commit bc4e1183 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mfd-next-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Drivers:
   - Add support for RAVE Supervisory Processor

  Moved drivers:
   - Move Realtek Card Reader Driver to Misc

  New Device Support:
   - Add support for Pinctrl to axp20x

  New Functionality:
   - Add resume support to atmel-flexcom

  Fix-ups:
   - Split MFD (mfd) and userspace handlers (platform) in cros_ec
   - Fix trivial (whitespace, spelling) issue(s) in pcf50633-core
   - Clean-up error handling in ab8500-debugfs
   - General tidying up in tmio_core
   - Kconfig fix-ups for qcom-pm8xxx
   - Licensing changes (SPDX) to stm32-lptimer, stm32-timers
   - Device Tree fixups in mc13xxx
   - Simplify/remove unused code in cros_ec_spi, axp20x, ti_am335x_tscadc,
     kempld-core, intel_soc_pmic_core.c, ab8500-debugfs"

* tag 'mfd-next-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (32 commits)
  mfd: lpc_ich: Do not touch SPI-NOR write protection bit on Apollo Lake
  mfd: axp20x: Mark axp288 CHRG_BAK_CTRL register volatile
  mfd: ab8500: Introduce DEFINE_SHOW_ATTRIBUTE() macro
  atmel_flexcom: Support resuming after a chip reset
  mfd: Remove duplicate includes
  dt-bindings: mfd: mc13xxx: Add the unit address to sysled
  mfd: stm32: Adopt SPDX identifier
  mfd: axp20x: Add pinctrl cell for AXP813
  mfd: pm8xxx: Make elegible for COMPILE_TEST
  mfd: kempld-core: Use resource_size function on resource object
  mfd: tmio: Move register macros to tmio_core.c
  mfd: cros ec: spi: Simplify delay handling between SPI messages
  mfd: palmas: Assign the right powerhold mask for tps65917
  mfd: ab8500-debugfs: Use common error handling code in ab8500_print_modem_registers()
  mfd: ti_am335x_tscadc: Remove redundant assignment to node
  mfd: pcf50633: Fix spelling mistake: 'Falied' -> 'Failed'
  dt-bindings: watchdog: Add bindings for RAVE SP watchdog driver
  watchdog: Add RAVE SP watchdog driver
  mfd: Add driver for RAVE Supervisory Processor
  serdev: Introduce devm_serdev_device_open()
  ...
parents 1c7385db 0f89ffef
...@@ -130,7 +130,7 @@ ecspi@70010000 { /* ECSPI1 */ ...@@ -130,7 +130,7 @@ ecspi@70010000 { /* ECSPI1 */
#size-cells = <0>; #size-cells = <0>;
led-control = <0x000 0x000 0x0e0 0x000>; led-control = <0x000 0x000 0x0e0 0x000>;
sysled { sysled@3 {
reg = <3>; reg = <3>;
label = "system:red:live"; label = "system:red:live";
linux,default-trigger = "heartbeat"; linux,default-trigger = "heartbeat";
......
Zodiac Inflight Innovations RAVE Supervisory Processor Watchdog Bindings
RAVE SP watchdog device is a "MFD cell" device corresponding to
watchdog functionality of RAVE Supervisory Processor. It is expected
that its Device Tree node is specified as a child of the node
corresponding to the parent RAVE SP device (as documented in
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
Required properties:
- compatible: Depending on wire protocol implemented by RAVE SP
firmware, should be one of:
- "zii,rave-sp-watchdog"
- "zii,rave-sp-watchdog-legacy"
Optional properties:
- wdt-timeout: Two byte nvmem cell specified as per
Documentation/devicetree/bindings/nvmem/nvmem.txt
Example:
rave-sp {
compatible = "zii,rave-sp-rdu1";
current-speed = <38400>;
eeprom {
wdt_timeout: wdt-timeout@8E {
reg = <0x8E 2>;
};
};
watchdog {
compatible = "zii,rave-sp-watchdog";
nvmem-cells = <&wdt_timeout>;
nvmem-cell-names = "wdt-timeout";
};
}
...@@ -384,6 +384,9 @@ RESET ...@@ -384,6 +384,9 @@ RESET
devm_reset_control_get() devm_reset_control_get()
devm_reset_controller_register() devm_reset_controller_register()
SERDEV
devm_serdev_device_open()
SLAVE DMA ENGINE SLAVE DMA ENGINE
devm_acpi_dma_controller_register() devm_acpi_dma_controller_register()
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
#include <linux/notifier.h> #include <linux/notifier.h>
#include <linux/extcon-provider.h> #include <linux/extcon-provider.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/mfd/axp20x.h> #include <linux/mfd/axp20x.h>
/* Power source status register */ /* Power source status register */
...@@ -79,11 +77,6 @@ enum axp288_extcon_reg { ...@@ -79,11 +77,6 @@ enum axp288_extcon_reg {
AXP288_BC_DET_STAT_REG = 0x2f, AXP288_BC_DET_STAT_REG = 0x2f,
}; };
enum axp288_mux_select {
EXTCON_GPIO_MUX_SEL_PMIC = 0,
EXTCON_GPIO_MUX_SEL_SOC,
};
enum axp288_extcon_irq { enum axp288_extcon_irq {
VBUS_FALLING_IRQ = 0, VBUS_FALLING_IRQ = 0,
VBUS_RISING_IRQ, VBUS_RISING_IRQ,
...@@ -104,10 +97,8 @@ struct axp288_extcon_info { ...@@ -104,10 +97,8 @@ struct axp288_extcon_info {
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
struct regmap_irq_chip_data *regmap_irqc; struct regmap_irq_chip_data *regmap_irqc;
struct gpio_desc *gpio_mux_cntl;
int irq[EXTCON_IRQ_END]; int irq[EXTCON_IRQ_END];
struct extcon_dev *edev; struct extcon_dev *edev;
struct notifier_block extcon_nb;
unsigned int previous_cable; unsigned int previous_cable;
}; };
...@@ -197,15 +188,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) ...@@ -197,15 +188,6 @@ static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info)
} }
no_vbus: no_vbus:
/*
* If VBUS is absent Connect D+/D- lines to PMIC for BC
* detection. Else connect them to SOC for USB communication.
*/
if (info->gpio_mux_cntl)
gpiod_set_value(info->gpio_mux_cntl,
vbus_attach ? EXTCON_GPIO_MUX_SEL_SOC
: EXTCON_GPIO_MUX_SEL_PMIC);
extcon_set_state_sync(info->edev, info->previous_cable, false); extcon_set_state_sync(info->edev, info->previous_cable, false);
if (info->previous_cable == EXTCON_CHG_USB_SDP) if (info->previous_cable == EXTCON_CHG_USB_SDP)
extcon_set_state_sync(info->edev, EXTCON_USB, false); extcon_set_state_sync(info->edev, EXTCON_USB, false);
...@@ -253,8 +235,7 @@ static int axp288_extcon_probe(struct platform_device *pdev) ...@@ -253,8 +235,7 @@ static int axp288_extcon_probe(struct platform_device *pdev)
{ {
struct axp288_extcon_info *info; struct axp288_extcon_info *info;
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
struct axp288_extcon_pdata *pdata = pdev->dev.platform_data; int ret, i, pirq;
int ret, i, pirq, gpio;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
...@@ -264,8 +245,6 @@ static int axp288_extcon_probe(struct platform_device *pdev) ...@@ -264,8 +245,6 @@ static int axp288_extcon_probe(struct platform_device *pdev)
info->regmap = axp20x->regmap; info->regmap = axp20x->regmap;
info->regmap_irqc = axp20x->regmap_irqc; info->regmap_irqc = axp20x->regmap_irqc;
info->previous_cable = EXTCON_NONE; info->previous_cable = EXTCON_NONE;
if (pdata)
info->gpio_mux_cntl = pdata->gpio_mux_cntl;
platform_set_drvdata(pdev, info); platform_set_drvdata(pdev, info);
...@@ -286,21 +265,11 @@ static int axp288_extcon_probe(struct platform_device *pdev) ...@@ -286,21 +265,11 @@ static int axp288_extcon_probe(struct platform_device *pdev)
return ret; return ret;
} }
/* Set up gpio control for USB Mux */
if (info->gpio_mux_cntl) {
gpio = desc_to_gpio(info->gpio_mux_cntl);
ret = devm_gpio_request(&pdev->dev, gpio, "USB_MUX");
if (ret < 0) {
dev_err(&pdev->dev,
"failed to request the gpio=%d\n", gpio);
return ret;
}
gpiod_direction_output(info->gpio_mux_cntl,
EXTCON_GPIO_MUX_SEL_PMIC);
}
for (i = 0; i < EXTCON_IRQ_END; i++) { for (i = 0; i < EXTCON_IRQ_END; i++) {
pirq = platform_get_irq(pdev, i); pirq = platform_get_irq(pdev, i);
if (pirq < 0)
return pirq;
info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq); info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
if (info->irq[i] < 0) { if (info->irq[i] < 0) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
......
...@@ -34,16 +34,26 @@ struct cros_ec_extcon_info { ...@@ -34,16 +34,26 @@ struct cros_ec_extcon_info {
struct notifier_block notifier; struct notifier_block notifier;
unsigned int dr; /* data role */
bool pr; /* power role (true if VBUS enabled) */
bool dp; /* DisplayPort enabled */ bool dp; /* DisplayPort enabled */
bool mux; /* SuperSpeed (usb3) enabled */ bool mux; /* SuperSpeed (usb3) enabled */
unsigned int power_type; unsigned int power_type;
}; };
static const unsigned int usb_type_c_cable[] = { static const unsigned int usb_type_c_cable[] = {
EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_DISP_DP, EXTCON_DISP_DP,
EXTCON_NONE, EXTCON_NONE,
}; };
enum usb_data_roles {
DR_NONE,
DR_HOST,
DR_DEVICE,
};
/** /**
* cros_ec_pd_command() - Send a command to the EC. * cros_ec_pd_command() - Send a command to the EC.
* @info: pointer to struct cros_ec_extcon_info * @info: pointer to struct cros_ec_extcon_info
...@@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info, ...@@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info,
pd_control.port = info->port_id; pd_control.port = info->port_id;
pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE; pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE;
pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE; pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE;
pd_control.swap = USB_PD_CTRL_SWAP_NONE;
ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1, ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1,
&pd_control, sizeof(pd_control), &pd_control, sizeof(pd_control),
&resp, sizeof(resp)); &resp, sizeof(resp));
...@@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info) ...@@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info)
return resp.num_ports; return resp.num_ports;
} }
static const char *cros_ec_usb_role_string(unsigned int role)
{
return role == DR_NONE ? "DISCONNECTED" :
(role == DR_HOST ? "DFP" : "UFP");
}
static const char *cros_ec_usb_power_type_string(unsigned int type)
{
switch (type) {
case USB_CHG_TYPE_NONE:
return "USB_CHG_TYPE_NONE";
case USB_CHG_TYPE_PD:
return "USB_CHG_TYPE_PD";
case USB_CHG_TYPE_PROPRIETARY:
return "USB_CHG_TYPE_PROPRIETARY";
case USB_CHG_TYPE_C:
return "USB_CHG_TYPE_C";
case USB_CHG_TYPE_BC12_DCP:
return "USB_CHG_TYPE_BC12_DCP";
case USB_CHG_TYPE_BC12_CDP:
return "USB_CHG_TYPE_BC12_CDP";
case USB_CHG_TYPE_BC12_SDP:
return "USB_CHG_TYPE_BC12_SDP";
case USB_CHG_TYPE_OTHER:
return "USB_CHG_TYPE_OTHER";
case USB_CHG_TYPE_VBUS:
return "USB_CHG_TYPE_VBUS";
case USB_CHG_TYPE_UNKNOWN:
return "USB_CHG_TYPE_UNKNOWN";
default:
return "USB_CHG_TYPE_UNKNOWN";
}
}
static bool cros_ec_usb_power_type_is_wall_wart(unsigned int type,
unsigned int role)
{
switch (type) {
/* FIXME : Guppy, Donnettes, and other chargers will be miscategorized
* because they identify with USB_CHG_TYPE_C, but we can't return true
* here from that code because that breaks Suzy-Q and other kinds of
* USB Type-C cables and peripherals.
*/
case USB_CHG_TYPE_PROPRIETARY:
case USB_CHG_TYPE_BC12_DCP:
return true;
case USB_CHG_TYPE_PD:
case USB_CHG_TYPE_C:
case USB_CHG_TYPE_BC12_CDP:
case USB_CHG_TYPE_BC12_SDP:
case USB_CHG_TYPE_OTHER:
case USB_CHG_TYPE_VBUS:
case USB_CHG_TYPE_UNKNOWN:
case USB_CHG_TYPE_NONE:
default:
return false;
}
}
static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
bool force) bool force)
{ {
struct device *dev = info->dev; struct device *dev = info->dev;
int role, power_type; int role, power_type;
unsigned int dr = DR_NONE;
bool pr = false;
bool polarity = false; bool polarity = false;
bool dp = false; bool dp = false;
bool mux = false; bool mux = false;
...@@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, ...@@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
dev_err(dev, "failed getting role err = %d\n", role); dev_err(dev, "failed getting role err = %d\n", role);
return role; return role;
} }
dev_dbg(dev, "disconnected\n");
} else { } else {
int pd_mux_state; int pd_mux_state;
dr = (role & PD_CTRL_RESP_ROLE_DATA) ? DR_HOST : DR_DEVICE;
pr = (role & PD_CTRL_RESP_ROLE_POWER);
pd_mux_state = cros_ec_usb_get_pd_mux_state(info); pd_mux_state = cros_ec_usb_get_pd_mux_state(info);
if (pd_mux_state < 0) if (pd_mux_state < 0)
pd_mux_state = USB_PD_MUX_USB_ENABLED; pd_mux_state = USB_PD_MUX_USB_ENABLED;
...@@ -216,20 +291,62 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, ...@@ -216,20 +291,62 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
dp = pd_mux_state & USB_PD_MUX_DP_ENABLED; dp = pd_mux_state & USB_PD_MUX_DP_ENABLED;
mux = pd_mux_state & USB_PD_MUX_USB_ENABLED; mux = pd_mux_state & USB_PD_MUX_USB_ENABLED;
hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ; hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ;
}
if (force || info->dp != dp || info->mux != mux || dev_dbg(dev,
info->power_type != power_type) { "connected role 0x%x pwr type %d dr %d pr %d pol %d mux %d dp %d hpd %d\n",
role, power_type, dr, pr, polarity, mux, dp, hpd);
}
/*
* When there is no USB host (e.g. USB PD charger),
* we are not really a UFP for the AP.
*/
if (dr == DR_DEVICE &&
cros_ec_usb_power_type_is_wall_wart(power_type, role))
dr = DR_NONE;
if (force || info->dr != dr || info->pr != pr || info->dp != dp ||
info->mux != mux || info->power_type != power_type) {
bool host_connected = false, device_connected = false;
dev_dbg(dev, "Type/Role switch! type = %s role = %s\n",
cros_ec_usb_power_type_string(power_type),
cros_ec_usb_role_string(dr));
info->dr = dr;
info->pr = pr;
info->dp = dp; info->dp = dp;
info->mux = mux; info->mux = mux;
info->power_type = power_type; info->power_type = power_type;
extcon_set_state(info->edev, EXTCON_DISP_DP, dp); if (dr == DR_DEVICE)
device_connected = true;
else if (dr == DR_HOST)
host_connected = true;
extcon_set_state(info->edev, EXTCON_USB, device_connected);
extcon_set_state(info->edev, EXTCON_USB_HOST, host_connected);
extcon_set_state(info->edev, EXTCON_DISP_DP, dp);
extcon_set_property(info->edev, EXTCON_USB,
EXTCON_PROP_USB_VBUS,
(union extcon_property_value)(int)pr);
extcon_set_property(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_VBUS,
(union extcon_property_value)(int)pr);
extcon_set_property(info->edev, EXTCON_USB,
EXTCON_PROP_USB_TYPEC_POLARITY,
(union extcon_property_value)(int)polarity);
extcon_set_property(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_TYPEC_POLARITY,
(union extcon_property_value)(int)polarity);
extcon_set_property(info->edev, EXTCON_DISP_DP, extcon_set_property(info->edev, EXTCON_DISP_DP,
EXTCON_PROP_USB_TYPEC_POLARITY, EXTCON_PROP_USB_TYPEC_POLARITY,
(union extcon_property_value)(int)polarity); (union extcon_property_value)(int)polarity);
extcon_set_property(info->edev, EXTCON_USB,
EXTCON_PROP_USB_SS,
(union extcon_property_value)(int)mux);
extcon_set_property(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_SS,
(union extcon_property_value)(int)mux);
extcon_set_property(info->edev, EXTCON_DISP_DP, extcon_set_property(info->edev, EXTCON_DISP_DP,
EXTCON_PROP_USB_SS, EXTCON_PROP_USB_SS,
(union extcon_property_value)(int)mux); (union extcon_property_value)(int)mux);
...@@ -237,6 +354,8 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, ...@@ -237,6 +354,8 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info,
EXTCON_PROP_DISP_HPD, EXTCON_PROP_DISP_HPD,
(union extcon_property_value)(int)hpd); (union extcon_property_value)(int)hpd);
extcon_sync(info->edev, EXTCON_USB);
extcon_sync(info->edev, EXTCON_USB_HOST);
extcon_sync(info->edev, EXTCON_DISP_DP); extcon_sync(info->edev, EXTCON_DISP_DP);
} else if (hpd) { } else if (hpd) {
...@@ -322,13 +441,28 @@ static int extcon_cros_ec_probe(struct platform_device *pdev) ...@@ -322,13 +441,28 @@ static int extcon_cros_ec_probe(struct platform_device *pdev)
return ret; return ret;
} }
extcon_set_property_capability(info->edev, EXTCON_USB,
EXTCON_PROP_USB_VBUS);
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_VBUS);
extcon_set_property_capability(info->edev, EXTCON_USB,
EXTCON_PROP_USB_TYPEC_POLARITY);
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_TYPEC_POLARITY);
extcon_set_property_capability(info->edev, EXTCON_DISP_DP, extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
EXTCON_PROP_USB_TYPEC_POLARITY); EXTCON_PROP_USB_TYPEC_POLARITY);
extcon_set_property_capability(info->edev, EXTCON_USB,
EXTCON_PROP_USB_SS);
extcon_set_property_capability(info->edev, EXTCON_USB_HOST,
EXTCON_PROP_USB_SS);
extcon_set_property_capability(info->edev, EXTCON_DISP_DP, extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
EXTCON_PROP_USB_SS); EXTCON_PROP_USB_SS);
extcon_set_property_capability(info->edev, EXTCON_DISP_DP, extcon_set_property_capability(info->edev, EXTCON_DISP_DP,
EXTCON_PROP_DISP_HPD); EXTCON_PROP_DISP_HPD);
info->dr = DR_NONE;
info->pr = false;
platform_set_drvdata(pdev, info); platform_set_drvdata(pdev, info);
/* Get PD events from the EC */ /* Get PD events from the EC */
......
...@@ -106,7 +106,7 @@ static int pm8058_led_probe(struct platform_device *pdev) ...@@ -106,7 +106,7 @@ static int pm8058_led_probe(struct platform_device *pdev)
if (!led) if (!led)
return -ENOMEM; return -ENOMEM;
led->ledtype = (u32)of_device_get_match_data(&pdev->dev); led->ledtype = (u32)(unsigned long)of_device_get_match_data(&pdev->dev);
map = dev_get_regmap(pdev->dev.parent, NULL); map = dev_get_regmap(pdev->dev.parent, NULL);
if (!map) { if (!map) {
......
...@@ -45,7 +45,7 @@ config MEMSTICK_R592 ...@@ -45,7 +45,7 @@ config MEMSTICK_R592
config MEMSTICK_REALTEK_PCI config MEMSTICK_REALTEK_PCI
tristate "Realtek PCI-E Memstick Card Interface Driver" tristate "Realtek PCI-E Memstick Card Interface Driver"
depends on MFD_RTSX_PCI depends on MISC_RTSX_PCI
help help
Say Y here to include driver code to support Memstick card interface Say Y here to include driver code to support Memstick card interface
of Realtek PCI-E card reader of Realtek PCI-E card reader
...@@ -55,7 +55,7 @@ config MEMSTICK_REALTEK_PCI ...@@ -55,7 +55,7 @@ config MEMSTICK_REALTEK_PCI
config MEMSTICK_REALTEK_USB config MEMSTICK_REALTEK_USB
tristate "Realtek USB Memstick Card Interface Driver" tristate "Realtek USB Memstick Card Interface Driver"
depends on MFD_RTSX_USB depends on MISC_RTSX_USB
help help
Say Y here to include driver code to support Memstick card interface Say Y here to include driver code to support Memstick card interface
of Realtek RTS5129/39 series USB card reader of Realtek RTS5129/39 series USB card reader
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/memstick.h> #include <linux/memstick.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
struct realtek_pci_ms { struct realtek_pci_ms {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/memstick.h> #include <linux/memstick.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/mfd/rtsx_usb.h> #include <linux/rtsx_usb.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/sched.h> #include <linux/sched.h>
......
...@@ -222,6 +222,16 @@ config MFD_CROS_EC_SPI ...@@ -222,6 +222,16 @@ config MFD_CROS_EC_SPI
response time cannot be guaranteed, we support ignoring response time cannot be guaranteed, we support ignoring
'pre-amble' bytes before the response actually starts. 'pre-amble' bytes before the response actually starts.
config MFD_CROS_EC_CHARDEV
tristate "Chrome OS Embedded Controller userspace device interface"
depends on MFD_CROS_EC
select CROS_EC_CTL
---help---
This driver adds support to talk with the ChromeOS EC from userspace.
If you have a supported Chromebook, choose Y or M here.
The module will be called cros_ec_dev.
config MFD_ASIC3 config MFD_ASIC3
bool "Compaq ASIC3" bool "Compaq ASIC3"
depends on GPIOLIB && ARM depends on GPIOLIB && ARM
...@@ -877,7 +887,7 @@ config UCB1400_CORE ...@@ -877,7 +887,7 @@ config UCB1400_CORE
config MFD_PM8XXX config MFD_PM8XXX
tristate "Qualcomm PM8xxx PMIC chips driver" tristate "Qualcomm PM8xxx PMIC chips driver"
depends on (ARM || HEXAGON) depends on (ARM || HEXAGON || COMPILE_TEST)
select IRQ_DOMAIN select IRQ_DOMAIN
select MFD_CORE select MFD_CORE
select REGMAP select REGMAP
...@@ -929,17 +939,6 @@ config MFD_RDC321X ...@@ -929,17 +939,6 @@ config MFD_RDC321X
southbridge which provides access to GPIOs and Watchdog using the southbridge which provides access to GPIOs and Watchdog using the
southbridge PCI device configuration space. southbridge PCI device configuration space.
config MFD_RTSX_PCI
tristate "Realtek PCI-E card reader"
depends on PCI
select MFD_CORE
help
This supports for Realtek PCI-Express card reader including rts5209,
rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc.
Realtek card reader supports access to many types of memory cards,
such as Memory Stick, Memory Stick Pro, Secure Digital and
MultiMediaCard.
config MFD_RT5033 config MFD_RT5033
tristate "Richtek RT5033 Power Management IC" tristate "Richtek RT5033 Power Management IC"
depends on I2C depends on I2C
...@@ -953,16 +952,6 @@ config MFD_RT5033 ...@@ -953,16 +952,6 @@ config MFD_RT5033
sub-devices like charger, fuel gauge, flash LED, current source, sub-devices like charger, fuel gauge, flash LED, current source,
LDO and Buck. LDO and Buck.
config MFD_RTSX_USB
tristate "Realtek USB card reader"
depends on USB
select MFD_CORE
help
Select this option to get support for Realtek USB 2.0 card readers
including RTS5129, RTS5139, RTS5179 and RTS5170.
Realtek card reader supports access to many types of memory cards,
such as Memory Stick Pro, Secure Digital and MultiMediaCard.
config MFD_RC5T583 config MFD_RC5T583
bool "Ricoh RC5T583 Power Management system device" bool "Ricoh RC5T583 Power Management system device"
depends on I2C=y depends on I2C=y
...@@ -1859,5 +1848,13 @@ config MFD_VEXPRESS_SYSREG ...@@ -1859,5 +1848,13 @@ config MFD_VEXPRESS_SYSREG
System Registers are the platform configuration block System Registers are the platform configuration block
on the ARM Ltd. Versatile Express board. on the ARM Ltd. Versatile Express board.
config RAVE_SP_CORE
tristate "RAVE SP MCU core driver"
depends on SERIAL_DEV_BUS
select CRC_CCITT
help
Select this to get support for the Supervisory Processor
device found on several devices in RAVE line of hardware.
endmenu endmenu
endif endif
...@@ -17,12 +17,9 @@ cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o ...@@ -17,12 +17,9 @@ cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
obj-$(CONFIG_MFD_CROS_EC_CHARDEV) += cros_ec_dev.o
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
...@@ -230,3 +227,5 @@ obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o ...@@ -230,3 +227,5 @@ obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o
obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o
This diff is collapsed.
...@@ -39,34 +39,43 @@ ...@@ -39,34 +39,43 @@
#define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \ #define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \
FLEX_MR_OPMODE_MASK) FLEX_MR_OPMODE_MASK)
struct atmel_flexcom {
void __iomem *base;
u32 opmode;
struct clk *clk;
};
static int atmel_flexcom_probe(struct platform_device *pdev) static int atmel_flexcom_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct clk *clk;
struct resource *res; struct resource *res;
void __iomem *base; struct atmel_flexcom *ddata;
u32 opmode;
int err; int err;
err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode); ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
platform_set_drvdata(pdev, ddata);
err = of_property_read_u32(np, "atmel,flexcom-mode", &ddata->opmode);
if (err) if (err)
return err; return err;
if (opmode < ATMEL_FLEXCOM_MODE_USART || if (ddata->opmode < ATMEL_FLEXCOM_MODE_USART ||
opmode > ATMEL_FLEXCOM_MODE_TWI) ddata->opmode > ATMEL_FLEXCOM_MODE_TWI)
return -EINVAL; return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res); ddata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base)) if (IS_ERR(ddata->base))
return PTR_ERR(base); return PTR_ERR(ddata->base);
clk = devm_clk_get(&pdev->dev, NULL); ddata->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(clk)) if (IS_ERR(ddata->clk))
return PTR_ERR(clk); return PTR_ERR(ddata->clk);
err = clk_prepare_enable(clk); err = clk_prepare_enable(ddata->clk);
if (err) if (err)
return err; return err;
...@@ -76,9 +85,9 @@ static int atmel_flexcom_probe(struct platform_device *pdev) ...@@ -76,9 +85,9 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
* inaccessible and are read as zero. Also the external I/O lines of the * inaccessible and are read as zero. Also the external I/O lines of the
* Flexcom are muxed to reach the selected device. * Flexcom are muxed to reach the selected device.
*/ */
writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR); writel(FLEX_MR_OPMODE(ddata->opmode), ddata->base + FLEX_MR);
clk_disable_unprepare(clk); clk_disable_unprepare(ddata->clk);
return devm_of_platform_populate(&pdev->dev); return devm_of_platform_populate(&pdev->dev);
} }
...@@ -89,10 +98,34 @@ static const struct of_device_id atmel_flexcom_of_match[] = { ...@@ -89,10 +98,34 @@ static const struct of_device_id atmel_flexcom_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match); MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
#ifdef CONFIG_PM_SLEEP
static int atmel_flexcom_resume(struct device *dev)
{
struct atmel_flexcom *ddata = dev_get_drvdata(dev);
int err;
u32 val;
err = clk_prepare_enable(ddata->clk);
if (err)
return err;
val = FLEX_MR_OPMODE(ddata->opmode),
writel(val, ddata->base + FLEX_MR);
clk_disable_unprepare(ddata->clk);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL,
atmel_flexcom_resume);
static struct platform_driver atmel_flexcom_driver = { static struct platform_driver atmel_flexcom_driver = {
.probe = atmel_flexcom_probe, .probe = atmel_flexcom_probe,
.driver = { .driver = {
.name = "atmel_flexcom", .name = "atmel_flexcom",
.pm = &atmel_flexcom_pm_ops,
.of_match_table = atmel_flexcom_of_match, .of_match_table = atmel_flexcom_of_match,
}, },
}; };
......
...@@ -129,6 +129,7 @@ static const struct regmap_range axp288_volatile_ranges[] = { ...@@ -129,6 +129,7 @@ static const struct regmap_range axp288_volatile_ranges[] = {
regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON), regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL), regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT), regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L), regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL), regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE), regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
...@@ -878,6 +879,9 @@ static struct mfd_cell axp813_cells[] = { ...@@ -878,6 +879,9 @@ static struct mfd_cell axp813_cells[] = {
.resources = axp803_pek_resources, .resources = axp803_pek_resources,
}, { }, {
.name = "axp20x-regulator", .name = "axp20x-regulator",
}, {
.name = "axp20x-gpio",
.of_compatible = "x-powers,axp813-gpio",
} }
}; };
......
...@@ -40,13 +40,13 @@ static struct cros_ec_platform pd_p = { ...@@ -40,13 +40,13 @@ static struct cros_ec_platform pd_p = {
}; };
static const struct mfd_cell ec_cell = { static const struct mfd_cell ec_cell = {
.name = "cros-ec-ctl", .name = "cros-ec-dev",
.platform_data = &ec_p, .platform_data = &ec_p,
.pdata_size = sizeof(ec_p), .pdata_size = sizeof(ec_p),
}; };
static const struct mfd_cell ec_pd_cell = { static const struct mfd_cell ec_pd_cell = {
.name = "cros-ec-ctl", .name = "cros-ec-dev",
.platform_data = &pd_p, .platform_data = &pd_p,
.pdata_size = sizeof(pd_p), .pdata_size = sizeof(pd_p),
}; };
......
...@@ -25,9 +25,10 @@ ...@@ -25,9 +25,10 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "cros_ec_debugfs.h"
#include "cros_ec_dev.h" #include "cros_ec_dev.h"
#define DRV_NAME "cros-ec-dev"
/* Device variables */ /* Device variables */
#define CROS_MAX_DEV 128 #define CROS_MAX_DEV 128
static int ec_major; static int ec_major;
...@@ -461,7 +462,7 @@ static int ec_device_remove(struct platform_device *pdev) ...@@ -461,7 +462,7 @@ static int ec_device_remove(struct platform_device *pdev)
} }
static const struct platform_device_id cros_ec_id[] = { static const struct platform_device_id cros_ec_id[] = {
{ "cros-ec-ctl", 0 }, { DRV_NAME, 0 },
{ /* sentinel */ }, { /* sentinel */ },
}; };
MODULE_DEVICE_TABLE(platform, cros_ec_id); MODULE_DEVICE_TABLE(platform, cros_ec_id);
...@@ -493,7 +494,7 @@ static const struct dev_pm_ops cros_ec_dev_pm_ops = { ...@@ -493,7 +494,7 @@ static const struct dev_pm_ops cros_ec_dev_pm_ops = {
static struct platform_driver cros_ec_dev_driver = { static struct platform_driver cros_ec_dev_driver = {
.driver = { .driver = {
.name = "cros-ec-ctl", .name = DRV_NAME,
.pm = &cros_ec_dev_pm_ops, .pm = &cros_ec_dev_pm_ops,
}, },
.probe = ec_device_probe, .probe = ec_device_probe,
...@@ -544,6 +545,7 @@ static void __exit cros_ec_dev_exit(void) ...@@ -544,6 +545,7 @@ static void __exit cros_ec_dev_exit(void)
module_init(cros_ec_dev_init); module_init(cros_ec_dev_init);
module_exit(cros_ec_dev_exit); module_exit(cros_ec_dev_exit);
MODULE_ALIAS("platform:" DRV_NAME);
MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>"); MODULE_AUTHOR("Bill Richardson <wfrichar@chromium.org>");
MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller"); MODULE_DESCRIPTION("Userspace interface to the Chrome OS Embedded Controller");
MODULE_VERSION("1.0"); MODULE_VERSION("1.0");
......
...@@ -72,8 +72,7 @@ ...@@ -72,8 +72,7 @@
* struct cros_ec_spi - information about a SPI-connected EC * struct cros_ec_spi - information about a SPI-connected EC
* *
* @spi: SPI device we are connected to * @spi: SPI device we are connected to
* @last_transfer_ns: time that we last finished a transfer, or 0 if there * @last_transfer_ns: time that we last finished a transfer.
* if no record
* @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that * @start_of_msg_delay: used to set the delay_usecs on the spi_transfer that
* is sent when we want to turn on CS at the start of a transaction. * is sent when we want to turn on CS at the start of a transaction.
* @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that
...@@ -379,18 +378,15 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev, ...@@ -379,18 +378,15 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
u8 sum; u8 sum;
u8 rx_byte; u8 rx_byte;
int ret = 0, final_ret; int ret = 0, final_ret;
unsigned long delay;
len = cros_ec_prepare_tx(ec_dev, ec_msg); len = cros_ec_prepare_tx(ec_dev, ec_msg);
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
/* If it's too soon to do another transaction, wait */ /* If it's too soon to do another transaction, wait */
if (ec_spi->last_transfer_ns) {
unsigned long delay; /* The delay completed so far */
delay = ktime_get_ns() - ec_spi->last_transfer_ns; delay = ktime_get_ns() - ec_spi->last_transfer_ns;
if (delay < EC_SPI_RECOVERY_TIME_NS) if (delay < EC_SPI_RECOVERY_TIME_NS)
ndelay(EC_SPI_RECOVERY_TIME_NS - delay); ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
}
rx_buf = kzalloc(len, GFP_KERNEL); rx_buf = kzalloc(len, GFP_KERNEL);
if (!rx_buf) if (!rx_buf)
...@@ -509,18 +505,15 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, ...@@ -509,18 +505,15 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
u8 rx_byte; u8 rx_byte;
int sum; int sum;
int ret = 0, final_ret; int ret = 0, final_ret;
unsigned long delay;
len = cros_ec_prepare_tx(ec_dev, ec_msg); len = cros_ec_prepare_tx(ec_dev, ec_msg);
dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); dev_dbg(ec_dev->dev, "prepared, len=%d\n", len);
/* If it's too soon to do another transaction, wait */ /* If it's too soon to do another transaction, wait */
if (ec_spi->last_transfer_ns) {
unsigned long delay; /* The delay completed so far */
delay = ktime_get_ns() - ec_spi->last_transfer_ns; delay = ktime_get_ns() - ec_spi->last_transfer_ns;
if (delay < EC_SPI_RECOVERY_TIME_NS) if (delay < EC_SPI_RECOVERY_TIME_NS)
ndelay(EC_SPI_RECOVERY_TIME_NS - delay); ndelay(EC_SPI_RECOVERY_TIME_NS - delay);
}
rx_buf = kzalloc(len, GFP_KERNEL); rx_buf = kzalloc(len, GFP_KERNEL);
if (!rx_buf) if (!rx_buf)
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com> * Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
*/ */
#include <linux/acpi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/i2c.h> #include <linux/i2c.h>
......
...@@ -458,7 +458,7 @@ static int kempld_probe(struct platform_device *pdev) ...@@ -458,7 +458,7 @@ static int kempld_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
pld->io_base = devm_ioport_map(dev, ioport->start, pld->io_base = devm_ioport_map(dev, ioport->start,
ioport->end - ioport->start); resource_size(ioport));
if (!pld->io_base) if (!pld->io_base)
return -ENOMEM; return -ENOMEM;
......
...@@ -1143,11 +1143,6 @@ static int lpc_ich_init_spi(struct pci_dev *dev) ...@@ -1143,11 +1143,6 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
res->end = res->start + SPIBASE_APL_SZ - 1; res->end = res->start + SPIBASE_APL_SZ - 1;
pci_bus_read_config_dword(bus, spi, BCR, &bcr); pci_bus_read_config_dword(bus, spi, BCR, &bcr);
if (!(bcr & BCR_WPD)) {
bcr |= BCR_WPD;
pci_bus_write_config_dword(bus, spi, BCR, bcr);
pci_bus_read_config_dword(bus, spi, BCR, &bcr);
}
info->writeable = !!(bcr & BCR_WPD); info->writeable = !!(bcr & BCR_WPD);
} }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/max77693-common.h> #include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h> #include <linux/mfd/max77843-private.h>
......
...@@ -430,6 +430,7 @@ static void palmas_power_off(void) ...@@ -430,6 +430,7 @@ static void palmas_power_off(void)
{ {
unsigned int addr; unsigned int addr;
int ret, slave; int ret, slave;
u8 powerhold_mask;
struct device_node *np = palmas_dev->dev->of_node; struct device_node *np = palmas_dev->dev->of_node;
if (of_property_read_bool(np, "ti,palmas-override-powerhold")) { if (of_property_read_bool(np, "ti,palmas-override-powerhold")) {
...@@ -437,8 +438,15 @@ static void palmas_power_off(void) ...@@ -437,8 +438,15 @@ static void palmas_power_off(void)
PALMAS_PRIMARY_SECONDARY_PAD2); PALMAS_PRIMARY_SECONDARY_PAD2);
slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
if (of_device_is_compatible(np, "ti,tps65917"))
powerhold_mask =
TPS65917_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK;
else
powerhold_mask =
PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK;
ret = regmap_update_bits(palmas_dev->regmap[slave], addr, ret = regmap_update_bits(palmas_dev->regmap[slave], addr,
PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK, 0); powerhold_mask, 0);
if (ret) if (ret)
dev_err(palmas_dev->dev, dev_err(palmas_dev->dev,
"Unable to write PRIMARY_SECONDARY_PAD2 %d\n", "Unable to write PRIMARY_SECONDARY_PAD2 %d\n",
......
...@@ -149,7 +149,7 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name, ...@@ -149,7 +149,7 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
*pdev = platform_device_alloc(name, -1); *pdev = platform_device_alloc(name, -1);
if (!*pdev) { if (!*pdev) {
dev_err(pcf->dev, "Falied to allocate %s\n", name); dev_err(pcf->dev, "Failed to allocate %s\n", name);
return; return;
} }
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/* /*
* STM32 Low-Power Timer parent driver. * STM32 Low-Power Timer parent driver.
*
* Copyright (C) STMicroelectronics 2017 * Copyright (C) STMicroelectronics 2017
*
* Author: Fabrice Gasnier <fabrice.gasnier@st.com> * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
*
* Inspired by Benjamin Gaignard's stm32-timers driver * Inspired by Benjamin Gaignard's stm32-timers driver
*
* License terms: GNU General Public License (GPL), version 2
*/ */
#include <linux/mfd/stm32-lptimer.h> #include <linux/mfd/stm32-lptimer.h>
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* Copyright (C) STMicroelectronics 2016 * Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com> * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/ */
#include <linux/mfd/stm32-timers.h> #include <linux/mfd/stm32-timers.h>
......
...@@ -124,7 +124,7 @@ static int ti_tscadc_probe(struct platform_device *pdev) ...@@ -124,7 +124,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
struct ti_tscadc_dev *tscadc; struct ti_tscadc_dev *tscadc;
struct resource *res; struct resource *res;
struct clk *clk; struct clk *clk;
struct device_node *node = pdev->dev.of_node; struct device_node *node;
struct mfd_cell *cell; struct mfd_cell *cell;
struct property *prop; struct property *prop;
const __be32 *cur; const __be32 *cur;
......
...@@ -9,6 +9,26 @@ ...@@ -9,6 +9,26 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/mfd/tmio.h> #include <linux/mfd/tmio.h>
#define CNF_CMD 0x04
#define CNF_CTL_BASE 0x10
#define CNF_INT_PIN 0x3d
#define CNF_STOP_CLK_CTL 0x40
#define CNF_GCLK_CTL 0x41
#define CNF_SD_CLK_MODE 0x42
#define CNF_PIN_STATUS 0x44
#define CNF_PWR_CTL_1 0x48
#define CNF_PWR_CTL_2 0x49
#define CNF_PWR_CTL_3 0x4a
#define CNF_CARD_DETECT_MODE 0x4c
#define CNF_SD_SLOT 0x50
#define CNF_EXT_GCLK_CTL_1 0xf0
#define CNF_EXT_GCLK_CTL_2 0xf1
#define CNF_EXT_GCLK_CTL_3 0xf9
#define CNF_SD_LED_EN_1 0xfa
#define CNF_SD_LED_EN_2 0xfe
#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base) int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base)
{ {
/* Enable the MMC/SD Control registers */ /* Enable the MMC/SD Control registers */
......
...@@ -496,6 +496,10 @@ config PCI_ENDPOINT_TEST ...@@ -496,6 +496,10 @@ config PCI_ENDPOINT_TEST
Enable this configuration option to enable the host side test driver Enable this configuration option to enable the host side test driver
for PCI Endpoint. for PCI Endpoint.
config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
source "drivers/misc/c2port/Kconfig" source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig" source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig" source "drivers/misc/cb710/Kconfig"
...@@ -508,4 +512,5 @@ source "drivers/misc/mic/Kconfig" ...@@ -508,4 +512,5 @@ source "drivers/misc/mic/Kconfig"
source "drivers/misc/genwqe/Kconfig" source "drivers/misc/genwqe/Kconfig"
source "drivers/misc/echo/Kconfig" source "drivers/misc/echo/Kconfig"
source "drivers/misc/cxl/Kconfig" source "drivers/misc/cxl/Kconfig"
source "drivers/misc/cardreader/Kconfig"
endmenu endmenu
...@@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE) += cxl/ ...@@ -55,6 +55,7 @@ obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o
obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o
obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
obj-$(CONFIG_MISC_RTSX) += cardreader/
lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
......
config MISC_RTSX_PCI
tristate "Realtek PCI-E card reader"
depends on PCI
select MFD_CORE
help
This supports for Realtek PCI-Express card reader including rts5209,
rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260.
Realtek card readers support access to many types of memory cards,
such as Memory Stick, Memory Stick Pro, Secure Digital and
MultiMediaCard.
config MISC_RTSX_USB
tristate "Realtek USB card reader"
depends on USB
select MFD_CORE
help
Select this option to get support for Realtek USB 2.0 card readers
including RTS5129, RTS5139, RTS5179 and RTS5170.
Realtek card reader supports access to many types of memory cards,
such as Memory Stick Pro, Secure Digital and MultiMediaCard.
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o rts5260.o
obj-$(CONFIG_MISC_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_MISC_RTSX_USB) += rtsx_usb.o
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include "rtsx_pcr.h" #include "rtsx_pcr.h"
...@@ -738,4 +738,3 @@ void rts525a_init_params(struct rtsx_pcr *pcr) ...@@ -738,4 +738,3 @@ void rts525a_init_params(struct rtsx_pcr *pcr)
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3; pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
pcr->ops = &rts525a_pcr_ops; pcr->ops = &rts525a_pcr_ops;
} }
This diff is collapsed.
#ifndef __RTS5260_H__
#define __RTS5260_H__
#define RTS5260_DVCC_CTRL 0xFF73
#define RTS5260_DVCC_OCP_EN (0x01 << 7)
#define RTS5260_DVCC_OCP_THD_MASK (0x07 << 4)
#define RTS5260_DVCC_POWERON (0x01 << 3)
#define RTS5260_DVCC_OCP_CL_EN (0x01 << 2)
#define RTS5260_DVIO_CTRL 0xFF75
#define RTS5260_DVIO_OCP_EN (0x01 << 7)
#define RTS5260_DVIO_OCP_THD_MASK (0x07 << 4)
#define RTS5260_DVIO_POWERON (0x01 << 3)
#define RTS5260_DVIO_OCP_CL_EN (0x01 << 2)
#define RTS5260_DV331812_CFG 0xFF71
#define RTS5260_DV331812_OCP_EN (0x01 << 7)
#define RTS5260_DV331812_OCP_THD_MASK (0x07 << 4)
#define RTS5260_DV331812_POWERON (0x01 << 3)
#define RTS5260_DV331812_SEL (0x01 << 2)
#define RTS5260_DV331812_VDD1 (0x01 << 2)
#define RTS5260_DV331812_VDD2 (0x00 << 2)
#define RTS5260_DV331812_OCP_THD_120 (0x00 << 4)
#define RTS5260_DV331812_OCP_THD_140 (0x01 << 4)
#define RTS5260_DV331812_OCP_THD_160 (0x02 << 4)
#define RTS5260_DV331812_OCP_THD_180 (0x03 << 4)
#define RTS5260_DV331812_OCP_THD_210 (0x04 << 4)
#define RTS5260_DV331812_OCP_THD_240 (0x05 << 4)
#define RTS5260_DV331812_OCP_THD_270 (0x06 << 4)
#define RTS5260_DV331812_OCP_THD_300 (0x07 << 4)
#define RTS5260_DVIO_OCP_THD_250 (0x00 << 4)
#define RTS5260_DVIO_OCP_THD_300 (0x01 << 4)
#define RTS5260_DVIO_OCP_THD_350 (0x02 << 4)
#define RTS5260_DVIO_OCP_THD_400 (0x03 << 4)
#define RTS5260_DVIO_OCP_THD_450 (0x04 << 4)
#define RTS5260_DVIO_OCP_THD_500 (0x05 << 4)
#define RTS5260_DVIO_OCP_THD_550 (0x06 << 4)
#define RTS5260_DVIO_OCP_THD_600 (0x07 << 4)
#define RTS5260_DVCC_OCP_THD_550 (0x00 << 4)
#define RTS5260_DVCC_OCP_THD_970 (0x05 << 4)
#endif
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <linux/idr.h> #include <linux/idr.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -62,6 +62,7 @@ static const struct pci_device_id rtsx_pci_ids[] = { ...@@ -62,6 +62,7 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5260), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ 0, } { 0, }
}; };
...@@ -334,6 +335,9 @@ EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register); ...@@ -334,6 +335,9 @@ EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register);
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr) void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
{ {
if (pcr->ops->stop_cmd)
return pcr->ops->stop_cmd(pcr);
rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD); rtsx_pci_writel(pcr, RTSX_HCBCTLR, STOP_CMD);
rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA); rtsx_pci_writel(pcr, RTSX_HDBCTLR, STOP_DMA);
...@@ -826,7 +830,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, ...@@ -826,7 +830,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
return err; return err;
/* Wait SSC clock stable */ /* Wait SSC clock stable */
udelay(10); udelay(SSC_CLOCK_STABLE_WAIT);
err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0); err = rtsx_pci_write_register(pcr, CLK_CTL, CLK_LOW_FREQ, 0);
if (err < 0) if (err < 0)
return err; return err;
...@@ -963,6 +967,20 @@ static void rtsx_pci_card_detect(struct work_struct *work) ...@@ -963,6 +967,20 @@ static void rtsx_pci_card_detect(struct work_struct *work)
pcr->slots[RTSX_MS_CARD].p_dev); pcr->slots[RTSX_MS_CARD].p_dev);
} }
void rtsx_pci_process_ocp(struct rtsx_pcr *pcr)
{
if (pcr->ops->process_ocp)
pcr->ops->process_ocp(pcr);
}
int rtsx_pci_process_ocp_interrupt(struct rtsx_pcr *pcr)
{
if (pcr->option.ocp_en)
rtsx_pci_process_ocp(pcr);
return 0;
}
static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
{ {
struct rtsx_pcr *pcr = dev_id; struct rtsx_pcr *pcr = dev_id;
...@@ -987,6 +1005,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) ...@@ -987,6 +1005,9 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id)
int_reg &= (pcr->bier | 0x7FFFFF); int_reg &= (pcr->bier | 0x7FFFFF);
if (int_reg & SD_OC_INT)
rtsx_pci_process_ocp_interrupt(pcr);
if (int_reg & SD_INT) { if (int_reg & SD_INT) {
if (int_reg & SD_EXIST) { if (int_reg & SD_EXIST) {
pcr->card_inserted |= SD_EXIST; pcr->card_inserted |= SD_EXIST;
...@@ -1119,6 +1140,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state) ...@@ -1119,6 +1140,102 @@ static void rtsx_pci_power_off(struct rtsx_pcr *pcr, u8 pm_state)
} }
#endif #endif
void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr)
{
u8 val = SD_OCP_INT_EN | SD_DETECT_EN;
if (pcr->ops->enable_ocp)
pcr->ops->enable_ocp(pcr);
else
rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val);
}
void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr)
{
u8 mask = SD_OCP_INT_EN | SD_DETECT_EN;
if (pcr->ops->disable_ocp)
pcr->ops->disable_ocp(pcr);
else
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
}
void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
{
if (pcr->ops->init_ocp) {
pcr->ops->init_ocp(pcr);
} else {
struct rtsx_cr_option *option = &(pcr->option);
if (option->ocp_en) {
u8 val = option->sd_400mA_ocp_thd;
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN, 0);
rtsx_pci_write_register(pcr, REG_OCPPARA1,
SD_OCP_TIME_MASK, SD_OCP_TIME_800);
rtsx_pci_write_register(pcr, REG_OCPPARA2,
SD_OCP_THD_MASK, val);
rtsx_pci_write_register(pcr, REG_OCPGLITCH,
SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch);
rtsx_pci_enable_ocp(pcr);
} else {
/* OC power down */
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
OC_POWER_DOWN);
}
}
}
int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val)
{
if (pcr->ops->get_ocpstat)
return pcr->ops->get_ocpstat(pcr, val);
else
return rtsx_pci_read_register(pcr, REG_OCPSTAT, val);
}
void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr)
{
if (pcr->ops->clear_ocpstat) {
pcr->ops->clear_ocpstat(pcr);
} else {
u8 mask = SD_OCP_INT_CLR | SD_OC_CLR;
u8 val = SD_OCP_INT_CLR | SD_OC_CLR;
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val);
rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0);
}
}
int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr)
{
rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
MS_CLK_EN | SD40_CLK_EN, 0);
rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0);
rtsx_pci_card_power_off(pcr, RTSX_SD_CARD);
msleep(50);
rtsx_pci_card_pull_ctl_disable(pcr, RTSX_SD_CARD);
return 0;
}
int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr)
{
rtsx_pci_write_register(pcr, CARD_CLK_EN, SD_CLK_EN |
MS_CLK_EN | SD40_CLK_EN, 0);
rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
rtsx_pci_write_register(pcr, CARD_OE, MS_OUTPUT_EN, 0);
rtsx_pci_card_power_off(pcr, RTSX_MS_CARD);
return 0;
}
static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
{ {
int err; int err;
...@@ -1189,6 +1306,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) ...@@ -1189,6 +1306,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
case PID_5250: case PID_5250:
case PID_524A: case PID_524A:
case PID_525A: case PID_525A:
case PID_5260:
rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1); rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 1, 1);
break; break;
default: default:
...@@ -1265,6 +1383,9 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) ...@@ -1265,6 +1383,9 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
case 0x5286: case 0x5286:
rtl8402_init_params(pcr); rtl8402_init_params(pcr);
break; break;
case 0x5260:
rts5260_init_params(pcr);
break;
} }
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n", pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#ifndef __RTSX_PCR_H #ifndef __RTSX_PCR_H
#define __RTSX_PCR_H #define __RTSX_PCR_H
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#define MIN_DIV_N_PCR 80 #define MIN_DIV_N_PCR 80
#define MAX_DIV_N_PCR 208 #define MAX_DIV_N_PCR 208
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#define ASPM_MASK_NEG 0xFC #define ASPM_MASK_NEG 0xFC
#define MASK_8_BIT_DEF 0xFF #define MASK_8_BIT_DEF 0xFF
#define SSC_CLOCK_STABLE_WAIT 130
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val); int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val); int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
...@@ -57,6 +59,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr); ...@@ -57,6 +59,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr);
void rts524a_init_params(struct rtsx_pcr *pcr); void rts524a_init_params(struct rtsx_pcr *pcr);
void rts525a_init_params(struct rtsx_pcr *pcr); void rts525a_init_params(struct rtsx_pcr *pcr);
void rtl8411b_init_params(struct rtsx_pcr *pcr); void rtl8411b_init_params(struct rtsx_pcr *pcr);
void rts5260_init_params(struct rtsx_pcr *pcr);
static inline u8 map_sd_drive(int idx) static inline u8 map_sd_drive(int idx)
{ {
...@@ -99,5 +102,12 @@ do { \ ...@@ -99,5 +102,12 @@ do { \
int rtsx_gops_pm_reset(struct rtsx_pcr *pcr); int rtsx_gops_pm_reset(struct rtsx_pcr *pcr);
int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency); int rtsx_set_ltr_latency(struct rtsx_pcr *pcr, u32 latency);
int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val); int rtsx_set_l1off_sub(struct rtsx_pcr *pcr, u8 val);
void rtsx_pci_init_ocp(struct rtsx_pcr *pcr);
void rtsx_pci_disable_ocp(struct rtsx_pcr *pcr);
void rtsx_pci_enable_ocp(struct rtsx_pcr *pcr);
int rtsx_pci_get_ocpstat(struct rtsx_pcr *pcr, u8 *val);
void rtsx_pci_clear_ocpstat(struct rtsx_pcr *pcr);
int rtsx_sd_power_off_card3v3(struct rtsx_pcr *pcr);
int rtsx_ms_power_off_card3v3(struct rtsx_pcr *pcr);
#endif #endif
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/rtsx_usb.h> #include <linux/rtsx_usb.h>
static int polling_pipe = 1; static int polling_pipe = 1;
module_param(polling_pipe, int, S_IRUGO | S_IWUSR); module_param(polling_pipe, int, S_IRUGO | S_IWUSR);
......
...@@ -838,14 +838,14 @@ config MMC_USDHI6ROL0 ...@@ -838,14 +838,14 @@ config MMC_USDHI6ROL0
config MMC_REALTEK_PCI config MMC_REALTEK_PCI
tristate "Realtek PCI-E SD/MMC Card Interface Driver" tristate "Realtek PCI-E SD/MMC Card Interface Driver"
depends on MFD_RTSX_PCI depends on MISC_RTSX_PCI
help help
Say Y here to include driver code to support SD/MMC card interface Say Y here to include driver code to support SD/MMC card interface
of Realtek PCI-E card reader of Realtek PCI-E card reader
config MMC_REALTEK_USB config MMC_REALTEK_USB
tristate "Realtek USB SD/MMC Card Interface Driver" tristate "Realtek USB SD/MMC Card Interface Driver"
depends on MFD_RTSX_USB depends on MISC_RTSX_USB
help help
Say Y here to include driver code to support SD/MMC card interface Say Y here to include driver code to support SD/MMC card interface
of Realtek RTS5129/39 series card reader of Realtek RTS5129/39 series card reader
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/mmc/sd.h> #include <linux/mmc/sd.h>
#include <linux/mmc/sdio.h> #include <linux/mmc/sdio.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/mfd/rtsx_pci.h> #include <linux/rtsx_pci.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
struct realtek_pci_sdmmc { struct realtek_pci_sdmmc {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/mfd/rtsx_usb.h> #include <linux/rtsx_usb.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \
......
...@@ -38,14 +38,8 @@ config CHROMEOS_PSTORE ...@@ -38,14 +38,8 @@ config CHROMEOS_PSTORE
If you have a supported Chromebook, choose Y or M here. If you have a supported Chromebook, choose Y or M here.
The module will be called chromeos_pstore. The module will be called chromeos_pstore.
config CROS_EC_CHARDEV config CROS_EC_CTL
tristate "Chrome OS Embedded Controller userspace device interface" tristate
depends on MFD_CROS_EC
---help---
This driver adds support to talk with the ChromeOS EC from userspace.
If you have a supported Chromebook, choose Y or M here.
The module will be called cros_ec_dev.
config CROS_EC_LPC config CROS_EC_LPC
tristate "ChromeOS Embedded Controller (LPC)" tristate "ChromeOS Embedded Controller (LPC)"
......
...@@ -2,10 +2,9 @@ ...@@ -2,10 +2,9 @@
obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o
cros_ec_devs-objs := cros_ec_dev.o cros_ec_sysfs.o \ cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \
cros_ec_lightbar.o cros_ec_vbc.o \ cros_ec_vbc.o cros_ec_debugfs.o
cros_ec_debugfs.o obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o
obj-$(CONFIG_CROS_EC_CHARDEV) += cros_ec_devs.o
cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o
cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o
obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o
......
...@@ -29,9 +29,6 @@ ...@@ -29,9 +29,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/wait.h> #include <linux/wait.h>
#include "cros_ec_dev.h"
#include "cros_ec_debugfs.h"
#define LOG_SHIFT 14 #define LOG_SHIFT 14
#define LOG_SIZE (1 << LOG_SHIFT) #define LOG_SIZE (1 << LOG_SHIFT)
#define LOG_POLL_SEC 10 #define LOG_POLL_SEC 10
...@@ -390,6 +387,7 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec) ...@@ -390,6 +387,7 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec)
debugfs_remove_recursive(debug_info->dir); debugfs_remove_recursive(debug_info->dir);
return ret; return ret;
} }
EXPORT_SYMBOL(cros_ec_debugfs_init);
void cros_ec_debugfs_remove(struct cros_ec_dev *ec) void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
{ {
...@@ -399,3 +397,4 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec) ...@@ -399,3 +397,4 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
debugfs_remove_recursive(ec->debug_info->dir); debugfs_remove_recursive(ec->debug_info->dir);
cros_ec_cleanup_console_log(ec->debug_info); cros_ec_cleanup_console_log(ec->debug_info);
} }
EXPORT_SYMBOL(cros_ec_debugfs_remove);
/*
* Copyright 2015 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DRV_CROS_EC_DEBUGFS_H_
#define _DRV_CROS_EC_DEBUGFS_H_
#include "cros_ec_dev.h"
/* debugfs stuff */
int cros_ec_debugfs_init(struct cros_ec_dev *ec);
void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
#endif /* _DRV_CROS_EC_DEBUGFS_H_ */
...@@ -33,8 +33,6 @@ ...@@ -33,8 +33,6 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/slab.h> #include <linux/slab.h>
#include "cros_ec_dev.h"
/* Rate-limit the lightbar interface to prevent DoS. */ /* Rate-limit the lightbar interface to prevent DoS. */
static unsigned long lb_interval_jiffies = 50 * HZ / 1000; static unsigned long lb_interval_jiffies = 50 * HZ / 1000;
...@@ -414,6 +412,7 @@ int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable) ...@@ -414,6 +412,7 @@ int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable)
return ret; return ret;
} }
EXPORT_SYMBOL(lb_manual_suspend_ctrl);
int lb_suspend(struct cros_ec_dev *ec) int lb_suspend(struct cros_ec_dev *ec)
{ {
...@@ -422,6 +421,7 @@ int lb_suspend(struct cros_ec_dev *ec) ...@@ -422,6 +421,7 @@ int lb_suspend(struct cros_ec_dev *ec)
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND); return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND);
} }
EXPORT_SYMBOL(lb_suspend);
int lb_resume(struct cros_ec_dev *ec) int lb_resume(struct cros_ec_dev *ec)
{ {
...@@ -430,6 +430,7 @@ int lb_resume(struct cros_ec_dev *ec) ...@@ -430,6 +430,7 @@ int lb_resume(struct cros_ec_dev *ec)
return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME); return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME);
} }
EXPORT_SYMBOL(lb_resume);
static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, static ssize_t sequence_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
...@@ -622,3 +623,4 @@ struct attribute_group cros_ec_lightbar_attr_group = { ...@@ -622,3 +623,4 @@ struct attribute_group cros_ec_lightbar_attr_group = {
.attrs = __lb_cmds_attrs, .attrs = __lb_cmds_attrs,
.is_visible = cros_ec_lightbar_attrs_are_visible, .is_visible = cros_ec_lightbar_attrs_are_visible,
}; };
EXPORT_SYMBOL(cros_ec_lightbar_attr_group);
...@@ -34,8 +34,6 @@ ...@@ -34,8 +34,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "cros_ec_dev.h"
/* Accessor functions */ /* Accessor functions */
static ssize_t show_ec_reboot(struct device *dev, static ssize_t show_ec_reboot(struct device *dev,
...@@ -294,4 +292,7 @@ static struct attribute *__ec_attrs[] = { ...@@ -294,4 +292,7 @@ static struct attribute *__ec_attrs[] = {
struct attribute_group cros_ec_attr_group = { struct attribute_group cros_ec_attr_group = {
.attrs = __ec_attrs, .attrs = __ec_attrs,
}; };
EXPORT_SYMBOL(cros_ec_attr_group);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ChromeOS EC control driver");
...@@ -135,3 +135,4 @@ struct attribute_group cros_ec_vbc_attr_group = { ...@@ -135,3 +135,4 @@ struct attribute_group cros_ec_vbc_attr_group = {
.bin_attrs = cros_ec_vbc_bin_attrs, .bin_attrs = cros_ec_vbc_bin_attrs,
.is_bin_visible = cros_ec_vbc_is_visible, .is_bin_visible = cros_ec_vbc_is_visible,
}; };
EXPORT_SYMBOL(cros_ec_vbc_attr_group);
...@@ -132,6 +132,33 @@ void serdev_device_close(struct serdev_device *serdev) ...@@ -132,6 +132,33 @@ void serdev_device_close(struct serdev_device *serdev)
} }
EXPORT_SYMBOL_GPL(serdev_device_close); EXPORT_SYMBOL_GPL(serdev_device_close);
static void devm_serdev_device_release(struct device *dev, void *dr)
{
serdev_device_close(*(struct serdev_device **)dr);
}
int devm_serdev_device_open(struct device *dev, struct serdev_device *serdev)
{
struct serdev_device **dr;
int ret;
dr = devres_alloc(devm_serdev_device_release, sizeof(*dr), GFP_KERNEL);
if (!dr)
return -ENOMEM;
ret = serdev_device_open(serdev);
if (ret) {
devres_free(dr);
return ret;
}
*dr = serdev;
devres_add(dev, dr);
return 0;
}
EXPORT_SYMBOL_GPL(devm_serdev_device_open);
void serdev_device_write_wakeup(struct serdev_device *serdev) void serdev_device_write_wakeup(struct serdev_device *serdev)
{ {
complete(&serdev->write_comp); complete(&serdev->write_comp);
...@@ -268,7 +295,7 @@ static int serdev_drv_probe(struct device *dev) ...@@ -268,7 +295,7 @@ static int serdev_drv_probe(struct device *dev)
static int serdev_drv_remove(struct device *dev) static int serdev_drv_remove(struct device *dev)
{ {
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver); const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
if (sdrv->remove)
sdrv->remove(to_serdev_device(dev)); sdrv->remove(to_serdev_device(dev));
return 0; return 0;
} }
......
...@@ -223,6 +223,13 @@ config ZIIRAVE_WATCHDOG ...@@ -223,6 +223,13 @@ config ZIIRAVE_WATCHDOG
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ziirave_wdt. module will be called ziirave_wdt.
config RAVE_SP_WATCHDOG
tristate "RAVE SP Watchdog timer"
depends on RAVE_SP_CORE
select WATCHDOG_CORE
help
Support for the watchdog on RAVE SP device.
# ALPHA Architecture # ALPHA Architecture
# ARM Architecture # ARM Architecture
......
...@@ -224,3 +224,4 @@ obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o ...@@ -224,3 +224,4 @@ obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o
obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o
// SPDX-License-Identifier: GPL-2.0+
/*
* Driver for watchdog aspect of for Zodiac Inflight Innovations RAVE
* Supervisory Processor(SP) MCU
*
* Copyright (C) 2017 Zodiac Inflight Innovation
*
*/
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/mfd/rave-sp.h>
#include <linux/module.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/watchdog.h>
enum {
RAVE_SP_RESET_BYTE = 1,
RAVE_SP_RESET_REASON_NORMAL = 0,
RAVE_SP_RESET_DELAY_MS = 500,
};
/**
* struct rave_sp_wdt_variant - RAVE SP watchdog variant
*
* @max_timeout: Largest possible watchdog timeout setting
* @min_timeout: Smallest possible watchdog timeout setting
*
* @configure: Function to send configuration command
* @restart: Function to send "restart" command
*/
struct rave_sp_wdt_variant {
unsigned int max_timeout;
unsigned int min_timeout;
int (*configure)(struct watchdog_device *, bool);
int (*restart)(struct watchdog_device *);
};
/**
* struct rave_sp_wdt - RAVE SP watchdog
*
* @wdd: Underlying watchdog device
* @sp: Pointer to parent RAVE SP device
* @variant: Device specific variant information
* @reboot_notifier: Reboot notifier implementing machine reset
*/
struct rave_sp_wdt {
struct watchdog_device wdd;
struct rave_sp *sp;
const struct rave_sp_wdt_variant *variant;
struct notifier_block reboot_notifier;
};
static struct rave_sp_wdt *to_rave_sp_wdt(struct watchdog_device *wdd)
{
return container_of(wdd, struct rave_sp_wdt, wdd);
}
static int rave_sp_wdt_exec(struct watchdog_device *wdd, void *data,
size_t data_size)
{
return rave_sp_exec(to_rave_sp_wdt(wdd)->sp,
data, data_size, NULL, 0);
}
static int rave_sp_wdt_legacy_configure(struct watchdog_device *wdd, bool on)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_SW_WDT,
[1] = 0,
[2] = 0,
[3] = on,
[4] = on ? wdd->timeout : 0,
};
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
}
static int rave_sp_wdt_rdu_configure(struct watchdog_device *wdd, bool on)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_SW_WDT,
[1] = 0,
[2] = on,
[3] = (u8)wdd->timeout,
[4] = (u8)(wdd->timeout >> 8),
};
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
}
/**
* rave_sp_wdt_configure - Configure watchdog device
*
* @wdd: Device to configure
* @on: Desired state of the watchdog timer (ON/OFF)
*
* This function configures two aspects of the watchdog timer:
*
* - Wheither it is ON or OFF
* - Its timeout duration
*
* with first aspect specified via function argument and second via
* the value of 'wdd->timeout'.
*/
static int rave_sp_wdt_configure(struct watchdog_device *wdd, bool on)
{
return to_rave_sp_wdt(wdd)->variant->configure(wdd, on);
}
static int rave_sp_wdt_legacy_restart(struct watchdog_device *wdd)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_RESET,
[1] = 0,
[2] = RAVE_SP_RESET_BYTE
};
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
}
static int rave_sp_wdt_rdu_restart(struct watchdog_device *wdd)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_RESET,
[1] = 0,
[2] = RAVE_SP_RESET_BYTE,
[3] = RAVE_SP_RESET_REASON_NORMAL
};
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
}
static int rave_sp_wdt_reboot_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
/*
* Restart handler is called in atomic context which means we
* can't communicate to SP via UART. Luckily for use SP will
* wait 500ms before actually resetting us, so we ask it to do
* so here and let the rest of the system go on wrapping
* things up.
*/
if (action == SYS_DOWN || action == SYS_HALT) {
struct rave_sp_wdt *sp_wd =
container_of(nb, struct rave_sp_wdt, reboot_notifier);
const int ret = sp_wd->variant->restart(&sp_wd->wdd);
if (ret < 0)
dev_err(sp_wd->wdd.parent,
"Failed to issue restart command (%d)", ret);
return NOTIFY_OK;
}
return NOTIFY_DONE;
}
static int rave_sp_wdt_restart(struct watchdog_device *wdd,
unsigned long action, void *data)
{
/*
* The actual work was done by reboot notifier above. SP
* firmware waits 500 ms before issuing reset, so let's hang
* here for twice that delay and hopefuly we'd never reach
* the return statement.
*/
mdelay(2 * RAVE_SP_RESET_DELAY_MS);
return -EIO;
}
static int rave_sp_wdt_start(struct watchdog_device *wdd)
{
int ret;
ret = rave_sp_wdt_configure(wdd, true);
if (!ret)
set_bit(WDOG_HW_RUNNING, &wdd->status);
return ret;
}
static int rave_sp_wdt_stop(struct watchdog_device *wdd)
{
return rave_sp_wdt_configure(wdd, false);
}
static int rave_sp_wdt_set_timeout(struct watchdog_device *wdd,
unsigned int timeout)
{
wdd->timeout = timeout;
return rave_sp_wdt_configure(wdd, watchdog_active(wdd));
}
static int rave_sp_wdt_ping(struct watchdog_device *wdd)
{
u8 cmd[] = {
[0] = RAVE_SP_CMD_PET_WDT,
[1] = 0,
};
return rave_sp_wdt_exec(wdd, cmd, sizeof(cmd));
}
static const struct watchdog_info rave_sp_wdt_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
.identity = "RAVE SP Watchdog",
};
static const struct watchdog_ops rave_sp_wdt_ops = {
.owner = THIS_MODULE,
.start = rave_sp_wdt_start,
.stop = rave_sp_wdt_stop,
.ping = rave_sp_wdt_ping,
.set_timeout = rave_sp_wdt_set_timeout,
.restart = rave_sp_wdt_restart,
};
static const struct rave_sp_wdt_variant rave_sp_wdt_legacy = {
.max_timeout = 255,
.min_timeout = 1,
.configure = rave_sp_wdt_legacy_configure,
.restart = rave_sp_wdt_legacy_restart,
};
static const struct rave_sp_wdt_variant rave_sp_wdt_rdu = {
.max_timeout = 180,
.min_timeout = 60,
.configure = rave_sp_wdt_rdu_configure,
.restart = rave_sp_wdt_rdu_restart,
};
static const struct of_device_id rave_sp_wdt_of_match[] = {
{
.compatible = "zii,rave-sp-watchdog-legacy",
.data = &rave_sp_wdt_legacy,
},
{
.compatible = "zii,rave-sp-watchdog",
.data = &rave_sp_wdt_rdu,
},
{ /* sentinel */ }
};
static int rave_sp_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct watchdog_device *wdd;
struct rave_sp_wdt *sp_wd;
struct nvmem_cell *cell;
__le16 timeout = 0;
int ret;
sp_wd = devm_kzalloc(dev, sizeof(*sp_wd), GFP_KERNEL);
if (!sp_wd)
return -ENOMEM;
sp_wd->variant = of_device_get_match_data(dev);
sp_wd->sp = dev_get_drvdata(dev->parent);
wdd = &sp_wd->wdd;
wdd->parent = dev;
wdd->info = &rave_sp_wdt_info;
wdd->ops = &rave_sp_wdt_ops;
wdd->min_timeout = sp_wd->variant->min_timeout;
wdd->max_timeout = sp_wd->variant->max_timeout;
wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
wdd->timeout = 60;
cell = nvmem_cell_get(dev, "wdt-timeout");
if (!IS_ERR(cell)) {
size_t len;
void *value = nvmem_cell_read(cell, &len);
if (!IS_ERR(value)) {
memcpy(&timeout, value, min(len, sizeof(timeout)));
kfree(value);
}
nvmem_cell_put(cell);
}
watchdog_init_timeout(wdd, le16_to_cpu(timeout), dev);
watchdog_set_restart_priority(wdd, 255);
watchdog_stop_on_unregister(wdd);
sp_wd->reboot_notifier.notifier_call = rave_sp_wdt_reboot_notifier;
ret = devm_register_reboot_notifier(dev, &sp_wd->reboot_notifier);
if (ret) {
dev_err(dev, "Failed to register reboot notifier\n");
return ret;
}
/*
* We don't know if watchdog is running now. To be sure, let's
* start it and depend on watchdog core to ping it
*/
wdd->max_hw_heartbeat_ms = wdd->max_timeout * 1000;
ret = rave_sp_wdt_start(wdd);
if (ret) {
dev_err(dev, "Watchdog didn't start\n");
return ret;
}
ret = devm_watchdog_register_device(dev, wdd);
if (ret) {
dev_err(dev, "Failed to register watchdog device\n");
rave_sp_wdt_stop(wdd);
return ret;
}
return 0;
}
static struct platform_driver rave_sp_wdt_driver = {
.probe = rave_sp_wdt_probe,
.driver = {
.name = KBUILD_MODNAME,
.of_match_table = rave_sp_wdt_of_match,
},
};
module_platform_driver(rave_sp_wdt_driver);
MODULE_DEVICE_TABLE(of, rave_sp_wdt_of_match);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
MODULE_DESCRIPTION("RAVE SP Watchdog driver");
MODULE_ALIAS("platform:rave-sp-watchdog");
...@@ -5,12 +5,19 @@ ...@@ -5,12 +5,19 @@
#include <linux/types.h> #include <linux/types.h>
extern u16 const crc_ccitt_table[256]; extern u16 const crc_ccitt_table[256];
extern u16 const crc_ccitt_false_table[256];
extern u16 crc_ccitt(u16 crc, const u8 *buffer, size_t len); extern u16 crc_ccitt(u16 crc, const u8 *buffer, size_t len);
extern u16 crc_ccitt_false(u16 crc, const u8 *buffer, size_t len);
static inline u16 crc_ccitt_byte(u16 crc, const u8 c) static inline u16 crc_ccitt_byte(u16 crc, const u8 c)
{ {
return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff]; return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
} }
static inline u16 crc_ccitt_false_byte(u16 crc, const u8 c)
{
return (crc << 8) ^ crc_ccitt_false_table[(crc >> 8) ^ c];
}
#endif /* _LINUX_CRC_CCITT_H */ #endif /* _LINUX_CRC_CCITT_H */
...@@ -645,11 +645,6 @@ struct axp20x_dev { ...@@ -645,11 +645,6 @@ struct axp20x_dev {
const struct regmap_irq_chip *regmap_irq_chip; const struct regmap_irq_chip *regmap_irq_chip;
}; };
struct axp288_extcon_pdata {
/* GPIO pin control to switch D+/D- lines b/w PMIC and SOC */
struct gpio_desc *gpio_mux_cntl;
};
/* generic helper function for reading 9-16 bit wide regs */ /* generic helper function for reading 9-16 bit wide regs */
static inline int axp20x_read_variable_width(struct regmap *regmap, static inline int axp20x_read_variable_width(struct regmap *regmap,
unsigned int reg, unsigned int width) unsigned int reg, unsigned int width)
......
...@@ -322,6 +322,10 @@ extern struct attribute_group cros_ec_attr_group; ...@@ -322,6 +322,10 @@ extern struct attribute_group cros_ec_attr_group;
extern struct attribute_group cros_ec_lightbar_attr_group; extern struct attribute_group cros_ec_lightbar_attr_group;
extern struct attribute_group cros_ec_vbc_attr_group; extern struct attribute_group cros_ec_vbc_attr_group;
/* debugfs stuff */
int cros_ec_debugfs_init(struct cros_ec_dev *ec);
void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
/* ACPI GPE handler */ /* ACPI GPE handler */
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
......
...@@ -2904,16 +2904,33 @@ enum usb_pd_control_mux { ...@@ -2904,16 +2904,33 @@ enum usb_pd_control_mux {
USB_PD_CTRL_MUX_AUTO = 5, USB_PD_CTRL_MUX_AUTO = 5,
}; };
enum usb_pd_control_swap {
USB_PD_CTRL_SWAP_NONE = 0,
USB_PD_CTRL_SWAP_DATA = 1,
USB_PD_CTRL_SWAP_POWER = 2,
USB_PD_CTRL_SWAP_VCONN = 3,
USB_PD_CTRL_SWAP_COUNT
};
struct ec_params_usb_pd_control { struct ec_params_usb_pd_control {
uint8_t port; uint8_t port;
uint8_t role; uint8_t role;
uint8_t mux; uint8_t mux;
uint8_t swap;
} __packed; } __packed;
#define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */ #define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */
#define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */ #define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */
#define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */ #define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */
#define PD_CTRL_RESP_ROLE_POWER BIT(0) /* 0=SNK/1=SRC */
#define PD_CTRL_RESP_ROLE_DATA BIT(1) /* 0=UFP/1=DFP */
#define PD_CTRL_RESP_ROLE_VCONN BIT(2) /* Vconn status */
#define PD_CTRL_RESP_ROLE_DR_POWER BIT(3) /* Partner is dualrole power */
#define PD_CTRL_RESP_ROLE_DR_DATA BIT(4) /* Partner is dualrole data */
#define PD_CTRL_RESP_ROLE_USB_COMM BIT(5) /* Partner USB comm capable */
#define PD_CTRL_RESP_ROLE_EXT_POWERED BIT(6) /* Partner externally powerd */
struct ec_response_usb_pd_control_v1 { struct ec_response_usb_pd_control_v1 {
uint8_t enabled; uint8_t enabled;
uint8_t role; uint8_t role;
......
...@@ -3733,6 +3733,9 @@ enum usb_irq_events { ...@@ -3733,6 +3733,9 @@ enum usb_irq_events {
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE 0x01 #define TPS65917_REGEN3_CTRL_MODE_ACTIVE 0x01
#define TPS65917_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0x00 #define TPS65917_REGEN3_CTRL_MODE_ACTIVE_SHIFT 0x00
/* POWERHOLD Mask field for PRIMARY_SECONDARY_PAD2 register */
#define TPS65917_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK 0xC
/* Registers for function RESOURCE */ /* Registers for function RESOURCE */
#define TPS65917_REGEN1_CTRL 0x2 #define TPS65917_REGEN1_CTRL 0x2
#define TPS65917_PLLEN_CTRL 0x3 #define TPS65917_PLLEN_CTRL 0x3
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Core definitions for RAVE SP MFD driver.
*
* Copyright (C) 2017 Zodiac Inflight Innovations
*/
#ifndef _LINUX_RAVE_SP_H_
#define _LINUX_RAVE_SP_H_
#include <linux/notifier.h>
enum rave_sp_command {
RAVE_SP_CMD_GET_FIRMWARE_VERSION = 0x20,
RAVE_SP_CMD_GET_BOOTLOADER_VERSION = 0x21,
RAVE_SP_CMD_BOOT_SOURCE = 0x26,
RAVE_SP_CMD_GET_BOARD_COPPER_REV = 0x2B,
RAVE_SP_CMD_GET_GPIO_STATE = 0x2F,
RAVE_SP_CMD_STATUS = 0xA0,
RAVE_SP_CMD_SW_WDT = 0xA1,
RAVE_SP_CMD_PET_WDT = 0xA2,
RAVE_SP_CMD_RESET = 0xA7,
RAVE_SP_CMD_RESET_REASON = 0xA8,
RAVE_SP_CMD_REQ_COPPER_REV = 0xB6,
RAVE_SP_CMD_GET_I2C_DEVICE_STATUS = 0xBA,
RAVE_SP_CMD_GET_SP_SILICON_REV = 0xB9,
RAVE_SP_CMD_CONTROL_EVENTS = 0xBB,
RAVE_SP_EVNT_BASE = 0xE0,
};
struct rave_sp;
static inline unsigned long rave_sp_action_pack(u8 event, u8 value)
{
return ((unsigned long)value << 8) | event;
}
static inline u8 rave_sp_action_unpack_event(unsigned long action)
{
return action;
}
static inline u8 rave_sp_action_unpack_value(unsigned long action)
{
return action >> 8;
}
int rave_sp_exec(struct rave_sp *sp,
void *__data, size_t data_size,
void *reply_data, size_t reply_data_size);
struct device;
int devm_rave_sp_register_event_notifier(struct device *dev,
struct notifier_block *nb);
#endif /* _LINUX_RAVE_SP_H_ */
/* SPDX-License-Identifier: GPL-2.0 */
/* /*
* STM32 Low-Power Timer parent driver. * STM32 Low-Power Timer parent driver.
*
* Copyright (C) STMicroelectronics 2017 * Copyright (C) STMicroelectronics 2017
*
* Author: Fabrice Gasnier <fabrice.gasnier@st.com> * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
*
* Inspired by Benjamin Gaignard's stm32-timers driver * Inspired by Benjamin Gaignard's stm32-timers driver
*
* License terms: GNU General Public License (GPL), version 2
*/ */
#ifndef _LINUX_STM32_LPTIMER_H_ #ifndef _LINUX_STM32_LPTIMER_H_
......
/* SPDX-License-Identifier: GPL-2.0 */
/* /*
* Copyright (C) STMicroelectronics 2016 * Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com> * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/ */
#ifndef _LINUX_STM32_GPTIMER_H_ #ifndef _LINUX_STM32_GPTIMER_H_
......
...@@ -25,26 +25,6 @@ ...@@ -25,26 +25,6 @@
writew((val) >> 16, (addr) + 2); \ writew((val) >> 16, (addr) + 2); \
} while (0) } while (0)
#define CNF_CMD 0x04
#define CNF_CTL_BASE 0x10
#define CNF_INT_PIN 0x3d
#define CNF_STOP_CLK_CTL 0x40
#define CNF_GCLK_CTL 0x41
#define CNF_SD_CLK_MODE 0x42
#define CNF_PIN_STATUS 0x44
#define CNF_PWR_CTL_1 0x48
#define CNF_PWR_CTL_2 0x49
#define CNF_PWR_CTL_3 0x4a
#define CNF_CARD_DETECT_MODE 0x4c
#define CNF_SD_SLOT 0x50
#define CNF_EXT_GCLK_CTL_1 0xf0
#define CNF_EXT_GCLK_CTL_2 0xf1
#define CNF_EXT_GCLK_CTL_3 0xf9
#define CNF_SD_LED_EN_1 0xfa
#define CNF_SD_LED_EN_2 0xfe
#define SDCREN 0x2 /* Enable access to MMC CTL regs. (flag in COMMAND_REG)*/
#define sd_config_write8(base, shift, reg, val) \ #define sd_config_write8(base, shift, reg, val) \
tmio_iowrite8((val), (base) + ((reg) << (shift))) tmio_iowrite8((val), (base) + ((reg) << (shift)))
#define sd_config_write16(base, shift, reg, val) \ #define sd_config_write16(base, shift, reg, val) \
......
...@@ -193,6 +193,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl, ...@@ -193,6 +193,7 @@ static inline int serdev_controller_receive_buf(struct serdev_controller *ctrl,
int serdev_device_open(struct serdev_device *); int serdev_device_open(struct serdev_device *);
void serdev_device_close(struct serdev_device *); void serdev_device_close(struct serdev_device *);
int devm_serdev_device_open(struct device *, struct serdev_device *);
unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int); unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned int);
void serdev_device_set_flow_control(struct serdev_device *, bool); void serdev_device_set_flow_control(struct serdev_device *, bool);
int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t); int serdev_device_write_buf(struct serdev_device *, const unsigned char *, size_t);
......
...@@ -51,8 +51,49 @@ u16 const crc_ccitt_table[256] = { ...@@ -51,8 +51,49 @@ u16 const crc_ccitt_table[256] = {
}; };
EXPORT_SYMBOL(crc_ccitt_table); EXPORT_SYMBOL(crc_ccitt_table);
/*
* Similar table to calculate CRC16 variant known as CRC-CCITT-FALSE
* Reflected bits order, does not augment final value.
*/
u16 const crc_ccitt_false_table[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
EXPORT_SYMBOL(crc_ccitt_false_table);
/** /**
* crc_ccitt - recompute the CRC for the data buffer * crc_ccitt - recompute the CRC (CRC-CCITT variant) for the data
* buffer
* @crc: previous CRC value * @crc: previous CRC value
* @buffer: data pointer * @buffer: data pointer
* @len: number of bytes in the buffer * @len: number of bytes in the buffer
...@@ -65,5 +106,20 @@ u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len) ...@@ -65,5 +106,20 @@ u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len)
} }
EXPORT_SYMBOL(crc_ccitt); EXPORT_SYMBOL(crc_ccitt);
/**
* crc_ccitt_false - recompute the CRC (CRC-CCITT-FALSE variant)
* for the data buffer
* @crc: previous CRC value
* @buffer: data pointer
* @len: number of bytes in the buffer
*/
u16 crc_ccitt_false(u16 crc, u8 const *buffer, size_t len)
{
while (len--)
crc = crc_ccitt_false_byte(crc, *buffer++);
return crc;
}
EXPORT_SYMBOL(crc_ccitt_false);
MODULE_DESCRIPTION("CRC-CCITT calculations"); MODULE_DESCRIPTION("CRC-CCITT calculations");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
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