diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/bus/Kconfig | 8 | ||||
-rw-r--r-- | drivers/bus/Makefile | 1 | ||||
-rw-r--r-- | drivers/bus/ti-sysc.c | 37 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 6 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_imx_bbm.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_mxs.c | 27 | ||||
-rw-r--r-- | drivers/net/cpsw.c | 17 | ||||
-rw-r--r-- | drivers/net/designware.c | 2 | ||||
-rw-r--r-- | drivers/net/e1000/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000/eeprom.c | 3 | ||||
-rw-r--r-- | drivers/net/e1000/main.c | 113 | ||||
-rw-r--r-- | drivers/of/platform.c | 19 |
13 files changed, 173 insertions, 73 deletions
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 202df59762..219982d878 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -6,6 +6,14 @@ config BUS_OMAP_GPMC depends on OMAP_GPMC bool "TI OMAP/AM33xx GPMC support" +config TI_SYSC + depends on ARCH_OMAP + bool "TI sysc interconnect target module driver" + default y + help + Generic driver for Texas Instruments interconnect target module + found on many TI SoCs. + config IMX_WEIM depends on ARCH_IMX bool "i.MX WEIM driver" diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 4b7aa888ab..ba5cee4063 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_BUS_OMAP_GPMC) += omap-gpmc.o obj-$(CONFIG_IMX_WEIM) += imx-weim.o obj-$(CONFIG_MVEBU_MBUS) += mvebu-mbus.o +obj-$(CONFIG_TI_SYSC) += ti-sysc.o diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c new file mode 100644 index 0000000000..af52d839bd --- /dev/null +++ b/drivers/bus/ti-sysc.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2019 Phytec Messtechnik GmbH, Teresa Remmet <t.remmet@phytec.de> + */ + +#include <common.h> +#include <init.h> +#include <of.h> +#include <linux/err.h> + +static int ti_sysc_probe(struct device_d *dev) +{ + int ret; + + ret = of_platform_populate(dev->device_node, + of_default_bus_match_table, dev); + if (ret) + dev_err(dev, "%s fail to create devices.\n", + dev->device_node->full_name); + return ret; +}; + +static struct of_device_id ti_sysc_dt_ids[] = { + { .compatible = "ti,sysc-omap4",}, + { .compatible = "ti,sysc-omap4-simple",}, + { .compatible = "ti,sysc-omap4-timer",}, + { .compatible = "ti,sysc-omap2",}, + { }, +}; + +static struct driver_d ti_sysc_driver = { + .name = "ti-sysc", + .probe = ti_sysc_probe, + .of_compatible = DRV_OF_COMPAT(ti_sysc_dt_ids), +}; + +postcore_platform_driver(ti_sysc_driver); diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 8ae6f34468..bf15e6ccee 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2956,6 +2956,10 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) #endif if (!chip->read_buf) chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; +#ifdef CONFIG_NAND_BBT + if (!chip->scan_bbt) + chip->scan_bbt = nand_default_bbt; +#endif if (!chip->controller) { chip->controller = &chip->hwcontrol; } @@ -3846,7 +3850,7 @@ int nand_scan_tail(struct mtd_info *mtd) return 0; /* Build bad block table */ - return nand_create_bbt(mtd); + return chip->scan_bbt(mtd); } EXPORT_SYMBOL(nand_scan_tail); diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 90c10862c5..a908a36544 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -77,8 +77,6 @@ #define BBT_ENTRY_MASK 0x03 #define BBT_ENTRY_SHIFT 2 -static int nand_update_bbt(struct mtd_info *mtd, loff_t offs); - static inline uint8_t bbt_get_entry(struct nand_chip *chip, int block) { uint8_t entry = chip->bbt[block >> BBT_ENTRY_SHIFT]; @@ -1225,7 +1223,7 @@ err: * * The function updates the bad block table(s). */ -static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) +int nand_update_bbt(struct mtd_info *mtd, loff_t offs) { struct nand_chip *this = mtd->priv; int len, res = 0; @@ -1353,13 +1351,13 @@ static int nand_create_badblock_pattern(struct nand_chip *this) } /** - * nand_create_bbt - [NAND Interface] Select a default bad block table for the device + * nand_default_bbt - [NAND Interface] Select a default bad block table for the device * @mtd: MTD device structure * * This function selects the default bad block table support for the device and * calls the nand_scan_bbt function. */ -int nand_create_bbt(struct mtd_info *mtd) +int nand_default_bbt(struct mtd_info *mtd) { struct nand_chip *this = mtd->priv; int ret; @@ -1457,3 +1455,5 @@ int nand_markgood_bbt(struct mtd_info *mtd, loff_t offs) } EXPORT_SYMBOL(nand_scan_bbt); +EXPORT_SYMBOL(nand_default_bbt); +EXPORT_SYMBOL_GPL(nand_update_bbt); diff --git a/drivers/mtd/nand/nand_imx_bbm.c b/drivers/mtd/nand/nand_imx_bbm.c index 4fd5487aa2..23722a9064 100644 --- a/drivers/mtd/nand/nand_imx_bbm.c +++ b/drivers/mtd/nand/nand_imx_bbm.c @@ -129,7 +129,7 @@ static int attach_bbt(struct mtd_info *mtd, void *bbt) free(chip->bbt); chip->bbt = bbt; - return nand_create_bbt(mtd); + return nand_update_bbt(mtd, 0); } static int do_imx_nand_bbm(int argc, char *argv[]) diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c index f69453aba5..28a07d4cba 100644 --- a/drivers/mtd/nand/nand_mxs.c +++ b/drivers/mtd/nand/nand_mxs.c @@ -1201,7 +1201,21 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) return 0; } -static int mxs_nand_init_bch(struct mtd_info *mtd) +/* + * Nominally, the purpose of this function is to look for or create the bad + * block table. In fact, since the we call this function at the very end of + * the initialization process started by nand_scan(), and we doesn't have a + * more formal mechanism, we "hook" this function to continue init process. + * + * At this point, the physical NAND Flash chips have been identified and + * counted, so we know the physical geometry. This enables us to make some + * important configuration decisions. + * + * The return value of this function propogates directly back to this driver's + * call to nand_scan(). Anything other than zero will cause this driver to + * tear everything down and declare failure. + */ +static int mxs_nand_scan_bbt(struct mtd_info *mtd) { struct nand_chip *nand = mtd->priv; struct mxs_nand_info *nand_info = nand->priv; @@ -1238,7 +1252,8 @@ static int mxs_nand_init_bch(struct mtd_info *mtd) mtd->block_markbad = mxs_nand_hook_block_markbad; } - return 0; + /* We use the reference implementation for bad block management. */ + return nand_default_bbt(mtd); } /* @@ -2168,6 +2183,7 @@ static int mxs_nand_probe(struct device_d *dev) nand->dev_ready = mxs_nand_device_ready; nand->select_chip = mxs_nand_select_chip; nand->block_bad = mxs_nand_block_bad; + nand->scan_bbt = mxs_nand_scan_bbt; nand->read_byte = mxs_nand_read_byte; @@ -2199,13 +2215,6 @@ static int mxs_nand_probe(struct device_d *dev) mxs_nand_setup_timing(nand_info); - err = mxs_nand_init_bch(mtd); - if (err) - goto err2; - err = nand_create_bbt(mtd); - if (err) - goto err2; - /* second phase scan */ err = nand_scan_tail(mtd); if (err) diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index 432004ec9c..65f71c6fce 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -1053,6 +1053,7 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) { struct device_d *dev = priv->dev; struct device_node *np = dev->device_node, *child; + struct device_node *physel; int ret, i = 0; ret = of_property_read_u32(np, "slaves", &priv->num_slaves); @@ -1061,13 +1062,17 @@ static int cpsw_probe_dt(struct cpsw_priv *priv) priv->slaves = xzalloc(sizeof(struct cpsw_slave) * priv->num_slaves); - for_each_child_of_node(np, child) { - if (of_device_is_compatible(child, "ti,am3352-cpsw-phy-sel")) { - ret = cpsw_phy_sel_init(priv, child); - if (ret) - return ret; - } + physel = of_parse_phandle(dev->device_node, "cpsw-phy-sel", 0); + if (!physel) { + physel = of_get_child_by_name(dev->device_node, "cpsw-phy-sel"); + if (!physel) + dev_err(dev, "Phy mode node not found\n"); + } + ret = cpsw_phy_sel_init(priv, physel); + if (ret) + return ret; + for_each_child_of_node(np, child) { if (of_device_is_compatible(child, "ti,davinci_mdio")) { ret = of_pinctrl_select_state_default(child); if (ret) diff --git a/drivers/net/designware.c b/drivers/net/designware.c index ad70967e8c..3c9bca981c 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -291,12 +291,14 @@ static int dwc_ether_send(struct eth_device *dev, void *packet, int length) if (priv->enh_desc) { desc_p->txrx_status |= DESC_ENH_TXSTS_TXFIRST | DESC_ENH_TXSTS_TXLAST; + desc_p->dmamac_cntl &= ~(DESC_ENH_TXCTRL_SIZE1MASK); desc_p->dmamac_cntl |= (length << DESC_ENH_TXCTRL_SIZE1SHFT) & DESC_ENH_TXCTRL_SIZE1MASK; desc_p->txrx_status &= ~(DESC_ENH_TXSTS_MSK); desc_p->txrx_status |= DESC_ENH_TXSTS_OWNBYDMA; } else { + desc_p->dmamac_cntl &= ~(DESC_TXCTRL_SIZE1MASK); desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | DESC_TXCTRL_TXFIRST; diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 0a9e107c07..52ad3d4cdb 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -2182,6 +2182,7 @@ struct e1000_hw { struct e1000_tx_desc *tx_base; struct e1000_rx_desc *rx_base; unsigned char *packet; + dma_addr_t packet_dma; int tx_tail; int rx_tail, rx_last; diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index c0f2db552a..36d818b3f3 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -1000,7 +1000,8 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, (words > eeprom->word_size - offset) || (words == 0)) { dev_dbg(hw->dev, "\"words\" parameter out of bounds." - "Words = %d, size = %d\n", offset, eeprom->word_size); + "Words = %d, size = %d\n", offset, + (int)eeprom->word_size); return -E1000_ERR_EEPROM; } diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 0ef8fd6231..774e3d030f 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -33,13 +33,10 @@ tested on both gig copper and gig fiber boards #include <init.h> #include <malloc.h> #include <linux/pci.h> +#include <linux/iopoll.h> #include <dma.h> #include "e1000.h" - -static u32 inline virt_to_bus(struct pci_dev *pdev, void *adr) -{ - return (u32)adr; -} +#include <io-64-nonatomic-lo-hi.h> #define PCI_VENDOR_ID_INTEL 0x8086 @@ -3201,21 +3198,24 @@ static int e1000_sw_init(struct eth_device *edev) return E1000_SUCCESS; } -static void fill_rx(struct e1000_hw *hw) +static int e1000_bd_next_index(int index) { - volatile struct e1000_rx_desc *rd; - volatile u32 *bla; - int i; + return (index + 1) % 8; +} - hw->rx_last = hw->rx_tail; - rd = hw->rx_base + hw->rx_tail; - hw->rx_tail = (hw->rx_tail + 1) % 8; +static void e1000_fill_rx(struct e1000_hw *hw) +{ + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; - bla = (void *)rd; - for (i = 0; i < 4; i++) - *bla++ = 0; + hw->rx_last = hw->rx_tail; + hw->rx_tail = e1000_bd_next_index(hw->rx_tail); - rd->buffer_addr = cpu_to_le64((unsigned long)hw->packet); + writeq(hw->packet_dma, &rd->buffer_addr); + writew(0, &rd->length); + writew(0, &rd->csum); + writeb(0, &rd->status); + writeb(0, &rd->errors); + writew(0, &rd->special); e1000_write_reg(hw, E1000_RDT, hw->rx_tail); } @@ -3232,9 +3232,10 @@ static void e1000_configure_tx(struct e1000_hw *hw) unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; + const unsigned long tx_base = (unsigned long)hw->tx_base; - e1000_write_reg(hw, E1000_TDBAL, (unsigned long)hw->tx_base); - e1000_write_reg(hw, E1000_TDBAH, 0); + e1000_write_reg(hw, E1000_TDBAL, lower_32_bits(tx_base)); + e1000_write_reg(hw, E1000_TDBAH, upper_32_bits(tx_base)); e1000_write_reg(hw, E1000_TDLEN, 128); @@ -3350,6 +3351,7 @@ static void e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { unsigned long rctl, ctrl_ext; + const unsigned long rx_base = (unsigned long)hw->rx_base; hw->rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -3371,8 +3373,8 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_flush(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - e1000_write_reg(hw, E1000_RDBAL, (unsigned long)hw->rx_base); - e1000_write_reg(hw, E1000_RDBAH, 0); + e1000_write_reg(hw, E1000_RDBAL, lower_32_bits(rx_base)); + e1000_write_reg(hw, E1000_RDBAH, upper_32_bits(rx_base)); e1000_write_reg(hw, E1000_RDLEN, 128); @@ -3390,59 +3392,62 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_reg(hw, E1000_RCTL, rctl); - fill_rx(hw); + e1000_fill_rx(hw); } static int e1000_poll(struct eth_device *edev) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_rx_desc *rd; - uint32_t len; + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_last]; - rd = hw->rx_base + hw->rx_last; + if (readb(&rd->status) & E1000_RXD_STAT_DD) { + const uint16_t len = readw(&rd->length); - if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) - return 0; + dma_sync_single_for_cpu(hw->packet_dma, len, + DMA_FROM_DEVICE); - len = le32_to_cpu(rd->length); + net_receive(edev, hw->packet, len); - dma_sync_single_for_cpu((unsigned long)hw->packet, len, DMA_FROM_DEVICE); + dma_sync_single_for_device(hw->packet_dma, len, + DMA_FROM_DEVICE); + e1000_fill_rx(hw); + return 1; + } - net_receive(edev, (uchar *)hw->packet, len); - fill_rx(hw); - return 1; + return 0; } static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_tx_desc *txp; - uint64_t to; + struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; + dma_addr_t dma; + uint32_t stat; + int ret; - txp = hw->tx_base + hw->tx_tail; - hw->tx_tail = (hw->tx_tail + 1) % 8; + hw->tx_tail = e1000_bd_next_index(hw->tx_tail); - txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, txpacket)); - txp->lower.data = cpu_to_le32(hw->txd_cmd | length); - txp->upper.data = 0; + writel(hw->txd_cmd | length, &txp->lower.data); + writel(0, &txp->upper.data); - dma_sync_single_for_device((unsigned long)txpacket, length, DMA_TO_DEVICE); + dma = dma_map_single(hw->dev, txpacket, length, DMA_TO_DEVICE); + if (dma_mapping_error(hw->dev, dma)) + return -EFAULT; + writeq(dma, &txp->buffer_addr); e1000_write_reg(hw, E1000_TDT, hw->tx_tail); e1000_write_flush(hw); - to = get_time_ns(); - while (1) { - if (le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD) - break; - if (is_timeout(to, MSECOND)) { - dev_dbg(hw->dev, "e1000: tx timeout\n"); - return -ETIMEDOUT; - } - } + ret = readl_poll_timeout(&txp->upper.data, + stat, stat & E1000_TXD_STAT_DD, + MSECOND / USECOND); + if (ret) + dev_dbg(hw->dev, "e1000: tx timeout\n"); - return 0; + dma_unmap_single(hw->dev, dma, length, DMA_TO_DEVICE); + + return ret; } static void e1000_disable(struct eth_device *edev) @@ -3561,7 +3566,6 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) hw->tx_base = dma_alloc_coherent(16 * sizeof(*hw->tx_base), DMA_ADDRESS_BROKEN); hw->rx_base = dma_alloc_coherent(16 * sizeof(*hw->rx_base), DMA_ADDRESS_BROKEN); - hw->packet = dma_alloc_coherent(4096, DMA_ADDRESS_BROKEN); edev = &hw->edev; @@ -3570,6 +3574,15 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->dev.priv = hw; edev->priv = hw; + hw->packet = dma_alloc(PAGE_SIZE); + if (!hw->packet) + return -ENOMEM; + + hw->packet_dma = dma_map_single(hw->dev, hw->packet, PAGE_SIZE, + DMA_FROM_DEVICE); + if (dma_mapping_error(hw->dev, hw->packet_dma)) + return -EFAULT; + hw->hw_addr = pci_iomap(pdev, 0); /* MAC and Phy settings */ diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ef8969ca8b..d3795d799a 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -207,6 +207,25 @@ struct device_d *of_device_enable_and_register_by_name(const char *name) } EXPORT_SYMBOL(of_device_enable_and_register_by_name); +/** + * of_device_enable_and_register_by_alias - Enable and register device by alias + * @name: alias of the device node + * + * Returns pointer to created platform device, or NULL if a device was not + * registered. Unavailable devices will not get registered. + */ +struct device_d *of_device_enable_and_register_by_alias(const char *alias) +{ + struct device_node *node; + + node = of_find_node_by_alias(NULL, alias); + if (!node) + return NULL; + + return of_device_enable_and_register(node); +} +EXPORT_SYMBOL(of_device_enable_and_register_by_alias); + #ifdef CONFIG_ARM_AMBA static struct device_d *of_amba_device_create(struct device_node *np) { |