summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-06-11 11:33:34 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2019-06-11 11:33:34 +0200
commit06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8 (patch)
tree3c7c238c81aa91405159959906f31f6195aa6217 /drivers
parentb697fba4a5c5395a9db271efa286870191418040 (diff)
parentb917f7864115a35fbb9e69af2c1d553a110a37fc (diff)
downloadbarebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.gz
barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/Kconfig17
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-pcf857x.c256
-rw-r--r--drivers/mtd/devices/Kconfig2
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/macb.c27
-rw-r--r--drivers/net/phy/Kconfig26
-rw-r--r--drivers/nvme/host/Kconfig2
-rw-r--r--drivers/of/partition.c6
-rw-r--r--drivers/usb/storage/transport.c1
-rw-r--r--drivers/usb/storage/usb.c4
-rw-r--r--drivers/w1/Kconfig4
12 files changed, 319 insertions, 31 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c535904ed0..6a4de7fbc8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -98,6 +98,23 @@ config GPIO_PCA953X
40 bits: pca9505, pca9698
+config GPIO_PCF857X
+ tristate "PCF857x, PCA{85,96}7x, and MAX732[89] I2C GPIO expanders"
+ depends on I2C
+ depends on CONFIG_OF
+ help
+ Say yes here to provide access to most "quasi-bidirectional" I2C
+ GPIO expanders used for additional digital outputs or inputs.
+ Most of these parts are from NXP, though TI is a second source for
+ some of them. Compatible models include:
+
+ 8 bits: pcf8574, pcf8574a, pca8574, pca8574a,
+ pca9670, pca9672, pca9674, pca9674a,
+ max7328, max7329
+
+ 16 bits: pcf8575, pcf8575c, pca8575,
+ pca9671, pca9673, pca9675
+
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 52280f0bb4..990df01788 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_GPIO_MALTA_FPGA_I2C) += gpio-malta-fpga-i2c.o
obj-$(CONFIG_GPIO_ORION) += gpio-orion.o
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o
+obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o
obj-$(CONFIG_GPIO_PL061) += gpio-pl061.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
new file mode 100644
index 0000000000..6c1c0ac352
--- /dev/null
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -0,0 +1,256 @@
+/*
+ * Driver for pcf857x, pca857x, and pca967x I2C GPIO expanders
+ *
+ * This code was ported from linux-5.1 kernel by Michael Grzeschik.
+ *
+ * Copyright (C) 2007 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <errno.h>
+#include <i2c/i2c.h>
+#include <gpio.h>
+
+static const struct platform_device_id pcf857x_id[] = {
+ { "pcf8574", 8 },
+ { "pcf8574a", 8 },
+ { "pca8574", 8 },
+ { "pca9670", 8 },
+ { "pca9672", 8 },
+ { "pca9674", 8 },
+ { "pcf8575", 16 },
+ { "pca8575", 16 },
+ { "pca9671", 16 },
+ { "pca9673", 16 },
+ { "pca9675", 16 },
+ { "max7328", 8 },
+ { "max7329", 8 },
+ { }
+};
+
+/*
+ * The pcf857x, pca857x, and pca967x chips only expose one read and one
+ * write register. Writing a "one" bit (to match the reset state) lets
+ * that pin be used as an input; it's not an open-drain model, but acts
+ * a bit like one. This is described as "quasi-bidirectional"; read the
+ * chip documentation for details.
+ *
+ * Many other I2C GPIO expander chips (like the pca953x models) have
+ * more complex register models and more conventional circuitry using
+ * push/pull drivers. They often use the same 0x20..0x27 addresses as
+ * pcf857x parts, making the "legacy" I2C driver model problematic.
+ */
+struct pcf857x {
+ struct gpio_chip chip;
+ struct i2c_client *client;
+ unsigned out; /* software latch */
+
+ int (*write)(struct i2c_client *client, unsigned data);
+ int (*read)(struct i2c_client *client);
+};
+
+static inline struct pcf857x *to_pcf(struct gpio_chip *gc)
+{
+ return container_of(gc, struct pcf857x, chip);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* Talk to 8-bit I/O expander */
+
+static int i2c_write_le8(struct i2c_client *client, unsigned data)
+{
+ return i2c_smbus_write_byte(client, data);
+}
+
+static int i2c_read_le8(struct i2c_client *client)
+{
+ return (int)i2c_smbus_read_byte(client);
+}
+
+/* Talk to 16-bit I/O expander */
+
+static int i2c_write_le16(struct i2c_client *client, unsigned word)
+{
+ u8 buf[2] = { word & 0xff, word >> 8, };
+ int ret;
+
+ ret = i2c_master_send(client, buf, 2);
+ return (ret < 0) ? ret : 0;
+}
+
+static int i2c_read_le16(struct i2c_client *client)
+{
+ u8 buf[2];
+ int ret;
+
+ ret = i2c_master_recv(client, buf, 2);
+ if (ret < 0)
+ return ret;
+ return (buf[1] << 8) | buf[0];
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int pcf857x_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct pcf857x *gpio = to_pcf(chip);
+ int ret;
+
+ gpio->out |= (1 << offset);
+ ret = gpio->write(gpio->client, gpio->out);
+
+ return ret;
+}
+
+static int pcf857x_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct pcf857x *gpio = to_pcf(chip);
+ int value;
+
+ value = gpio->read(gpio->client);
+ return (value < 0) ? value : !!(value & (1 << offset));
+}
+
+static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct pcf857x *gpio = to_pcf(chip);
+ unsigned bit = 1 << offset;
+ int ret;
+
+ if (value)
+ gpio->out |= bit;
+ else
+ gpio->out &= ~bit;
+ ret = gpio->write(gpio->client, gpio->out);
+
+ return ret;
+}
+
+static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ pcf857x_output(chip, offset, value);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct gpio_ops pcf857x_gpio_ops = {
+ .direction_input = pcf857x_input,
+ .direction_output = pcf857x_output,
+ .get = pcf857x_get,
+ .set = pcf857x_set,
+};
+
+static int pcf857x_probe(struct device_d *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct device_node *np = dev->device_node;
+ struct pcf857x *gpio;
+ unsigned long driver_data;
+ unsigned int n_latch = 0;
+ int ret;
+
+ if (!np)
+ return -EINVAL;
+
+ of_property_read_u32(np, "lines-initial-states", &n_latch);
+
+ /* Allocate, initialize, and register this gpio_chip. */
+ gpio = xzalloc(sizeof(*gpio));
+
+ ret = dev_get_drvdata(dev, (const void **)&driver_data);
+ if (ret)
+ return ret;
+
+ gpio->chip.base = -1;
+ gpio->chip.ops = &pcf857x_gpio_ops;
+ gpio->chip.ngpio = driver_data;
+ gpio->chip.dev = &client->dev;
+
+ /* NOTE: the OnSemi jlc1562b is also largely compatible with
+ * these parts, notably for output. It has a low-resolution
+ * DAC instead of pin change IRQs; and its inputs can be the
+ * result of comparators.
+ */
+
+ /* 8574 addresses are 0x20..0x27; 8574a uses 0x38..0x3f;
+ * 9670, 9672, 9764, and 9764a use quite a variety.
+ *
+ * NOTE: we don't distinguish here between *4 and *4a parts.
+ */
+ switch (gpio->chip.ngpio) {
+ case 8:
+ gpio->write = i2c_write_le8;
+ gpio->read = i2c_read_le8;
+ break;
+ /* '75/'75c addresses are 0x20..0x27, just like the '74;
+ * the '75c doesn't have a current source pulling high.
+ * 9671, 9673, and 9765 use quite a variety of addresses.
+ *
+ * NOTE: we don't distinguish here between '75 and '75c parts.
+ */
+ case 16:
+ gpio->write = i2c_write_le16;
+ gpio->read = i2c_read_le16;
+ break;
+ default:
+ dev_warn(&client->dev, "unsupported number of gpios\n");
+ return -EINVAL;
+ }
+
+ gpio->client = client;
+
+ /* NOTE: these chips have strange "quasi-bidirectional" I/O pins.
+ * We can't actually know whether a pin is configured (a) as output
+ * and driving the signal low, or (b) as input and reporting a low
+ * value ... without knowing the last value written since the chip
+ * came out of reset (if any). We can't read the latched output.
+ *
+ * In short, the only reliable solution for setting up pin direction
+ * is to do it explicitly.
+ *
+ * Using n_latch avoids that trouble. When left initialized to zero,
+ * our software copy of the "latch" then matches the chip's all-ones
+ * reset state. Otherwise it flags pins to be driven low.
+ */
+ gpio->out = ~n_latch;
+
+ ret = gpiochip_add(&gpio->chip);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static const struct of_device_id pcf857x_dt_ids[] = {
+ { .compatible = "nxp,pcf8574", .data = (void *)8 },
+ { .compatible = "nxp,pcf8574a", .data = (void *)8 },
+ { .compatible = "nxp,pca8574", .data = (void *)8 },
+ { .compatible = "nxp,pca9670", .data = (void *)8 },
+ { .compatible = "nxp,pca9672", .data = (void *)8 },
+ { .compatible = "nxp,pca9674", .data = (void *)8 },
+ { .compatible = "nxp,pcf8575", .data = (void *)16 },
+ { .compatible = "nxp,pca8575", .data = (void *)16 },
+ { .compatible = "nxp,pca9671", .data = (void *)16 },
+ { .compatible = "nxp,pca9673", .data = (void *)16 },
+ { .compatible = "nxp,pca9675", .data = (void *)16 },
+ { .compatible = "maxim,max7328", .data = (void *)8 },
+ { .compatible = "maxim,max7329", .data = (void *)8 },
+ { }
+};
+
+static struct driver_d pcf857x_driver = {
+ .name = "pcf857x",
+ .probe = pcf857x_probe,
+ .of_compatible = DRV_OF_COMPAT(pcf857x_dt_ids),
+ .id_table = pcf857x_id,
+};
+device_i2c_driver(pcf857x_driver);
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 25db10a9b2..47296cf518 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -52,7 +52,7 @@ config MTD_DOCG3
bool "M-Systems Disk-On-Chip G3"
select BCH
select BITREV
- ---help---
+ help
This provides an MTD device driver for the M-Systems DiskOnChip
G3 devices.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3e3de5a975..beeb4b8221 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -108,13 +108,13 @@ config DRIVER_NET_ENC28J60
bool "ENC28J60 support"
depends on SPI
select PHYLIB
- ---help---
+ help
Support for the Microchip EN28J60 ethernet chip.
config DRIVER_NET_ENC28J60_WRITEVERIFY
bool "Enable write verify"
depends on DRIVER_NET_ENC28J60
- ---help---
+ help
Enable the verify after the buffer write useful for debugging purpose.
If unsure, say N.
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0c0d17ee9b..a0411d6e4b 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -209,9 +209,11 @@ static int macb_recv(struct eth_device *edev)
dev_dbg(macb->dev, "%s\n", __func__);
for (;;) {
+ barrier();
if (!(macb->rx_ring[rx_tail].addr & MACB_BIT(RX_USED)))
return -1;
+ barrier();
status = macb->rx_ring[rx_tail].ctrl;
if (status & MACB_BIT(RX_SOF)) {
if (rx_tail != macb->rx_tail)
@@ -228,14 +230,26 @@ static int macb_recv(struct eth_device *edev)
headlen = macb->rx_buffer_size * (macb->rx_ring_size
- macb->rx_tail);
taillen = length - headlen;
- memcpy((void *)NetRxPackets[0],
- buffer, headlen);
+ dma_sync_single_for_cpu((unsigned long)buffer,
+ headlen, DMA_FROM_DEVICE);
+ memcpy((void *)NetRxPackets[0], buffer, headlen);
+ dma_sync_single_for_cpu((unsigned long)macb->rx_buffer,
+ taillen, DMA_FROM_DEVICE);
memcpy((void *)NetRxPackets[0] + headlen,
- macb->rx_buffer, taillen);
- buffer = (void *)NetRxPackets[0];
+ macb->rx_buffer, taillen);
+ dma_sync_single_for_device((unsigned long)buffer,
+ headlen, DMA_FROM_DEVICE);
+ dma_sync_single_for_device((unsigned long)macb->rx_buffer,
+ taillen, DMA_FROM_DEVICE);
+ net_receive(edev, NetRxPackets[0], length);
+ } else {
+ dma_sync_single_for_cpu((unsigned long)buffer, length,
+ DMA_FROM_DEVICE);
+ net_receive(edev, buffer, length);
+ dma_sync_single_for_device((unsigned long)buffer, length,
+ DMA_FROM_DEVICE);
}
-
- net_receive(edev, buffer, length);
+ barrier();
if (++rx_tail >= macb->rx_ring_size)
rx_tail = 0;
reclaim_rx_buffers(macb, rx_tail);
@@ -245,7 +259,6 @@ static int macb_recv(struct eth_device *edev)
rx_tail = 0;
}
}
- barrier();
}
return 0;
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c08b8257a7..2806af376f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -10,52 +10,52 @@ comment "MII PHY device drivers"
config AR8327N_PHY
bool "Driver for QCA AR8327N PHYs"
- ---help---
+ help
Currently supports the AR8327N PHY.
config AT803X_PHY
bool "Driver for Atheros AT803X PHYs"
- ---help---
+ help
Currently supports the AT8030, AT8031 and AT8035 PHYs.
config DAVICOM_PHY
bool "Driver for Davicom PHYs"
- ---help---
+ help
Currently supports dm9161e and dm9131
config DP83867_PHY
tristate "Texas Instruments DP83867 Gigabit PHY"
- ---help---
+ help
Currently supports the DP83867 PHY.
config LXT_PHY
bool "Driver for the Intel LXT PHYs"
- ---help---
+ help
Currently supports the lxt971 PHY.
config MARVELL_PHY
tristate "Drivers for Marvell PHYs"
- ---help---
+ help
Add support for various Marvell PHYs (e.g. 88E1121R).
config MICREL_PHY
bool "Driver for Micrel PHYs"
- ---help---
+ help
Supports the KSZ9021, VSC8201, KS8001 PHYs.
config NATIONAL_PHY
bool "Driver for National Semiconductor PHYs"
- ---help---
+ help
Currently supports the DP83865 PHY.
config REALTEK_PHY
bool "Driver for Realtek PHYs"
- ---help---
+ help
Supports the Realtek 821x PHY.
config SMSC_PHY
bool "Drivers for SMSC PHYs"
- ---help---
+ help
Currently supports the LAN83C185, LAN8187 and LAN8700 PHYs
config NET_DSA_MV88E6XXX
@@ -69,12 +69,12 @@ comment "MII bus device drivers"
config MDIO_MVEBU
bool "Driver for MVEBU SoC MDIO bus"
depends on ARCH_MVEBU
- ---help---
+ help
Driver for the MDIO bus found on Marvell EBU SoCs.
config MDIO_BITBANG
bool "Support for bitbanged MDIO buses"
- ---help---
+ help
This module implements the MDIO bus protocol in software,
for use by low level drivers that export the ability to
drive the relevant pins.
@@ -84,7 +84,7 @@ config MDIO_BITBANG
config MDIO_GPIO
bool "Support for GPIO lib-based bitbanged MDIO buses"
depends on MDIO_BITBANG && GPIOLIB
- ---help---
+ help
Supports GPIO lib-based MDIO busses.
config MDIO_BUS_MUX
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 8888c8900b..5499f97d7c 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -5,7 +5,7 @@ config BLK_DEV_NVME
bool "NVM Express block device"
depends on PCI && BLOCK
select NVME_CORE
- ---help---
+ help
The NVM Express driver is for solid state drives directly
connected to the PCI or PCI Express bus. If you know you
don't have one of these, it is safe to answer N.
diff --git a/drivers/of/partition.c b/drivers/of/partition.c
index 2848b9636d..655b67f854 100644
--- a/drivers/of/partition.c
+++ b/drivers/of/partition.c
@@ -64,9 +64,9 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
offset = of_read_number(reg, na);
size = of_read_number(reg + na, ns);
- partname = of_get_property(node, "label", &len);
+ partname = of_get_property(node, "label", NULL);
if (!partname)
- partname = of_get_property(node, "name", &len);
+ partname = of_get_property(node, "name", NULL);
if (!partname)
return NULL;
@@ -74,7 +74,7 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
debug("add partition: %s.%s 0x%08llx 0x%08llx\n", cdev->name, partname, offset, size);
- if (of_get_property(node, "read-only", &len))
+ if (of_get_property(node, "read-only", NULL))
flags = DEVFS_PARTITION_READONLY;
filename = basprintf("%s.%s", cdev->name, partname);
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 48ccee2072..5186508ba6 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -115,6 +115,7 @@ int usb_stor_Bulk_transport(struct us_blk_dev *usb_blkdev,
cbw.Length = cmdlen;
/* copy the command payload */
+ memset(cbw.CDB, 0, sizeof(cbw.CDB));
memcpy(cbw.CDB, cmd, cbw.Length);
/* send it to out endpoint */
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index fda24d6167..63d624e91b 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -142,7 +142,7 @@ exit:
static int usb_stor_test_unit_ready(struct us_blk_dev *usb_blkdev)
{
- u8 cmd[12];
+ u8 cmd[6];
int ret;
memset(cmd, 0, sizeof(cmd));
@@ -439,7 +439,7 @@ static int usb_stor_scan(struct usb_device *usbdev, struct us_data *us)
int num_devs = 0;
/* obtain the max LUN */
- us->max_lun = 1;
+ us->max_lun = 0;
if (us->protocol == US_PR_BULK)
us->max_lun = usb_stor_Bulk_max_lun(us);
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig
index 4a16197c69..6299f6e16d 100644
--- a/drivers/w1/Kconfig
+++ b/drivers/w1/Kconfig
@@ -1,6 +1,6 @@
menuconfig W1
bool "Dallas's 1-wire support"
- ---help---
+ help
Dallas' 1-wire bus is useful to connect slow 1-pin devices
such as iButtons and thermal sensors.
@@ -13,7 +13,7 @@ source "drivers/w1/slaves/Kconfig"
config W1_DUAL_SEARCH
bool "dual search"
- ---help---
+ help
Some device need to be searched twice to be detected
endif # W1