diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-06-11 11:33:34 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-06-11 11:33:34 +0200 |
commit | 06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8 (patch) | |
tree | 3c7c238c81aa91405159959906f31f6195aa6217 /drivers | |
parent | b697fba4a5c5395a9db271efa286870191418040 (diff) | |
parent | b917f7864115a35fbb9e69af2c1d553a110a37fc (diff) | |
download | barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.gz barebox-06b8bc4d708b8ff4eba1dd9b48ec110a8019d2c8.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpio/Kconfig | 17 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-pcf857x.c | 256 | ||||
-rw-r--r-- | drivers/mtd/devices/Kconfig | 2 | ||||
-rw-r--r-- | drivers/net/Kconfig | 4 | ||||
-rw-r--r-- | drivers/net/macb.c | 27 | ||||
-rw-r--r-- | drivers/net/phy/Kconfig | 26 | ||||
-rw-r--r-- | drivers/nvme/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/of/partition.c | 6 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 1 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 4 | ||||
-rw-r--r-- | drivers/w1/Kconfig | 4 |
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 |