aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/oxnas/files/drivers
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2018-05-31 17:28:38 +0200
committerDaniel Golle <daniel@makrotopia.org>2018-06-18 18:44:14 +0200
commit6f398aa76248dfdbd1ea31b8ef32431be0f762ee (patch)
treee9c8f6380fdabb0a5e00b6bdd335c9397e93b6ad /target/linux/oxnas/files/drivers
parentd6ee5e462c34a337a1b53994df5581a507e2c342 (diff)
downloadupstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.tar.gz
upstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.tar.bz2
upstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.zip
oxnas: reboot target
Reboot the oxnas target based on Linux 4.14 by rebasing our support on top of the now-existing upstream kernel support. This commit brings oxnas support to the level of v4.17 having upstream drivers for Ethernet, Serial and NAND flash. Botch up OpenWrt's local drivers for EHCI, SATA and PCIe based on the new platform code and device-tree. Re-introduce base-files from old oxnas target which works for now but needs further clean-up towards generic board support. Functional issues: * PCIe won't come up (hence no USB3 on Shuttle KD20) * I2C bus of Akitio myCloud device is likely not to work (missing debounce support in new pinctrl driver) Code-style issues: * plla/pllb needs further cleanup -- currently their users are writing into the syscon regmap after acquireling the clk instead of using defined clk_*_*() functions to setup multipliers and dividors. * PCIe phy needs its own little driver. * SATA driver is a monster and should be split into an mfd having a raidctrl regmap, sata controller, sata ports and sata phy. Tested on MitraStar STG-212 aka. Medion Akoya MD86xxx and Shuttle KD20. Signed-off-by: Daniel Golle <daniel@makrotopia.org> (squash-picked commit 17511a7ea8 and commit dcc34574ef from master)
Diffstat (limited to 'target/linux/oxnas/files/drivers')
-rw-r--r--target/linux/oxnas/files/drivers/ata/sata_oxnas.c38
-rw-r--r--target/linux/oxnas/files/drivers/clk/clk-oxnas.c297
-rw-r--r--target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c96
-rw-r--r--target/linux/oxnas/files/drivers/irqchip/irq-rps.c145
-rw-r--r--target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c206
-rw-r--r--target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c145
-rw-r--r--target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c276
-rw-r--r--target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c1461
-rw-r--r--target/linux/oxnas/files/drivers/reset/reset-ox820.c107
-rw-r--r--target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c106
10 files changed, 385 insertions, 2492 deletions
diff --git a/target/linux/oxnas/files/drivers/ata/sata_oxnas.c b/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
index 291a06f959..64afa728a1 100644
--- a/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
+++ b/target/linux/oxnas/files/drivers/ata/sata_oxnas.c
@@ -29,7 +29,35 @@
#include <linux/clk.h>
#include <linux/reset.h>
-#include <mach/utils.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+static inline void oxnas_register_clear_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_set_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val |= mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_value_mask(void __iomem *p,
+ unsigned mask, unsigned new_value)
+{
+ /* TODO sanity check mask & new_value = new_value */
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ val |= new_value;
+ writel_relaxed(val, p);
+}
/* sgdma request structure */
struct sgdma_request {
@@ -848,7 +876,7 @@ wait_for_lock:
* list so want to give reentrant accessors a chance to get
* access ASAP
*/
- if (!list_empty(&hd->scsi_wait_queue.task_list))
+ if (!list_empty(&hd->scsi_wait_queue.head))
wake_up(&hd->scsi_wait_queue);
}
@@ -867,7 +895,7 @@ int sata_core_has_fast_waiters(struct ata_host *ah)
struct sata_oxnas_host_priv *hd = ah->private_data;
spin_lock_irqsave(&hd->core_lock, flags);
- has_waiters = !list_empty(&hd->fast_wait_queue.task_list);
+ has_waiters = !list_empty(&hd->fast_wait_queue.head);
spin_unlock_irqrestore(&hd->core_lock, flags);
return has_waiters;
@@ -882,7 +910,7 @@ int sata_core_has_scsi_waiters(struct ata_host *ah)
spin_lock_irqsave(&hd->core_lock, flags);
has_waiters = hd->scsi_nonblocking_attempts ||
- !list_empty(&hd->scsi_wait_queue.task_list);
+ !list_empty(&hd->scsi_wait_queue.head);
spin_unlock_irqrestore(&hd->core_lock, flags);
return has_waiters;
@@ -954,7 +982,7 @@ static void sata_oxnas_release_hw(struct ata_port *ap)
hd->locker_uid = 0;
hd->core_locked = 0;
released = 1;
- wake_up(!list_empty(&hd->scsi_wait_queue.task_list) ?
+ wake_up(!list_empty(&hd->scsi_wait_queue.head) ?
&hd->scsi_wait_queue :
&hd->fast_wait_queue);
}
diff --git a/target/linux/oxnas/files/drivers/clk/clk-oxnas.c b/target/linux/oxnas/files/drivers/clk/clk-oxnas.c
deleted file mode 100644
index 4dc6c44992..0000000000
--- a/target/linux/oxnas/files/drivers/clk/clk-oxnas.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2010 Broadcom
- * Copyright (C) 2012 Stephen Warren
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/>.
- */
-
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/delay.h>
-#include <linux/stringify.h>
-#include <linux/reset.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
-
-#define MHZ (1000 * 1000)
-
-struct clk_oxnas_pllb {
- struct clk_hw hw;
- struct device_node *devnode;
- struct reset_control *rstc;
-};
-
-#define to_clk_oxnas_pllb(_hw) container_of(_hw, struct clk_oxnas_pllb, hw)
-
-static unsigned long plla_clk_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- unsigned long fin = parent_rate;
- unsigned long pll0;
- unsigned long fbdiv, refdiv, outdiv;
-
- pll0 = readl_relaxed(SYS_CTRL_PLLA_CTRL0);
- refdiv = (pll0 >> PLLA_REFDIV_SHIFT) & PLLA_REFDIV_MASK;
- refdiv += 1;
- outdiv = (pll0 >> PLLA_OUTDIV_SHIFT) & PLLA_OUTDIV_MASK;
- outdiv += 1;
- fbdiv = readl_relaxed(SYS_CTRL_PLLA_CTRL1);
-
- /* seems we will not be here when pll is bypassed, so ignore this
- * case */
-
- return fin / MHZ * fbdiv / (refdiv * outdiv) / 32768 * MHZ;
-}
-
-static const char *pll_clk_parents[] = {
- "oscillator",
-};
-
-static struct clk_ops plla_ops = {
- .recalc_rate = plla_clk_recalc_rate,
-};
-
-static struct clk_init_data clk_plla_init = {
- .name = "plla",
- .ops = &plla_ops,
- .parent_names = pll_clk_parents,
- .num_parents = ARRAY_SIZE(pll_clk_parents),
-};
-
-static struct clk_hw plla_hw = {
- .init = &clk_plla_init,
-};
-
-static int pllb_clk_is_prepared(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- return !!pllb->rstc;
-}
-
-static int pllb_clk_prepare(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- pllb->rstc = of_reset_control_get(pllb->devnode, NULL);
-
- return IS_ERR(pllb->rstc) ? PTR_ERR(pllb->rstc) : 0;
-}
-
-static void pllb_clk_unprepare(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- reset_control_put(pllb->rstc);
- pllb->rstc = NULL;
-}
-
-static int pllb_clk_enable(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- /* put PLL into bypass */
- oxnas_register_set_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
- wmb();
- udelay(10);
- reset_control_assert(pllb->rstc);
- udelay(10);
- /* set PLL B control information */
- writel((1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV),
- SEC_CTRL_PLLB_CTRL0);
- reset_control_deassert(pllb->rstc);
- udelay(100);
- oxnas_register_clear_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
-
- return 0;
-}
-
-static void pllb_clk_disable(struct clk_hw *hw)
-{
- struct clk_oxnas_pllb *pllb = to_clk_oxnas_pllb(hw);
-
- BUG_ON(IS_ERR(pllb->rstc));
-
- /* put PLL into bypass */
- oxnas_register_set_mask(SEC_CTRL_PLLB_CTRL0, BIT(PLLB_BYPASS));
- wmb();
- udelay(10);
-
- reset_control_assert(pllb->rstc);
-}
-
-static struct clk_ops pllb_ops = {
- .prepare = pllb_clk_prepare,
- .unprepare = pllb_clk_unprepare,
- .is_prepared = pllb_clk_is_prepared,
- .enable = pllb_clk_enable,
- .disable = pllb_clk_disable,
-};
-
-static struct clk_init_data clk_pllb_init = {
- .name = "pllb",
- .ops = &pllb_ops,
- .parent_names = pll_clk_parents,
- .num_parents = ARRAY_SIZE(pll_clk_parents),
-};
-
-
-/* standard gate clock */
-struct clk_std {
- struct clk_hw hw;
- signed char bit;
-};
-
-#define NUM_STD_CLKS 17
-#define to_stdclk(_hw) container_of(_hw, struct clk_std, hw)
-
-static int std_clk_is_enabled(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- return readl_relaxed(SYSCTRL_CLK_STAT) & BIT(std->bit);
-}
-
-static int std_clk_enable(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- writel(BIT(std->bit), SYS_CTRL_CLK_SET_CTRL);
- return 0;
-}
-
-static void std_clk_disable(struct clk_hw *hw)
-{
- struct clk_std *std = to_stdclk(hw);
-
- writel(BIT(std->bit), SYS_CTRL_CLK_CLR_CTRL);
-}
-
-static struct clk_ops std_clk_ops = {
- .enable = std_clk_enable,
- .disable = std_clk_disable,
- .is_enabled = std_clk_is_enabled,
-};
-
-static const char *std_clk_parents[] = {
- "oscillator",
-};
-
-static const char *eth_parents[] = {
- "gmacclk",
-};
-
-#define DECLARE_STD_CLKP(__clk, __bit, __parent) \
-static struct clk_init_data clk_##__clk##_init = { \
- .name = __stringify(__clk), \
- .ops = &std_clk_ops, \
- .parent_names = __parent, \
- .num_parents = ARRAY_SIZE(__parent), \
-}; \
- \
-static struct clk_std clk_##__clk = { \
- .bit = __bit, \
- .hw = { \
- .init = &clk_##__clk##_init, \
- }, \
-}
-
-#define DECLARE_STD_CLK(__clk, __bit) DECLARE_STD_CLKP(__clk, __bit, \
- std_clk_parents)
-
-DECLARE_STD_CLK(leon, 0);
-DECLARE_STD_CLK(dma_sgdma, 1);
-DECLARE_STD_CLK(cipher, 2);
-DECLARE_STD_CLK(sd, 3);
-DECLARE_STD_CLK(sata, 4);
-DECLARE_STD_CLK(audio, 5);
-DECLARE_STD_CLK(usbmph, 6);
-DECLARE_STD_CLKP(etha, 7, eth_parents);
-DECLARE_STD_CLK(pciea, 8);
-DECLARE_STD_CLK(static, 9);
-DECLARE_STD_CLK(ethb, 10);
-DECLARE_STD_CLK(pcieb, 11);
-DECLARE_STD_CLK(ref600, 12);
-DECLARE_STD_CLK(usbdev, 13);
-
-struct clk_hw *std_clk_hw_tbl[] = {
- &clk_leon.hw,
- &clk_dma_sgdma.hw,
- &clk_cipher.hw,
- &clk_sd.hw,
- &clk_sata.hw,
- &clk_audio.hw,
- &clk_usbmph.hw,
- &clk_etha.hw,
- &clk_pciea.hw,
- &clk_static.hw,
- &clk_ethb.hw,
- &clk_pcieb.hw,
- &clk_ref600.hw,
- &clk_usbdev.hw,
-};
-
-struct clk *std_clk_tbl[ARRAY_SIZE(std_clk_hw_tbl)];
-
-static struct clk_onecell_data std_clk_data;
-
-void __init oxnas_init_stdclk(struct device_node *np)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(std_clk_hw_tbl); i++) {
- std_clk_tbl[i] = clk_register(NULL, std_clk_hw_tbl[i]);
- BUG_ON(IS_ERR(std_clk_tbl[i]));
- }
- std_clk_data.clks = std_clk_tbl;
- std_clk_data.clk_num = ARRAY_SIZE(std_clk_tbl);
- of_clk_add_provider(np, of_clk_src_onecell_get, &std_clk_data);
-}
-CLK_OF_DECLARE(oxnas_pllstd, "plxtech,nas782x-stdclk", oxnas_init_stdclk);
-
-void __init oxnas_init_plla(struct device_node *np)
-{
- struct clk *clk;
-
- clk = clk_register(NULL, &plla_hw);
- BUG_ON(IS_ERR(clk));
- /* mark it as enabled */
- clk_prepare_enable(clk);
- of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(oxnas_plla, "plxtech,nas782x-plla", oxnas_init_plla);
-
-void __init oxnas_init_pllb(struct device_node *np)
-{
- struct clk *clk;
- struct clk_oxnas_pllb *pllb;
-
- pllb = kmalloc(sizeof(*pllb), GFP_KERNEL);
- BUG_ON(!pllb);
-
- pllb->hw.init = &clk_pllb_init;
- pllb->devnode = np;
- pllb->rstc = NULL;
-
- clk = clk_register(NULL, &pllb->hw);
- BUG_ON(IS_ERR(clk));
- of_clk_add_provider(np, of_clk_src_simple_get, clk);
-}
-CLK_OF_DECLARE(oxnas_pllb, "plxtech,nas782x-pllb", oxnas_init_pllb);
diff --git a/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c b/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c
deleted file mode 100644
index 7c8c4cf435..0000000000
--- a/target/linux/oxnas/files/drivers/clocksource/oxnas_rps_timer.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * arch/arm/mach-ox820/rps-time.c
- *
- * Copyright (C) 2009 Oxford Semiconductor Ltd
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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/>.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/of_irq.h>
-#include <linux/of_address.h>
-#include <linux/sched_clock.h>
-#include <mach/hardware.h>
-
-enum {
- TIMER_LOAD = 0,
- TIMER_CURR = 4,
- TIMER_CTRL = 8,
- TIMER_CLRINT = 0xC,
-
- TIMER_BITS = 24,
-
- TIMER_MAX_VAL = (1 << TIMER_BITS) - 1,
-
- TIMER_PERIODIC = (1 << 6),
- TIMER_ENABLE = (1 << 7),
-
- TIMER_DIV1 = (0 << 2),
- TIMER_DIV16 = (1 << 2),
- TIMER_DIV256 = (2 << 2),
-
- TIMER1_OFFSET = 0,
- TIMER2_OFFSET = 0x20,
-
-};
-
-static u64 notrace rps_read_sched_clock(void)
-{
- return ~readl_relaxed(RPSA_TIMER2_VAL);
-}
-
-static void __init rps_clocksource_init(void __iomem *base, ulong ref_rate)
-{
- int ret;
- ulong clock_rate;
- /* use prescale 16 */
- clock_rate = ref_rate / 16;
-
- iowrite32(TIMER_MAX_VAL, base + TIMER_LOAD);
- iowrite32(TIMER_PERIODIC | TIMER_ENABLE | TIMER_DIV16,
- base + TIMER_CTRL);
-
- ret = clocksource_mmio_init(base + TIMER_CURR, "rps_clocksource_timer",
- clock_rate, 250, TIMER_BITS,
- clocksource_mmio_readl_down);
- if (ret)
- panic("can't register clocksource\n");
-
- sched_clock_register(rps_read_sched_clock, TIMER_BITS, clock_rate);
-}
-
-static void __init rps_timer_init(struct device_node *np)
-{
- struct clk *refclk;
- unsigned long ref_rate;
- void __iomem *base;
-
- refclk = of_clk_get(np, 0);
-
- if (IS_ERR(refclk) || clk_prepare_enable(refclk))
- panic("rps_timer_init: failed to get refclk\n");
- ref_rate = clk_get_rate(refclk);
-
- base = of_iomap(np, 0);
- if (!base)
- panic("rps_timer_init: failed to map io\n");
-
- rps_clocksource_init(base + TIMER2_OFFSET, ref_rate);
-}
-
-CLOCKSOURCE_OF_DECLARE(nas782x, "plxtech,nas782x-rps-timer", rps_timer_init);
diff --git a/target/linux/oxnas/files/drivers/irqchip/irq-rps.c b/target/linux/oxnas/files/drivers/irqchip/irq-rps.c
deleted file mode 100644
index f2b0829de6..0000000000
--- a/target/linux/oxnas/files/drivers/irqchip/irq-rps.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include <linux/irqdomain.h>
-#include <linux/irq.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/irqchip.h>
-
-struct rps_chip_data {
- void __iomem *base;
- struct irq_chip chip;
- struct irq_domain *domain;
-} rps_data;
-
-enum {
- RPS_IRQ_BASE = 64,
- RPS_IRQ_COUNT = 32,
- PRS_HWIRQ_BASE = 0,
-
- RPS_STATUS = 0,
- RPS_RAW_STATUS = 4,
- RPS_UNMASK = 8,
- RPS_MASK = 0xc,
-};
-
-/*
- * Routines to acknowledge, disable and enable interrupts
- */
-static void rps_mask_irq(struct irq_data *d)
-{
- struct rps_chip_data *chip_data = irq_data_get_irq_chip_data(d);
- u32 mask = BIT(d->hwirq);
-
- iowrite32(mask, chip_data->base + RPS_MASK);
-}
-
-static void rps_unmask_irq(struct irq_data *d)
-{
- struct rps_chip_data *chip_data = irq_data_get_irq_chip_data(d);
- u32 mask = BIT(d->hwirq);
-
- iowrite32(mask, chip_data->base + RPS_UNMASK);
-}
-
-static struct irq_chip rps_chip = {
- .name = "RPS",
- .irq_mask = rps_mask_irq,
- .irq_unmask = rps_unmask_irq,
-};
-
-static int rps_irq_domain_xlate(struct irq_domain *d,
- struct device_node *controller,
- const u32 *intspec, unsigned int intsize,
- unsigned long *out_hwirq,
- unsigned int *out_type)
-{
- if (irq_domain_get_of_node(d) != controller)
- return -EINVAL;
- if (intsize < 1)
- return -EINVAL;
-
- *out_hwirq = intspec[0];
- /* Honestly I do not know the type */
- *out_type = IRQ_TYPE_LEVEL_HIGH;
-
- return 0;
-}
-
-static int rps_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
- irq_set_chip_and_handler(irq, &rps_chip, handle_level_irq);
- irq_set_probe(irq);
- irq_set_chip_data(irq, d->host_data);
- return 0;
-}
-
-const struct irq_domain_ops rps_irq_domain_ops = {
- .map = rps_irq_domain_map,
- .xlate = rps_irq_domain_xlate,
-};
-
-static void rps_handle_cascade_irq(struct irq_desc *desc)
-{
- struct rps_chip_data *chip_data = irq_desc_get_handler_data(desc);
- struct irq_chip *chip = irq_desc_get_chip(desc);
- unsigned int cascade_irq, rps_irq;
- u32 status;
-
- chained_irq_enter(chip, desc);
-
- status = ioread32(chip_data->base + RPS_STATUS);
- rps_irq = __ffs(status);
- cascade_irq = irq_find_mapping(chip_data->domain, rps_irq);
-
- if (unlikely(rps_irq >= RPS_IRQ_COUNT))
- handle_bad_irq(desc);
- else
- generic_handle_irq(cascade_irq);
-
- chained_irq_exit(chip, desc);
-}
-
-#ifdef CONFIG_OF
-int __init rps_of_init(struct device_node *node, struct device_node *parent)
-{
- void __iomem *rps_base;
- int irq_start = RPS_IRQ_BASE;
- int irq_base;
- int irq;
-
- if (WARN_ON(!node))
- return -ENODEV;
-
- rps_base = of_iomap(node, 0);
- WARN(!rps_base, "unable to map rps registers\n");
- rps_data.base = rps_base;
-
- irq_base = irq_alloc_descs(irq_start, 0, RPS_IRQ_COUNT, numa_node_id());
- if (IS_ERR_VALUE(irq_base)) {
- WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
- irq_start);
- irq_base = irq_start;
- }
-
- rps_data.domain = irq_domain_add_legacy(node, RPS_IRQ_COUNT, irq_base,
- PRS_HWIRQ_BASE, &rps_irq_domain_ops, &rps_data);
-
- if (WARN_ON(!rps_data.domain))
- return -ENOMEM;
-
- if (parent) {
- irq = irq_of_parse_and_map(node, 0);
- if (irq_set_handler_data(irq, &rps_data) != 0)
- BUG();
- irq_set_chained_handler(irq, rps_handle_cascade_irq);
- }
- return 0;
-
-}
-
-IRQCHIP_DECLARE(nas782x, "plxtech,nas782x-rps", rps_of_init);
-#endif
diff --git a/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c b/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c
deleted file mode 100644
index 36807b7767..0000000000
--- a/target/linux/oxnas/files/drivers/mtd/nand/oxnas_nand.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Oxford Semiconductor OXNAS NAND driver
-
- * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
- * Heavily based on plat_nand.c :
- * Author: Vitaly Wool <vitalywool@gmail.com>
- * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com>
- * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/clk.h>
-#include <linux/reset.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/of.h>
-
-/* Nand commands */
-#define OXNAS_NAND_CMD_ALE BIT(18)
-#define OXNAS_NAND_CMD_CLE BIT(19)
-
-#define OXNAS_NAND_MAX_CHIPS 1
-
-struct oxnas_nand {
- struct nand_hw_control base;
- void __iomem *io_base;
- struct clk *clk;
- struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS];
- unsigned long ctrl;
- struct mtd_partition *partitions;
- int nr_partitions;
-};
-
-static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- return readb(oxnas->io_base);
-}
-
-static void oxnas_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- ioread8_rep(oxnas->io_base, buf, len);
-}
-
-static void oxnas_nand_write_buf(struct mtd_info *mtd,
- const uint8_t *buf, int len)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- iowrite8_rep(oxnas->io_base + oxnas->ctrl, buf, len);
-}
-
-/* Single CS command control */
-static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
- unsigned int ctrl)
-{
- struct nand_chip *chip = mtd_to_nand(mtd);
- struct oxnas_nand *oxnas = nand_get_controller_data(chip);
-
- if (ctrl & NAND_CTRL_CHANGE) {
- if (ctrl & NAND_CLE)
- oxnas->ctrl = OXNAS_NAND_CMD_CLE;
- else if (ctrl & NAND_ALE)
- oxnas->ctrl = OXNAS_NAND_CMD_ALE;
- else
- oxnas->ctrl = 0;
- }
-
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, oxnas->io_base + oxnas->ctrl);
-}
-
-/*
- * Probe for the NAND device.
- */
-static int oxnas_nand_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *nand_np;
- struct oxnas_nand *oxnas;
- struct nand_chip *chip;
- struct mtd_info *mtd;
- struct resource *res;
- int nchips = 0;
- int count = 0;
- int err = 0;
-
- /* Allocate memory for the device structure (and zero it) */
- oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
- GFP_KERNEL);
- if (!oxnas)
- return -ENOMEM;
-
- nand_hw_control_init(&oxnas->base);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas->io_base))
- return PTR_ERR(oxnas->io_base);
-
- oxnas->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(oxnas->clk))
- oxnas->clk = NULL;
-
- /* Only a single chip node is supported */
- count = of_get_child_count(np);
- if (count > 1)
- return -EINVAL;
-
- clk_prepare_enable(oxnas->clk);
- device_reset_optional(&pdev->dev);
-
- for_each_child_of_node(np, nand_np) {
- chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip),
- GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- chip->controller = &oxnas->base;
-
- nand_set_flash_node(chip, nand_np);
- nand_set_controller_data(chip, oxnas);
-
- mtd = nand_to_mtd(chip);
- mtd->dev.parent = &pdev->dev;
- mtd->priv = chip;
-
- chip->cmd_ctrl = oxnas_nand_cmd_ctrl;
- chip->read_buf = oxnas_nand_read_buf;
- chip->read_byte = oxnas_nand_read_byte;
- chip->write_buf = oxnas_nand_write_buf;
- chip->chip_delay = 30;
-
- /* Scan to find existence of the device */
- err = nand_scan(mtd, 1);
- if (err)
- return err;
-
- err = mtd_device_register(mtd, NULL, 0);
- if (err) {
- nand_release(mtd);
- return err;
- }
-
- oxnas->chips[nchips] = chip;
- ++nchips;
- }
-
- /* Exit if no chips found */
- if (!nchips)
- return -ENODEV;
-
- platform_set_drvdata(pdev, oxnas);
-
- return 0;
-}
-
-static int oxnas_nand_remove(struct platform_device *pdev)
-{
- struct oxnas_nand *oxnas = platform_get_drvdata(pdev);
-
- if (oxnas->chips[0])
- nand_release(nand_to_mtd(oxnas->chips[0]));
-
- clk_disable_unprepare(oxnas->clk);
-
- return 0;
-}
-
-static const struct of_device_id oxnas_nand_match[] = {
- { .compatible = "oxsemi,ox820-nand" },
- {},
-};
-MODULE_DEVICE_TABLE(of, oxnas_nand_match);
-
-static struct platform_driver oxnas_nand_driver = {
- .probe = oxnas_nand_probe,
- .remove = oxnas_nand_remove,
- .driver = {
- .name = "oxnas_nand",
- .of_match_table = oxnas_nand_match,
- },
-};
-
-module_platform_driver(oxnas_nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
-MODULE_DESCRIPTION("Oxnas NAND driver");
-MODULE_ALIAS("platform:oxnas_nand");
diff --git a/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
deleted file mode 100644
index aafb118144..0000000000
--- a/target/linux/oxnas/files/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright OpenWrt.org (C) 2015.
- * Copyright Altera Corporation (C) 2014. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2,
- * as published by the Free Software Foundation.
- *
- * 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/>.
- *
- * Adopted from dwmac-socfpga.c
- * Based on code found in mach-oxnas.c
- */
-
-#include <linux/mfd/syscon.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_net.h>
-#include <linux/phy.h>
-#include <linux/regmap.h>
-#include <linux/reset.h>
-#include <linux/stmmac.h>
-
-#include <mach/hardware.h>
-
-#include "stmmac.h"
-#include "stmmac_platform.h"
-
-struct oxnas_gmac {
- struct clk *clk;
-};
-
-static int oxnas_gmac_init(struct platform_device *pdev, void *priv)
-{
- struct oxnas_gmac *bsp_priv = priv;
- int ret = 0;
- unsigned value;
-
- ret = device_reset(&pdev->dev);
- if (ret)
- return ret;
-
- if (IS_ERR(bsp_priv->clk))
- return PTR_ERR(bsp_priv->clk);
- clk_prepare_enable(bsp_priv->clk);
-
- value = readl(SYS_CTRL_GMAC_CTRL);
-
- /* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
- value |= BIT(SYS_CTRL_GMAC_CKEN_GTX);
- /* Use simple mux for 25/125 Mhz clock switching */
- value |= BIT(SYS_CTRL_GMAC_SIMPLE_MUX);
- /* set auto switch tx clock source */
- value |= BIT(SYS_CTRL_GMAC_AUTO_TX_SOURCE);
- /* enable tx & rx vardelay */
- value |= BIT(SYS_CTRL_GMAC_CKEN_TX_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_TXN_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_TX_IN);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RX_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RXN_OUT);
- value |= BIT(SYS_CTRL_GMAC_CKEN_RX_IN);
- writel(value, SYS_CTRL_GMAC_CTRL);
-
- /* set tx & rx vardelay */
- value = 0;
- value |= SYS_CTRL_GMAC_TX_VARDELAY(4);
- value |= SYS_CTRL_GMAC_TXN_VARDELAY(2);
- value |= SYS_CTRL_GMAC_RX_VARDELAY(10);
- value |= SYS_CTRL_GMAC_RXN_VARDELAY(8);
- writel(value, SYS_CTRL_GMAC_DELAY_CTRL);
-
- return 0;
-}
-
-static void oxnas_gmac_exit(struct platform_device *pdev, void *priv)
-{
- struct reset_control *rstc;
-
- clk_disable_unprepare(priv);
- devm_clk_put(&pdev->dev, priv);
-
- rstc = reset_control_get(&pdev->dev, NULL);
- if (!IS_ERR(rstc)) {
- reset_control_assert(rstc);
- reset_control_put(rstc);
- }
-}
-
-static int oxnas_gmac_probe(struct platform_device *pdev)
-{
- struct plat_stmmacenet_data *plat_dat;
- struct stmmac_resources stmmac_res;
- int ret;
- struct device *dev = &pdev->dev;
- struct oxnas_gmac *bsp_priv;
-
- bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
- if (!bsp_priv)
- return -ENOMEM;
- bsp_priv->clk = devm_clk_get(dev, "gmac");
- if (IS_ERR(bsp_priv->clk))
- return PTR_ERR(bsp_priv->clk);
-
- ret = stmmac_get_platform_resources(pdev, &stmmac_res);
- if (ret)
- return ret;
-
- plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac);
- if (IS_ERR(plat_dat))
- return PTR_ERR(plat_dat);
-
- plat_dat->bsp_priv = bsp_priv;
- plat_dat->init = oxnas_gmac_init;
- plat_dat->exit = oxnas_gmac_exit;
-
- ret = oxnas_gmac_init(pdev, bsp_priv);
- if (ret)
- return ret;
-
- return stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
-}
-
-static const struct of_device_id oxnas_gmac_match[] = {
- { .compatible = "plxtech,nas782x-gmac" },
- { }
-};
-MODULE_DEVICE_TABLE(of, oxnas_gmac_match);
-
-static struct platform_driver oxnas_gmac_driver = {
- .probe = oxnas_gmac_probe,
- .remove = stmmac_pltfr_remove,
- .driver = {
- .name = "oxnas-gmac",
- .pm = &stmmac_pltfr_pm_ops,
- .of_match_table = oxnas_gmac_match,
- },
-};
-module_platform_driver(oxnas_gmac_driver);
-
-MODULE_LICENSE("GPL v2");
diff --git a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
index 9e8d6d9f93..7cf3ad1670 100644
--- a/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
+++ b/target/linux/oxnas/files/drivers/pci/host/pcie-oxnas.c
@@ -22,9 +22,279 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/reset.h>
-#include <mach/iomap.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+
+#define OXNAS_UART1_BASE 0x44200000
+#define OXNAS_UART1_SIZE SZ_32
+#define OXNAS_UART1_BASE_VA 0xF0000000
+
+#define OXNAS_UART2_BASE 0x44300000
+#define OXNAS_UART2_SIZE SZ_32
+
+#define OXNAS_PERCPU_BASE 0x47000000
+#define OXNAS_PERCPU_SIZE SZ_8K
+#define OXNAS_PERCPU_BASE_VA 0xF0002000
+
+#define OXNAS_SYSCRTL_BASE 0x44E00000
+#define OXNAS_SYSCRTL_SIZE SZ_4K
+#define OXNAS_SYSCRTL_BASE_VA 0xF0004000
+
+#define OXNAS_SECCRTL_BASE 0x44F00000
+#define OXNAS_SECCRTL_SIZE SZ_4K
+#define OXNAS_SECCRTL_BASE_VA 0xF0005000
+
+#define OXNAS_RPSA_BASE 0x44400000
+#define OXNAS_RPSA_SIZE SZ_4K
+#define OXNAS_RPSA_BASE_VA 0xF0006000
+
+#define OXNAS_RPSC_BASE 0x44500000
+#define OXNAS_RPSC_SIZE SZ_4K
+#define OXNAS_RPSC_BASE_VA 0xF0007000
+
+
+/*
+ * Location of flags and vectors in SRAM for controlling the booting of the
+ * secondary ARM11 processors.
+ */
+
+#define OXNAS_SCU_BASE_VA OXNAS_PERCPU_BASE_VA
+#define OXNAS_GICN_BASE_VA(n) (OXNAS_PERCPU_BASE_VA + 0x200 + n*0x100)
+
+#define HOLDINGPEN_CPU IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8)
+#define HOLDINGPEN_LOCATION IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4)
+
+/**
+ * System block reset and clock control
+ */
+#define SYS_CTRL_PCI_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x20)
+#define SYSCTRL_CLK_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x24)
+#define SYS_CTRL_CLK_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x2C)
+#define SYS_CTRL_CLK_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x30)
+#define SYS_CTRL_RST_SET_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x34)
+#define SYS_CTRL_RST_CLR_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x38)
+
+#define SYS_CTRL_PLLSYS_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x48)
+#define SYS_CTRL_CLK_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x64)
+#define SYS_CTRL_PLLSYS_KEY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x6C)
+#define SYS_CTRL_GMAC_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x78)
+#define SYS_CTRL_GMAC_DELAY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x100)
+
+/* Scratch registers */
+#define SYS_CTRL_SCRATCHWORD0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc4)
+#define SYS_CTRL_SCRATCHWORD1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xc8)
+#define SYS_CTRL_SCRATCHWORD2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xcc)
+#define SYS_CTRL_SCRATCHWORD3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xd0)
+
+#define SYS_CTRL_PLLA_CTRL0 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F0)
+#define SYS_CTRL_PLLA_CTRL1 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F4)
+#define SYS_CTRL_PLLA_CTRL2 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1F8)
+#define SYS_CTRL_PLLA_CTRL3 IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x1FC)
+
+#define SYS_CTRL_USBHSMPH_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x40)
+#define SYS_CTRL_USBHSMPH_STAT IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x44)
+#define SYS_CTRL_REF300_DIV IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xF8)
+#define SYS_CTRL_USBHSPHY_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x84)
+#define SYS_CTRL_USB_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x90)
+
+/* pcie */
+#define SYS_CTRL_HCSL_CTRL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x114)
+
+/* System control multi-function pin function selection */
+#define SYS_CTRL_SECONDARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x14)
+#define SYS_CTRL_TERTIARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x8c)
+#define SYS_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x94)
+#define SYS_CTRL_DEBUG_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0x9c)
+#define SYS_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xa4)
+#define SYS_CTRL_PULLUP_SEL IOMEM(OXNAS_SYSCRTL_BASE_VA + 0xac)
+
+/* Secure control multi-function pin function selection */
+#define SEC_CTRL_SECONDARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x14)
+#define SEC_CTRL_TERTIARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x8c)
+#define SEC_CTRL_QUATERNARY_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x94)
+#define SEC_CTRL_DEBUG_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x9c)
+#define SEC_CTRL_ALTERNATIVE_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xa4)
+#define SEC_CTRL_PULLUP_SEL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xac)
+
+#define SEC_CTRL_COPRO_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x68)
+#define SEC_CTRL_SECURE_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0x98)
+#define SEC_CTRL_LEON_DEBUG IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF0)
+#define SEC_CTRL_PLLB_DIV_CTRL IOMEM(OXNAS_SECCRTL_BASE_VA + 0xF8)
+#define SEC_CTRL_PLLB_CTRL0 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F0)
+#define SEC_CTRL_PLLB_CTRL1 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4)
+#define SEC_CTRL_PLLB_CTRL8 IOMEM(OXNAS_SECCRTL_BASE_VA + 0x1F4)
+
+#define RPSA_IRQ_SOFT IOMEM(OXNAS_RPSA_BASE_VA + 0x10)
+#define RPSA_FIQ_ENABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x108)
+#define RPSA_FIQ_DISABLE IOMEM(OXNAS_RPSA_BASE_VA + 0x10C)
+#define RPSA_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSA_BASE_VA + 0x1FC)
+
+#define RPSC_IRQ_SOFT IOMEM(OXNAS_RPSC_BASE_VA + 0x10)
+#define RPSC_FIQ_ENABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x108)
+#define RPSC_FIQ_DISABLE IOMEM(OXNAS_RPSC_BASE_VA + 0x10C)
+#define RPSC_FIQ_IRQ_TO_FIQ IOMEM(OXNAS_RPSC_BASE_VA + 0x1FC)
+
+#define RPSA_TIMER2_VAL IOMEM(OXNAS_RPSA_BASE_VA + 0x224)
+
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
+#define USBHSPHY_SUSPENDM_MANUAL_STATE 15
+#define USBHSPHY_ATE_ESET 14
+#define USBHSPHY_TEST_DIN 6
+#define USBHSPHY_TEST_ADD 2
+#define USBHSPHY_TEST_DOUT_SEL 1
+#define USBHSPHY_TEST_CLK 0
+
+#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5
+#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+
+#define USBAMUX_DEVICE BIT(4)
+
+#define USBPHY_REFCLKDIV_SHIFT 2
+#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT)
+
+#define USB_CTRL_USB_CKO_SEL_BIT 0
+
+#define USB_INT_CLK_XTAL 0
+#define USB_INT_CLK_REF300 2
+#define USB_INT_CLK_PLLB 3
+
+#define SYS_CTRL_GMAC_CKEN_RX_IN 14
+#define SYS_CTRL_GMAC_CKEN_RXN_OUT 13
+#define SYS_CTRL_GMAC_CKEN_RX_OUT 12
+#define SYS_CTRL_GMAC_CKEN_TX_IN 10
+#define SYS_CTRL_GMAC_CKEN_TXN_OUT 9
+#define SYS_CTRL_GMAC_CKEN_TX_OUT 8
+#define SYS_CTRL_GMAC_RX_SOURCE 7
+#define SYS_CTRL_GMAC_TX_SOURCE 6
+#define SYS_CTRL_GMAC_LOW_TX_SOURCE 4
+#define SYS_CTRL_GMAC_AUTO_TX_SOURCE 3
+#define SYS_CTRL_GMAC_RGMII 2
+#define SYS_CTRL_GMAC_SIMPLE_MUX 1
+#define SYS_CTRL_GMAC_CKEN_GTX 0
+#define SYS_CTRL_GMAC_TX_VARDELAY_SHIFT 0
+#define SYS_CTRL_GMAC_TXN_VARDELAY_SHIFT 8
+#define SYS_CTRL_GMAC_RX_VARDELAY_SHIFT 16
+#define SYS_CTRL_GMAC_RXN_VARDELAY_SHIFT 24
+#define SYS_CTRL_GMAC_TX_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_TX_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_TXN_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_TXN_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_RX_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_RX_VARDELAY_SHIFT)
+#define SYS_CTRL_GMAC_RXN_VARDELAY(d) ((d)<<SYS_CTRL_GMAC_RXN_VARDELAY_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
+
+#define SYS_CTRL_CKCTRL_PCI_DIV_BIT 0
+#define SYS_CTRL_CKCTRL_SLOW_BIT 8
+
+#define SYS_CTRL_UART2_DEQ_EN 0
+#define SYS_CTRL_UART3_DEQ_EN 1
+#define SYS_CTRL_UART3_IQ_EN 2
+#define SYS_CTRL_UART4_IQ_EN 3
+#define SYS_CTRL_UART4_NOT_PCI_MODE 4
+
+#define SYS_CTRL_PCI_CTRL1_PCI_STATIC_RQ_BIT 11
+
+#define PLLA_REFDIV_MASK 0x3F
+#define PLLA_REFDIV_SHIFT 8
+#define PLLA_OUTDIV_MASK 0x7
+#define PLLA_OUTDIV_SHIFT 4
+
+/* bit numbers of clock control register */
+#define SYS_CTRL_CLK_COPRO 0
+#define SYS_CTRL_CLK_DMA 1
+#define SYS_CTRL_CLK_CIPHER 2
+#define SYS_CTRL_CLK_SD 3
+#define SYS_CTRL_CLK_SATA 4
+#define SYS_CTRL_CLK_I2S 5
+#define SYS_CTRL_CLK_USBHS 6
+#define SYS_CTRL_CLK_MACA 7
+#define SYS_CTRL_CLK_MAC SYS_CTRL_CLK_MACA
+#define SYS_CTRL_CLK_PCIEA 8
+#define SYS_CTRL_CLK_STATIC 9
+#define SYS_CTRL_CLK_MACB 10
+#define SYS_CTRL_CLK_PCIEB 11
+#define SYS_CTRL_CLK_REF600 12
+#define SYS_CTRL_CLK_USBDEV 13
+#define SYS_CTRL_CLK_DDR 14
+#define SYS_CTRL_CLK_DDRPHY 15
+#define SYS_CTRL_CLK_DDRCK 16
+
+
+/* bit numbers of reset control register */
+#define SYS_CTRL_RST_SCU 0
+#define SYS_CTRL_RST_COPRO 1
+#define SYS_CTRL_RST_ARM0 2
+#define SYS_CTRL_RST_ARM1 3
+#define SYS_CTRL_RST_USBHS 4
+#define SYS_CTRL_RST_USBHSPHYA 5
+#define SYS_CTRL_RST_MACA 6
+#define SYS_CTRL_RST_MAC SYS_CTRL_RST_MACA
+#define SYS_CTRL_RST_PCIEA 7
+#define SYS_CTRL_RST_SGDMA 8
+#define SYS_CTRL_RST_CIPHER 9
+#define SYS_CTRL_RST_DDR 10
+#define SYS_CTRL_RST_SATA 11
+#define SYS_CTRL_RST_SATA_LINK 12
+#define SYS_CTRL_RST_SATA_PHY 13
+#define SYS_CTRL_RST_PCIEPHY 14
+#define SYS_CTRL_RST_STATIC 15
+#define SYS_CTRL_RST_GPIO 16
+#define SYS_CTRL_RST_UART1 17
+#define SYS_CTRL_RST_UART2 18
+#define SYS_CTRL_RST_MISC 19
+#define SYS_CTRL_RST_I2S 20
+#define SYS_CTRL_RST_SD 21
+#define SYS_CTRL_RST_MACB 22
+#define SYS_CTRL_RST_PCIEB 23
+#define SYS_CTRL_RST_VIDEO 24
+#define SYS_CTRL_RST_DDR_PHY 25
+#define SYS_CTRL_RST_USBHSPHYB 26
+#define SYS_CTRL_RST_USBDEV 27
+#define SYS_CTRL_RST_ARMDBG 29
+#define SYS_CTRL_RST_PLLA 30
+#define SYS_CTRL_RST_PLLB 31
+
+static inline void oxnas_register_clear_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_set_mask(void __iomem *p, unsigned mask)
+{
+ u32 val = readl_relaxed(p);
+
+ val |= mask;
+ writel_relaxed(val, p);
+}
+
+static inline void oxnas_register_value_mask(void __iomem *p,
+ unsigned mask, unsigned new_value)
+{
+ /* TODO sanity check mask & new_value = new_value */
+ u32 val = readl_relaxed(p);
+
+ val &= ~mask;
+ val |= new_value;
+ writel_relaxed(val, p);
+}
#define VERSION_ID_MAGIC 0x082510b5
#define LINK_UP_TIMEOUT_SECONDS 1
diff --git a/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c b/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c
deleted file mode 100644
index 38a8cbb451..0000000000
--- a/target/linux/oxnas/files/drivers/pinctrl/pinctrl-oxnas.c
+++ /dev/null
@@ -1,1461 +0,0 @@
-/*
- * oxnas pinctrl driver based on at91 pinctrl driver
- *
- * Copyright (C) 2011-2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2 only
- */
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/irqchip/chained_irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-/* Since we request GPIOs from ourself */
-#include <linux/pinctrl/consumer.h>
-#include <linux/spinlock.h>
-
-#include "core.h"
-
-#include <mach/utils.h>
-
-#define MAX_NB_GPIO_PER_BANK 32
-#define MAX_GPIO_BANKS 2
-
-struct oxnas_gpio_chip {
- struct gpio_chip chip;
- struct pinctrl_gpio_range range;
- void __iomem *regbase; /* GPIOA/B virtual address */
- void __iomem *ctrlbase; /* SYS/SEC_CTRL virtual address */
- struct irq_domain *domain; /* associated irq domain */
- spinlock_t lock;
-};
-
-#define to_oxnas_gpio_chip(c) container_of(c, struct oxnas_gpio_chip, chip)
-
-static struct oxnas_gpio_chip *gpio_chips[MAX_GPIO_BANKS];
-
-static int gpio_banks;
-
-#define PULL_UP (1 << 0)
-#define PULL_DOWN (1 << 1)
-#define DEBOUNCE (1 << 2)
-
-/**
- * struct oxnas_pmx_func - describes pinmux functions
- * @name: the name of this specific function
- * @groups: corresponding pin groups
- * @ngroups: the number of groups
- */
-struct oxnas_pmx_func {
- const char *name;
- const char **groups;
- unsigned ngroups;
-};
-
-enum oxnas_mux {
- OXNAS_PINMUX_GPIO,
- OXNAS_PINMUX_FUNC2,
- OXNAS_PINMUX_FUNC3,
- OXNAS_PINMUX_FUNC4,
- OXNAS_PINMUX_DEBUG,
- OXNAS_PINMUX_ALT,
-};
-
-enum {
- INPUT_VALUE = 0,
- OUTPUT_ENABLE = 4,
- IRQ_PENDING = 0xC,
- OUTPUT_VALUE = 0x10,
- OUTPUT_SET = 0x14,
- OUTPUT_CLEAR = 0x18,
- OUTPUT_EN_SET = 0x1C,
- OUTPUT_EN_CLEAR = 0x20,
- DEBOUNCE_ENABLE = 0x24,
- RE_IRQ_ENABLE = 0x28, /* rising edge */
- FE_IRQ_ENABLE = 0x2C, /* falling edge */
- RE_IRQ_PENDING = 0x30, /* rising edge */
- FE_IRQ_PENDING = 0x34, /* falling edge */
- CLOCK_DIV = 0x48,
- PULL_ENABLE = 0x50,
- PULL_SENSE = 0x54, /* 1 up, 0 down */
-
-
- DEBOUNCE_MASK = 0x3FFF0000,
- /* put hw debounce and soft config at same bit position*/
- DEBOUNCE_SHIFT = 16
-};
-
-enum {
- PINMUX_SECONDARY_SEL = 0x14,
- PINMUX_TERTIARY_SEL = 0x8c,
- PINMUX_QUATERNARY_SEL = 0x94,
- PINMUX_DEBUG_SEL = 0x9c,
- PINMUX_ALTERNATIVE_SEL = 0xa4,
- PINMUX_PULLUP_SEL = 0xac,
-};
-
-/**
- * struct oxnas_pmx_pin - describes an pin mux
- * @bank: the bank of the pin
- * @pin: the pin number in the @bank
- * @mux: the mux mode : gpio or periph_x of the pin i.e. alternate function.
- * @conf: the configuration of the pin: PULL_UP, MULTIDRIVE etc...
- */
-struct oxnas_pmx_pin {
- uint32_t bank;
- uint32_t pin;
- enum oxnas_mux mux;
- unsigned long conf;
-};
-
-/**
- * struct oxnas_pin_group - describes an pin group
- * @name: the name of this specific pin group
- * @pins_conf: the mux mode for each pin in this group. The size of this
- * array is the same as pins.
- * @pins: an array of discrete physical pins used in this group, taken
- * from the driver-local pin enumeration space
- * @npins: the number of pins in this group array, i.e. the number of
- * elements in .pins so we can iterate over that array
- */
-struct oxnas_pin_group {
- const char *name;
- struct oxnas_pmx_pin *pins_conf;
- unsigned int *pins;
- unsigned npins;
-};
-
-struct oxnas_pinctrl {
- struct device *dev;
- struct pinctrl_dev *pctl;
-
- int nbanks;
-
- uint32_t *mux_mask;
- int nmux;
-
- struct oxnas_pmx_func *functions;
- int nfunctions;
-
- struct oxnas_pin_group *groups;
- int ngroups;
-};
-
-static const inline struct oxnas_pin_group *oxnas_pinctrl_find_group_by_name(
- const struct oxnas_pinctrl *info,
- const char *name)
-{
- const struct oxnas_pin_group *grp = NULL;
- int i;
-
- for (i = 0; i < info->ngroups; i++) {
- if (strcmp(info->groups[i].name, name))
- continue;
-
- grp = &info->groups[i];
- dev_dbg(info->dev, "%s: %d 0:%d\n", name, grp->npins,
- grp->pins[0]);
- break;
- }
-
- return grp;
-}
-
-static int oxnas_get_groups_count(struct pinctrl_dev *pctldev)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->ngroups;
-}
-
-static const char *oxnas_get_group_name(struct pinctrl_dev *pctldev,
- unsigned selector)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->groups[selector].name;
-}
-
-static int oxnas_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
- const unsigned **pins,
- unsigned *npins)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- if (selector >= info->ngroups)
- return -EINVAL;
-
- *pins = info->groups[selector].pins;
- *npins = info->groups[selector].npins;
-
- return 0;
-}
-
-static void oxnas_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
- unsigned offset)
-{
- seq_printf(s, "%s", dev_name(pctldev->dev));
-}
-
-static int oxnas_dt_node_to_map(struct pinctrl_dev *pctldev,
- struct device_node *np,
- struct pinctrl_map **map, unsigned *num_maps)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct oxnas_pin_group *grp;
- struct pinctrl_map *new_map;
- struct device_node *parent;
- int map_num = 1;
- int i;
-
- /*
- * first find the group of this node and check if we need create
- * config maps for pins
- */
- grp = oxnas_pinctrl_find_group_by_name(info, np->name);
- if (!grp) {
- dev_err(info->dev, "unable to find group for node %s\n",
- np->name);
- return -EINVAL;
- }
-
- map_num += grp->npins;
- new_map = devm_kzalloc(pctldev->dev, sizeof(*new_map) * map_num,
- GFP_KERNEL);
- if (!new_map)
- return -ENOMEM;
-
- *map = new_map;
- *num_maps = map_num;
-
- /* create mux map */
- parent = of_get_parent(np);
- if (!parent) {
- devm_kfree(pctldev->dev, new_map);
- return -EINVAL;
- }
- new_map[0].type = PIN_MAP_TYPE_MUX_GROUP;
- new_map[0].data.mux.function = parent->name;
- new_map[0].data.mux.group = np->name;
- of_node_put(parent);
-
- /* create config map */
- new_map++;
- for (i = 0; i < grp->npins; i++) {
- new_map[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
- new_map[i].data.configs.group_or_pin =
- pin_get_name(pctldev, grp->pins[i]);
- new_map[i].data.configs.configs = &grp->pins_conf[i].conf;
- new_map[i].data.configs.num_configs = 1;
- }
-
- dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n",
- (*map)->data.mux.function, (*map)->data.mux.group, map_num);
-
- return 0;
-}
-
-static void oxnas_dt_free_map(struct pinctrl_dev *pctldev,
- struct pinctrl_map *map, unsigned num_maps)
-{
-}
-
-static const struct pinctrl_ops oxnas_pctrl_ops = {
- .get_groups_count = oxnas_get_groups_count,
- .get_group_name = oxnas_get_group_name,
- .get_group_pins = oxnas_get_group_pins,
- .pin_dbg_show = oxnas_pin_dbg_show,
- .dt_node_to_map = oxnas_dt_node_to_map,
- .dt_free_map = oxnas_dt_free_map,
-};
-
-static void __iomem *pin_to_gpioctrl(struct oxnas_pinctrl *info,
- unsigned int bank)
-{
- return gpio_chips[bank]->regbase;
-}
-
-static void __iomem *pin_to_muxctrl(struct oxnas_pinctrl *info,
- unsigned int bank)
-{
- return gpio_chips[bank]->ctrlbase;
-}
-
-
-static inline int pin_to_bank(unsigned pin)
-{
- return pin / MAX_NB_GPIO_PER_BANK;
-}
-
-static unsigned pin_to_mask(unsigned int pin)
-{
- return 1 << pin;
-}
-
-static void oxnas_mux_disable_interrupt(void __iomem *pio, unsigned mask)
-{
- oxnas_register_clear_mask(pio + RE_IRQ_ENABLE, mask);
- oxnas_register_clear_mask(pio + FE_IRQ_ENABLE, mask);
-}
-
-static unsigned oxnas_mux_get_pullup(void __iomem *pio, unsigned pin)
-{
- return (readl_relaxed(pio + PULL_ENABLE) & BIT(pin)) &&
- (readl_relaxed(pio + PULL_SENSE) & BIT(pin));
-}
-
-static void oxnas_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
-{
- if (on) {
- oxnas_register_set_mask(pio + PULL_SENSE, mask);
- oxnas_register_set_mask(pio + PULL_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + PULL_ENABLE, mask);
- }
-}
-
-static bool oxnas_mux_get_pulldown(void __iomem *pio, unsigned pin)
-{
- return (readl_relaxed(pio + PULL_ENABLE) & BIT(pin)) &&
- (!(readl_relaxed(pio + PULL_SENSE) & BIT(pin)));
-}
-
-static void oxnas_mux_set_pulldown(void __iomem *pio, unsigned mask, bool on)
-{
- if (on) {
- oxnas_register_clear_mask(pio + PULL_SENSE, mask);
- oxnas_register_set_mask(pio + PULL_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + PULL_ENABLE, mask);
- };
-}
-
-/* unfortunately debounce control are shared */
-static bool oxnas_mux_get_debounce(void __iomem *pio, unsigned pin, u32 *div)
-{
- *div = __raw_readl(pio + CLOCK_DIV) & DEBOUNCE_MASK;
- return __raw_readl(pio + DEBOUNCE_ENABLE) & BIT(pin);
-}
-
-static void oxnas_mux_set_debounce(void __iomem *pio, unsigned mask,
- bool is_on, u32 div)
-{
- if (is_on) {
- oxnas_register_value_mask(pio + CLOCK_DIV, DEBOUNCE_MASK, div);
- oxnas_register_set_mask(pio + DEBOUNCE_ENABLE, mask);
- } else {
- oxnas_register_clear_mask(pio + DEBOUNCE_ENABLE, mask);
- }
-}
-
-
-static void oxnas_mux_set_func2(void __iomem *cio, unsigned mask)
-{
-/* in fact, SECONDARY takes precedence, so clear others is not necessary */
- oxnas_register_set_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func3(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func4(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func_dbg(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_func_alt(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_set_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static void oxnas_mux_set_gpio(void __iomem *cio, unsigned mask)
-{
- oxnas_register_clear_mask(cio + PINMUX_SECONDARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_TERTIARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_QUATERNARY_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_DEBUG_SEL, mask);
- oxnas_register_clear_mask(cio + PINMUX_ALTERNATIVE_SEL, mask);
-}
-
-static enum oxnas_mux oxnas_mux_get_func(void __iomem *cio, unsigned mask)
-{
- if (readl_relaxed(cio + PINMUX_SECONDARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC2;
- if (readl_relaxed(cio + PINMUX_TERTIARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC3;
- if (readl_relaxed(cio + PINMUX_QUATERNARY_SEL) & mask)
- return OXNAS_PINMUX_FUNC4;
- if (readl_relaxed(cio + PINMUX_DEBUG_SEL) & mask)
- return OXNAS_PINMUX_DEBUG;
- if (readl_relaxed(cio + PINMUX_ALTERNATIVE_SEL) & mask)
- return OXNAS_PINMUX_ALT;
- return OXNAS_PINMUX_GPIO;
-}
-
-
-static void oxnas_pin_dbg(const struct device *dev,
- const struct oxnas_pmx_pin *pin)
-{
- if (pin->mux) {
- dev_dbg(dev,
- "MF_%c%d configured as periph%c with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->mux - 1 + 'A',
- pin->conf);
- } else {
- dev_dbg(dev, "MF_%c%d configured as gpio with conf = 0x%lu\n",
- pin->bank + 'A', pin->pin, pin->conf);
- }
-}
-
-static int pin_check_config(struct oxnas_pinctrl *info, const char *name,
- int index, const struct oxnas_pmx_pin *pin)
-{
- int mux;
-
- /* check if it's a valid config */
- if (pin->bank >= info->nbanks) {
- dev_err(info->dev, "%s: pin conf %d bank_id %d >= nbanks %d\n",
- name, index, pin->bank, info->nbanks);
- return -EINVAL;
- }
-
- if (pin->pin >= MAX_NB_GPIO_PER_BANK) {
- dev_err(info->dev, "%s: pin conf %d pin_bank_id %d >= %d\n",
- name, index, pin->pin, MAX_NB_GPIO_PER_BANK);
- return -EINVAL;
- }
- /* gpio always allowed */
- if (!pin->mux)
- return 0;
-
- mux = pin->mux - 1;
-
- if (mux >= info->nmux) {
- dev_err(info->dev, "%s: pin conf %d mux_id %d >= nmux %d\n",
- name, index, mux, info->nmux);
- return -EINVAL;
- }
-
- if (!(info->mux_mask[pin->bank * info->nmux + mux] & 1 << pin->pin)) {
- dev_err(info->dev, "%s: pin conf %d mux_id %d not supported for MF_%c%d\n",
- name, index, mux, pin->bank + 'A', pin->pin);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void oxnas_mux_gpio_enable(void __iomem *cio, void __iomem *pio,
- unsigned mask, bool input)
-{
- oxnas_mux_set_gpio(cio, mask);
- if (input)
- writel_relaxed(mask, pio + OUTPUT_EN_CLEAR);
- else
- writel_relaxed(mask, pio + OUTPUT_EN_SET);
-}
-
-static void oxnas_mux_gpio_disable(void __iomem *cio, void __iomem *pio,
- unsigned mask)
-{
- /* when switch to other function, gpio is disabled automatically */
- return;
-}
-
-static int oxnas_pmx_set_mux(struct pinctrl_dev *pctldev, unsigned selector,
- unsigned group)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- const struct oxnas_pmx_pin *pins_conf = info->groups[group].pins_conf;
- const struct oxnas_pmx_pin *pin;
- uint32_t npins = info->groups[group].npins;
- int i, ret;
- unsigned mask;
- void __iomem *pio;
- void __iomem *cio;
-
- dev_dbg(info->dev, "enable function %s group %s\n",
- info->functions[selector].name, info->groups[group].name);
-
- /* first check that all the pins of the group are valid with a valid
- * paramter */
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- ret = pin_check_config(info, info->groups[group].name, i, pin);
- if (ret)
- return ret;
- }
-
- for (i = 0; i < npins; i++) {
- pin = &pins_conf[i];
- oxnas_pin_dbg(info->dev, pin);
-
- pio = pin_to_gpioctrl(info, pin->bank);
- cio = pin_to_muxctrl(info, pin->bank);
-
- mask = pin_to_mask(pin->pin);
- oxnas_mux_disable_interrupt(pio, mask);
-
- switch (pin->mux) {
- case OXNAS_PINMUX_GPIO:
- oxnas_mux_gpio_enable(cio, pio, mask, 1);
- break;
- case OXNAS_PINMUX_FUNC2:
- oxnas_mux_set_func2(cio, mask);
- break;
- case OXNAS_PINMUX_FUNC3:
- oxnas_mux_set_func3(cio, mask);
- break;
- case OXNAS_PINMUX_FUNC4:
- oxnas_mux_set_func4(cio, mask);
- break;
- case OXNAS_PINMUX_DEBUG:
- oxnas_mux_set_func_dbg(cio, mask);
- break;
- case OXNAS_PINMUX_ALT:
- oxnas_mux_set_func_alt(cio, mask);
- break;
- }
- if (pin->mux)
- oxnas_mux_gpio_disable(cio, pio, mask);
- }
-
- return 0;
-}
-
-static int oxnas_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->nfunctions;
-}
-
-static const char *oxnas_pmx_get_func_name(struct pinctrl_dev *pctldev,
- unsigned selector)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- return info->functions[selector].name;
-}
-
-static int oxnas_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector,
- const char * const **groups,
- unsigned * const num_groups)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
-
- *groups = info->functions[selector].groups;
- *num_groups = info->functions[selector].ngroups;
-
- return 0;
-}
-
-static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
-{
- struct oxnas_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
- struct oxnas_gpio_chip *oxnas_chip;
- struct gpio_chip *chip;
- unsigned mask;
-
- if (!range) {
- dev_err(npct->dev, "invalid range\n");
- return -EINVAL;
- }
- if (!range->gc) {
- dev_err(npct->dev, "missing GPIO chip in range\n");
- return -EINVAL;
- }
- chip = range->gc;
- oxnas_chip = container_of(chip, struct oxnas_gpio_chip, chip);
-
- dev_dbg(npct->dev, "enable pin %u as GPIO\n", offset);
-
- mask = 1 << (offset - chip->base);
-
- dev_dbg(npct->dev, "enable pin %u as MF_%c%d 0x%x\n",
- offset, 'A' + range->id, offset - chip->base, mask);
-
- oxnas_mux_set_gpio(oxnas_chip->ctrlbase, mask);
-
- return 0;
-}
-
-static void oxnas_gpio_disable_free(struct pinctrl_dev *pctldev,
- struct pinctrl_gpio_range *range,
- unsigned offset)
-{
- struct oxnas_pinctrl *npct = pinctrl_dev_get_drvdata(pctldev);
-
- dev_dbg(npct->dev, "disable pin %u as GPIO\n", offset);
- /* Set the pin to some default state, GPIO is usually default */
-}
-
-static const struct pinmux_ops oxnas_pmx_ops = {
- .get_functions_count = oxnas_pmx_get_funcs_count,
- .get_function_name = oxnas_pmx_get_func_name,
- .get_function_groups = oxnas_pmx_get_groups,
- .set_mux = oxnas_pmx_set_mux,
- .gpio_request_enable = oxnas_gpio_request_enable,
- .gpio_disable_free = oxnas_gpio_disable_free,
-};
-
-static int oxnas_pinconf_get(struct pinctrl_dev *pctldev,
- unsigned pin_id, unsigned long *config)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- void __iomem *pio;
- unsigned pin;
- int div;
-
- dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__,
- __LINE__, pin_id, *config);
- pio = pin_to_gpioctrl(info, pin_to_bank(pin_id));
- pin = pin_id % MAX_NB_GPIO_PER_BANK;
-
- if (oxnas_mux_get_pullup(pio, pin))
- *config |= PULL_UP;
-
- if (oxnas_mux_get_pulldown(pio, pin))
- *config |= PULL_DOWN;
-
- if (oxnas_mux_get_debounce(pio, pin, &div))
- *config |= DEBOUNCE | div;
- return 0;
-}
-
-static int oxnas_pinconf_set(struct pinctrl_dev *pctldev,
- unsigned pin_id, unsigned long *configs,
- unsigned num_configs)
-{
- struct oxnas_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
- unsigned mask;
- void __iomem *pio;
- int i;
- unsigned long config;
-
- pio = pin_to_gpioctrl(info, pin_to_bank(pin_id));
- mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
-
- for (i = 0; i < num_configs; i++) {
- config = configs[i];
-
- dev_dbg(info->dev,
- "%s:%d, pin_id=%d, config=0x%lx",
- __func__, __LINE__, pin_id, config);
-
- if ((config & PULL_UP) && (config & PULL_DOWN))
- return -EINVAL;
-
- oxnas_mux_set_pullup(pio, mask, config & PULL_UP);
- oxnas_mux_set_pulldown(pio, mask, config & PULL_DOWN);
- oxnas_mux_set_debounce(pio, mask, config & DEBOUNCE,
- config & DEBOUNCE_MASK);
-
- } /* for each config */
-
- return 0;
-}
-
-static void oxnas_pinconf_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned pin_id)
-{
-
-}
-
-static void oxnas_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s, unsigned group)
-{
-}
-
-static const struct pinconf_ops oxnas_pinconf_ops = {
- .pin_config_get = oxnas_pinconf_get,
- .pin_config_set = oxnas_pinconf_set,
- .pin_config_dbg_show = oxnas_pinconf_dbg_show,
- .pin_config_group_dbg_show = oxnas_pinconf_group_dbg_show,
-};
-
-static struct pinctrl_desc oxnas_pinctrl_desc = {
- .pctlops = &oxnas_pctrl_ops,
- .pmxops = &oxnas_pmx_ops,
- .confops = &oxnas_pinconf_ops,
- .owner = THIS_MODULE,
-};
-
-static const char *gpio_compat = "plxtech,nas782x-gpio";
-
-static void oxnas_pinctrl_child_count(struct oxnas_pinctrl *info,
- struct device_node *np)
-{
- struct device_node *child;
-
- for_each_child_of_node(np, child) {
- if (of_device_is_compatible(child, gpio_compat)) {
- info->nbanks++;
- } else {
- info->nfunctions++;
- info->ngroups += of_get_child_count(child);
- }
- }
-}
-
-static int oxnas_pinctrl_mux_mask(struct oxnas_pinctrl *info,
- struct device_node *np)
-{
- int ret = 0;
- int size;
- const __be32 *list;
-
- list = of_get_property(np, "plxtech,mux-mask", &size);
- if (!list) {
- dev_err(info->dev, "can not read the mux-mask of %d\n", size);
- return -EINVAL;
- }
-
- size /= sizeof(*list);
- if (!size || size % info->nbanks) {
- dev_err(info->dev, "wrong mux mask array should be by %d\n",
- info->nbanks);
- return -EINVAL;
- }
- info->nmux = size / info->nbanks;
-
- info->mux_mask = devm_kzalloc(info->dev, sizeof(u32) * size, GFP_KERNEL);
- if (!info->mux_mask) {
- dev_err(info->dev, "could not alloc mux_mask\n");
- return -ENOMEM;
- }
-
- ret = of_property_read_u32_array(np, "plxtech,mux-mask",
- info->mux_mask, size);
- if (ret)
- dev_err(info->dev, "can not read the mux-mask of %d\n", size);
- return ret;
-}
-
-static int oxnas_pinctrl_parse_groups(struct device_node *np,
- struct oxnas_pin_group *grp,
- struct oxnas_pinctrl *info, u32 index)
-{
- struct oxnas_pmx_pin *pin;
- int size;
- const __be32 *list;
- int i, j;
-
- dev_dbg(info->dev, "group(%d): %s\n", index, np->name);
-
- /* Initialise group */
- grp->name = np->name;
-
- /*
- * the binding format is plxtech,pins = <bank pin mux CONFIG ...>,
- * do sanity check and calculate pins number
- */
- list = of_get_property(np, "plxtech,pins", &size);
- /* we do not check return since it's safe node passed down */
- size /= sizeof(*list);
- if (!size || size % 4) {
- dev_err(info->dev, "wrong pins number or pins and configs"
- " should be divisible by 4\n");
- return -EINVAL;
- }
-
- grp->npins = size / 4;
- pin = grp->pins_conf = devm_kzalloc(info->dev,
- grp->npins * sizeof(struct oxnas_pmx_pin),
- GFP_KERNEL);
- grp->pins = devm_kzalloc(info->dev, grp->npins * sizeof(unsigned int),
- GFP_KERNEL);
- if (!grp->pins_conf || !grp->pins)
- return -ENOMEM;
-
- for (i = 0, j = 0; i < size; i += 4, j++) {
- pin->bank = be32_to_cpu(*list++);
- pin->pin = be32_to_cpu(*list++);
- grp->pins[j] = pin->bank * MAX_NB_GPIO_PER_BANK + pin->pin;
- pin->mux = be32_to_cpu(*list++);
- pin->conf = be32_to_cpu(*list++);
-
- oxnas_pin_dbg(info->dev, pin);
- pin++;
- }
-
- return 0;
-}
-
-static int oxnas_pinctrl_parse_functions(struct device_node *np,
- struct oxnas_pinctrl *info, u32 index)
-{
- struct device_node *child;
- struct oxnas_pmx_func *func;
- struct oxnas_pin_group *grp;
- int ret;
- static u32 grp_index;
- u32 i = 0;
-
- dev_dbg(info->dev, "parse function(%d): %s\n", index, np->name);
-
- func = &info->functions[index];
-
- /* Initialise function */
- func->name = np->name;
- func->ngroups = of_get_child_count(np);
- if (func->ngroups <= 0) {
- dev_err(info->dev, "no groups defined\n");
- return -EINVAL;
- }
- func->groups = devm_kzalloc(info->dev,
- func->ngroups * sizeof(char *), GFP_KERNEL);
- if (!func->groups)
- return -ENOMEM;
-
- for_each_child_of_node(np, child) {
- func->groups[i] = child->name;
- grp = &info->groups[grp_index++];
- ret = oxnas_pinctrl_parse_groups(child, grp, info, i++);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static struct of_device_id oxnas_pinctrl_of_match[] = {
- { .compatible = "plxtech,nas782x-pinctrl"},
- { /* sentinel */ }
-};
-
-static int oxnas_pinctrl_probe_dt(struct platform_device *pdev,
- struct oxnas_pinctrl *info)
-{
- int ret = 0;
- int i, j;
- uint32_t *tmp;
- struct device_node *np = pdev->dev.of_node;
- struct device_node *child;
-
- if (!np)
- return -ENODEV;
-
- info->dev = &pdev->dev;
-
- oxnas_pinctrl_child_count(info, np);
-
- if (info->nbanks < 1) {
- dev_err(&pdev->dev, "you need to specify atleast one gpio-controller\n");
- return -EINVAL;
- }
-
- ret = oxnas_pinctrl_mux_mask(info, np);
- if (ret)
- return ret;
-
- dev_dbg(&pdev->dev, "nmux = %d\n", info->nmux);
-
- dev_dbg(&pdev->dev, "mux-mask\n");
- tmp = info->mux_mask;
- for (i = 0; i < info->nbanks; i++)
- for (j = 0; j < info->nmux; j++, tmp++)
- dev_dbg(&pdev->dev, "%d:%d\t0x%x\n", i, j, tmp[0]);
-
- dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
- dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
- info->functions = devm_kzalloc(&pdev->dev, info->nfunctions *
- sizeof(struct oxnas_pmx_func),
- GFP_KERNEL);
- if (!info->functions)
- return -ENOMEM;
-
- info->groups = devm_kzalloc(&pdev->dev, info->ngroups *
- sizeof(struct oxnas_pin_group),
- GFP_KERNEL);
- if (!info->groups)
- return -ENOMEM;
-
- dev_dbg(&pdev->dev, "nbanks = %d\n", info->nbanks);
- dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions);
- dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups);
-
- i = 0;
-
- for_each_child_of_node(np, child) {
- if (of_device_is_compatible(child, gpio_compat))
- continue;
- ret = oxnas_pinctrl_parse_functions(child, info, i++);
- if (ret) {
- dev_err(&pdev->dev, "failed to parse function\n");
- return ret;
- }
- }
-
- return 0;
-}
-
-static int oxnas_pinctrl_probe(struct platform_device *pdev)
-{
- struct oxnas_pinctrl *info;
- struct pinctrl_pin_desc *pdesc;
- int ret, i, j, k;
-
- info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- ret = oxnas_pinctrl_probe_dt(pdev, info);
- if (ret)
- return ret;
-
- /*
- * We need all the GPIO drivers to probe FIRST, or we will not be able
- * to obtain references to the struct gpio_chip * for them, and we
- * need this to proceed.
- */
- for (i = 0; i < info->nbanks; i++) {
- if (!gpio_chips[i]) {
- dev_warn(&pdev->dev,
- "GPIO chip %d not registered yet\n", i);
- devm_kfree(&pdev->dev, info);
- return -EPROBE_DEFER;
- }
- }
-
- oxnas_pinctrl_desc.name = dev_name(&pdev->dev);
- oxnas_pinctrl_desc.npins = info->nbanks * MAX_NB_GPIO_PER_BANK;
- oxnas_pinctrl_desc.pins = pdesc =
- devm_kzalloc(&pdev->dev, sizeof(*pdesc) *
- oxnas_pinctrl_desc.npins, GFP_KERNEL);
-
- if (!oxnas_pinctrl_desc.pins)
- return -ENOMEM;
-
- for (i = 0 , k = 0; i < info->nbanks; i++) {
- for (j = 0; j < MAX_NB_GPIO_PER_BANK; j++, k++) {
- pdesc->number = k;
- pdesc->name = kasprintf(GFP_KERNEL, "MF_%c%d", i + 'A',
- j);
- pdesc++;
- }
- }
-
- platform_set_drvdata(pdev, info);
- info->pctl = pinctrl_register(&oxnas_pinctrl_desc, &pdev->dev, info);
-
- if (!info->pctl) {
- dev_err(&pdev->dev, "could not register OX820 pinctrl driver\n");
- ret = -EINVAL;
- goto err;
- }
-
- /* We will handle a range of GPIO pins */
- for (i = 0; i < info->nbanks; i++)
- pinctrl_add_gpio_range(info->pctl, &gpio_chips[i]->range);
-
- dev_info(&pdev->dev, "initialized OX820 pinctrl driver\n");
-
- return 0;
-
-err:
- return ret;
-}
-
-static int oxnas_pinctrl_remove(struct platform_device *pdev)
-{
- struct oxnas_pinctrl *info = platform_get_drvdata(pdev);
-
- pinctrl_unregister(info->pctl);
-
- return 0;
-}
-
-static int oxnas_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
- /*
- * Map back to global GPIO space and request muxing, the direction
- * parameter does not matter for this controller.
- */
- int gpio = chip->base + offset;
- int bank = chip->base / chip->ngpio;
-
- dev_dbg(chip->dev, "%s:%d MF_%c%d(%d)\n", __func__, __LINE__,
- 'A' + bank, offset, gpio);
-
- return pinctrl_request_gpio(gpio);
-}
-
-static void oxnas_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
- int gpio = chip->base + offset;
-
- pinctrl_free_gpio(gpio);
-}
-
-static int oxnas_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- writel_relaxed(BIT(offset), pio + OUTPUT_EN_CLEAR);
- return 0;
-}
-
-static int oxnas_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << offset;
- u32 pdsr;
-
- pdsr = readl_relaxed(pio + INPUT_VALUE);
- return (pdsr & mask) != 0;
-}
-
-static void oxnas_gpio_set(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- if (val)
- writel_relaxed(BIT(offset), pio + OUTPUT_SET);
- else
- writel_relaxed(BIT(offset), pio + OUTPUT_CLEAR);
-
-}
-
-static int oxnas_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
-
- if (val)
- writel_relaxed(BIT(offset), pio + OUTPUT_SET);
- else
- writel_relaxed(BIT(offset), pio + OUTPUT_CLEAR);
-
- writel_relaxed(BIT(offset), pio + OUTPUT_EN_SET);
-
- return 0;
-}
-
-static int oxnas_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- int virq;
-
- if (offset < chip->ngpio)
- virq = irq_create_mapping(oxnas_gpio->domain, offset);
- else
- virq = -ENXIO;
-
- dev_dbg(chip->dev, "%s: request IRQ for GPIO %d, return %d\n",
- chip->label, offset + chip->base, virq);
- return virq;
-}
-
-#ifdef CONFIG_DEBUG_FS
-static void oxnas_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
- enum oxnas_mux mode;
- int i;
- struct oxnas_gpio_chip *oxnas_gpio = to_oxnas_gpio_chip(chip);
- void __iomem *pio = oxnas_gpio->regbase;
- void __iomem *cio = oxnas_gpio->ctrlbase;
-
- for (i = 0; i < chip->ngpio; i++) {
- unsigned pin = chip->base + i;
- unsigned mask = pin_to_mask(pin);
- const char *gpio_label;
- u32 pdsr;
-
- gpio_label = gpiochip_is_requested(chip, i);
- if (!gpio_label)
- continue;
- /* FIXME */
- mode = oxnas_mux_get_func(cio, mask);
- seq_printf(s, "[%s] GPIO%s%d: ",
- gpio_label, chip->label, i);
- if (mode == OXNAS_PINMUX_GPIO) {
- pdsr = readl_relaxed(pio + INPUT_VALUE);
-
- seq_printf(s, "[gpio] %s\n",
- pdsr & mask ?
- "set" : "clear");
- } else {
- seq_printf(s, "[periph %c]\n",
- mode + 'A' - 1);
- }
- }
-}
-#else
-#define oxnas_gpio_dbg_show NULL
-#endif
-
-/* Several AIC controller irqs are dispatched through this GPIO handler.
- * To use any AT91_PIN_* as an externally triggered IRQ, first call
- * oxnas_set_gpio_input() then maybe enable its glitch filter.
- * Then just request_irq() with the pin ID; it works like any ARM IRQ
- * handler.
- */
-
-static void gpio_irq_mask(struct irq_data *d)
-{
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(d);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << d->hwirq;
- unsigned type = irqd_get_trigger_type(d);
- unsigned long flags;
-
- if (!(type & IRQ_TYPE_EDGE_BOTH))
- return;
-
- spin_lock_irqsave(&oxnas_gpio->lock, flags);
- if (type & IRQ_TYPE_EDGE_RISING)
- oxnas_register_clear_mask(pio + RE_IRQ_ENABLE, mask);
- if (type & IRQ_TYPE_EDGE_FALLING)
- oxnas_register_clear_mask(pio + FE_IRQ_ENABLE, mask);
- spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
-}
-
-static void gpio_irq_unmask(struct irq_data *d)
-{
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(d);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned mask = 1 << d->hwirq;
- unsigned type = irqd_get_trigger_type(d);
- unsigned long flags;
-
- if (!(type & IRQ_TYPE_EDGE_BOTH))
- return;
-
- spin_lock_irqsave(&oxnas_gpio->lock, flags);
- if (type & IRQ_TYPE_EDGE_RISING)
- oxnas_register_set_mask(pio + RE_IRQ_ENABLE, mask);
- if (type & IRQ_TYPE_EDGE_FALLING)
- oxnas_register_set_mask(pio + FE_IRQ_ENABLE, mask);
- spin_unlock_irqrestore(&oxnas_gpio->lock, flags);
-}
-
-
-static int gpio_irq_type(struct irq_data *d, unsigned type)
-{
- if ((type & IRQ_TYPE_EDGE_BOTH) == 0) {
- pr_warn("OX820: Unsupported type for irq %d\n",
- gpio_to_irq(d->irq));
- return -EINVAL;
- }
- /* seems no way to set trigger type without enable irq, so leave it to unmask time */
-
- return 0;
-}
-
-static struct irq_chip gpio_irqchip = {
- .name = "GPIO",
- .irq_disable = gpio_irq_mask,
- .irq_mask = gpio_irq_mask,
- .irq_unmask = gpio_irq_unmask,
- .irq_set_type = gpio_irq_type,
-};
-
-static void gpio_irq_handler(struct irq_desc *desc)
-{
- struct irq_chip *chip = irq_desc_get_chip(desc);
- struct irq_data *idata = irq_desc_get_irq_data(desc);
- struct oxnas_gpio_chip *oxnas_gpio = irq_data_get_irq_chip_data(idata);
- void __iomem *pio = oxnas_gpio->regbase;
- unsigned long isr;
- int n;
-
- chained_irq_enter(chip, desc);
- for (;;) {
- /* TODO: see if it works */
- isr = readl_relaxed(pio + IRQ_PENDING);
- if (!isr)
- break;
- /* acks pending interrupts */
- writel_relaxed(isr, pio + IRQ_PENDING);
-
- for_each_set_bit(n, &isr, BITS_PER_LONG) {
- generic_handle_irq(irq_find_mapping(oxnas_gpio->domain,
- n));
- }
- }
- chained_irq_exit(chip, desc);
- /* now it may re-trigger */
-}
-
-/*
- * This lock class tells lockdep that GPIO irqs are in a different
- * category than their parents, so it won't report false recursion.
- */
-static struct lock_class_key gpio_lock_class;
-
-static int oxnas_gpio_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct oxnas_gpio_chip *oxnas_gpio = h->host_data;
-
- irq_set_lockdep_class(virq, &gpio_lock_class);
-
- irq_set_chip_and_handler(virq, &gpio_irqchip, handle_edge_irq);
- irq_set_chip_data(virq, oxnas_gpio);
-
- return 0;
-}
-
-static int oxnas_gpio_irq_domain_xlate(struct irq_domain *d,
- struct device_node *ctrlr,
- const u32 *intspec,
- unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_type)
-{
- struct oxnas_gpio_chip *oxnas_gpio = d->host_data;
- int ret;
- int pin = oxnas_gpio->chip.base + intspec[0];
-
- if (WARN_ON(intsize < 2))
- return -EINVAL;
- *out_hwirq = intspec[0];
- *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
-
- ret = gpio_request(pin, ctrlr->full_name);
- if (ret)
- return ret;
-
- ret = gpio_direction_input(pin);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static struct irq_domain_ops oxnas_gpio_ops = {
- .map = oxnas_gpio_irq_map,
- .xlate = oxnas_gpio_irq_domain_xlate,
-};
-
-static int oxnas_gpio_of_irq_setup(struct device_node *node,
- struct oxnas_gpio_chip *oxnas_gpio,
- unsigned int irq)
-{
- /* Disable irqs of this controller */
- writel_relaxed(0, oxnas_gpio->regbase + RE_IRQ_ENABLE);
- writel_relaxed(0, oxnas_gpio->regbase + FE_IRQ_ENABLE);
-
- /* Setup irq domain */
- oxnas_gpio->domain = irq_domain_add_linear(node, oxnas_gpio->chip.ngpio,
- &oxnas_gpio_ops, oxnas_gpio);
- if (!oxnas_gpio->domain)
- panic("oxnas_gpio: couldn't allocate irq domain (DT).\n");
-
- irq_set_chip_data(irq, oxnas_gpio);
- irq_set_chained_handler(irq, gpio_irq_handler);
-
- return 0;
-}
-
-/* This structure is replicated for each GPIO block allocated at probe time */
-static struct gpio_chip oxnas_gpio_template = {
- .request = oxnas_gpio_request,
- .free = oxnas_gpio_free,
- .direction_input = oxnas_gpio_direction_input,
- .get = oxnas_gpio_get,
- .direction_output = oxnas_gpio_direction_output,
- .set = oxnas_gpio_set,
- .to_irq = oxnas_gpio_to_irq,
- .dbg_show = oxnas_gpio_dbg_show,
- .can_sleep = 0,
- .ngpio = MAX_NB_GPIO_PER_BANK,
-};
-
-static struct of_device_id oxnas_gpio_of_match[] = {
- { .compatible = "plxtech,nas782x-gpio"},
- { /* sentinel */ }
-};
-
-static int oxnas_gpio_probe(struct platform_device *pdev)
-{
- struct device_node *np = pdev->dev.of_node;
- struct resource *res;
- struct oxnas_gpio_chip *oxnas_chip = NULL;
- struct gpio_chip *chip;
- struct pinctrl_gpio_range *range;
- int ret = 0;
- int irq, i;
- int alias_idx = of_alias_get_id(np, "gpio");
- uint32_t ngpio;
- char **names;
-
- BUG_ON(alias_idx >= ARRAY_SIZE(gpio_chips));
- if (gpio_chips[alias_idx]) {
- ret = -EBUSY;
- goto err;
- }
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto err;
- }
-
- oxnas_chip = devm_kzalloc(&pdev->dev, sizeof(*oxnas_chip), GFP_KERNEL);
- if (!oxnas_chip) {
- ret = -ENOMEM;
- goto err;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- oxnas_chip->regbase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas_chip->regbase)) {
- ret = PTR_ERR(oxnas_chip->regbase);
- goto err;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- oxnas_chip->ctrlbase = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(oxnas_chip->ctrlbase)) {
- ret = PTR_ERR(oxnas_chip->ctrlbase);
- goto err;
- }
-
- oxnas_chip->chip = oxnas_gpio_template;
-
- spin_lock_init(&oxnas_chip->lock);
-
- chip = &oxnas_chip->chip;
- chip->of_node = np;
- chip->label = dev_name(&pdev->dev);
- chip->dev = &pdev->dev;
- chip->owner = THIS_MODULE;
- chip->base = alias_idx * MAX_NB_GPIO_PER_BANK;
-
- if (!of_property_read_u32(np, "#gpio-lines", &ngpio)) {
- if (ngpio > MAX_NB_GPIO_PER_BANK)
- pr_err("oxnas_gpio.%d, gpio-nb >= %d failback to %d\n",
- alias_idx, MAX_NB_GPIO_PER_BANK,
- MAX_NB_GPIO_PER_BANK);
- else
- chip->ngpio = ngpio;
- }
-
- names = devm_kzalloc(&pdev->dev, sizeof(char *) * chip->ngpio,
- GFP_KERNEL);
-
- if (!names) {
- ret = -ENOMEM;
- goto err;
- }
-
- for (i = 0; i < chip->ngpio; i++)
- names[i] = kasprintf(GFP_KERNEL, "MF_%c%d", alias_idx + 'A', i);
-
- chip->names = (const char *const *)names;
-
- range = &oxnas_chip->range;
- range->name = chip->label;
- range->id = alias_idx;
- range->pin_base = range->base = range->id * MAX_NB_GPIO_PER_BANK;
-
- range->npins = chip->ngpio;
- range->gc = chip;
-
- ret = gpiochip_add(chip);
- if (ret)
- goto err;
-
- gpio_chips[alias_idx] = oxnas_chip;
- gpio_banks = max(gpio_banks, alias_idx + 1);
-
- oxnas_gpio_of_irq_setup(np, oxnas_chip, irq);
-
- dev_info(&pdev->dev, "at address %p\n", oxnas_chip->regbase);
-
- return 0;
-err:
- dev_err(&pdev->dev, "Failure %i for GPIO %i\n", ret, alias_idx);
-
- return ret;
-}
-
-static struct platform_driver oxnas_gpio_driver = {
- .driver = {
- .name = "gpio-oxnas",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(oxnas_gpio_of_match),
- },
- .probe = oxnas_gpio_probe,
-};
-
-static struct platform_driver oxnas_pinctrl_driver = {
- .driver = {
- .name = "pinctrl-oxnas",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(oxnas_pinctrl_of_match),
- },
- .probe = oxnas_pinctrl_probe,
- .remove = oxnas_pinctrl_remove,
-};
-
-static int __init oxnas_pinctrl_init(void)
-{
- int ret;
-
- ret = platform_driver_register(&oxnas_gpio_driver);
- if (ret)
- return ret;
- return platform_driver_register(&oxnas_pinctrl_driver);
-}
-arch_initcall(oxnas_pinctrl_init);
-
-static void __exit oxnas_pinctrl_exit(void)
-{
- platform_driver_unregister(&oxnas_pinctrl_driver);
-}
-
-module_exit(oxnas_pinctrl_exit);
-MODULE_AUTHOR("Ma Hajun <mahaijuns@gmail.com>");
-MODULE_DESCRIPTION("Plxtech Nas782x pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/target/linux/oxnas/files/drivers/reset/reset-ox820.c b/target/linux/oxnas/files/drivers/reset/reset-ox820.c
deleted file mode 100644
index 0a28de55f4..0000000000
--- a/target/linux/oxnas/files/drivers/reset/reset-ox820.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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 <linux/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/reset-controller.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <mach/hardware.h>
-
-static int ox820_reset_reset(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_SET_CTRL);
- writel(BIT(id), SYS_CTRL_RST_CLR_CTRL);
- return 0;
-}
-
-static int ox820_reset_assert(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_SET_CTRL);
-
- return 0;
-}
-
-static int ox820_reset_deassert(struct reset_controller_dev *rcdev,
- unsigned long id)
-{
- writel(BIT(id), SYS_CTRL_RST_CLR_CTRL);
-
- return 0;
-}
-
-static struct reset_control_ops ox820_reset_ops = {
- .reset = ox820_reset_reset,
- .assert = ox820_reset_assert,
- .deassert = ox820_reset_deassert,
-};
-
-static const struct of_device_id ox820_reset_dt_ids[] = {
- { .compatible = "plxtech,nas782x-reset", },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, ox820_reset_dt_ids);
-
-struct reset_controller_dev rcdev;
-
-static int ox820_reset_probe(struct platform_device *pdev)
-{
- struct reset_controller_dev *rcdev;
-
- rcdev = devm_kzalloc(&pdev->dev, sizeof(*rcdev), GFP_KERNEL);
- if (!rcdev)
- return -ENOMEM;
-
- /* note: reset controller is statically mapped */
-
- rcdev->owner = THIS_MODULE;
- rcdev->nr_resets = 32;
- rcdev->ops = &ox820_reset_ops;
- rcdev->of_node = pdev->dev.of_node;
- reset_controller_register(rcdev);
- platform_set_drvdata(pdev, rcdev);
-
- return 0;
-}
-
-static int ox820_reset_remove(struct platform_device *pdev)
-{
- struct reset_controller_dev *rcdev = platform_get_drvdata(pdev);
-
- reset_controller_unregister(rcdev);
-
- return 0;
-}
-
-static struct platform_driver ox820_reset_driver = {
- .probe = ox820_reset_probe,
- .remove = ox820_reset_remove,
- .driver = {
- .name = "ox820-reset",
- .owner = THIS_MODULE,
- .of_match_table = ox820_reset_dt_ids,
- },
-};
-
-static int __init ox820_reset_init(void)
-{
- return platform_driver_probe(&ox820_reset_driver,
- ox820_reset_probe);
-}
-/*
- * reset controller does not support probe deferral, so it has to be
- * initialized before any user, in particular, PCIE uses subsys_initcall.
- */
-arch_initcall(ox820_reset_init);
-
-MODULE_AUTHOR("Ma Haijun");
-MODULE_LICENSE("GPL");
diff --git a/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c b/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
index 15578a3027..79c4fa3a95 100644
--- a/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
+++ b/target/linux/oxnas/files/drivers/usb/host/ehci-oxnas.c
@@ -14,13 +14,59 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
+#include <linux/mfd/syscon.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
+#include <linux/regmap.h>
#include <linux/reset.h>
-#include <mach/hardware.h>
-#include <mach/utils.h>
+
+#define USBHSMPH_CTRL_REGOFFSET 0x40
+#define USBHSMPH_STAT_REGOFFSET 0x44
+#define REF300_DIV_REGOFFSET 0xF8
+#define USBHSPHY_CTRL_REGOFFSET 0x84
+#define USB_CTRL_REGOFFSET 0x90
+#define PLLB_DIV_CTRL_REGOFFSET 0x1000F8
+#define USBHSPHY_SUSPENDM_MANUAL_ENABLE 16
+#define USBHSPHY_SUSPENDM_MANUAL_STATE 15
+#define USBHSPHY_ATE_ESET 14
+#define USBHSPHY_TEST_DIN 6
+#define USBHSPHY_TEST_ADD 2
+#define USBHSPHY_TEST_DOUT_SEL 1
+#define USBHSPHY_TEST_CLK 0
+
+#define USB_CTRL_USBAPHY_CKSEL_SHIFT 5
+#define USB_CLK_XTAL0_XTAL1 (0 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_XTAL0 (1 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+#define USB_CLK_INTERNAL (2 << USB_CTRL_USBAPHY_CKSEL_SHIFT)
+
+#define USBAMUX_DEVICE BIT(4)
+
+#define USBPHY_REFCLKDIV_SHIFT 2
+#define USB_PHY_REF_12MHZ (0 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_24MHZ (1 << USBPHY_REFCLKDIV_SHIFT)
+#define USB_PHY_REF_48MHZ (2 << USBPHY_REFCLKDIV_SHIFT)
+
+#define USB_CTRL_USB_CKO_SEL_BIT 0
+
+#define USB_INT_CLK_XTAL 0
+#define USB_INT_CLK_REF300 2
+#define USB_INT_CLK_PLLB 3
+
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
#include "ehci.h"
@@ -33,6 +79,7 @@ struct oxnas_hcd {
struct reset_control *rst_host;
struct reset_control *rst_phya;
struct reset_control *rst_phyb;
+ struct regmap *syscon;
};
#define DRIVER_DESC "Oxnas On-Chip EHCI Host Controller"
@@ -41,21 +88,16 @@ static struct hc_driver __read_mostly oxnas_hc_driver;
static void start_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
{
- u32 reg;
-
if (oxnas->use_pllb) {
/* enable pllb */
clk_prepare_enable(oxnas->refsrc);
/* enable ref600 */
clk_prepare_enable(oxnas->phyref);
/* 600MHz pllb divider for 12MHz */
- writel(PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0),
- SEC_CTRL_PLLB_DIV_CTRL);
-
+ regmap_write_bits(oxnas->syscon, PLLB_DIV_CTRL_REGOFFSET, 0xffff, PLLB_DIV_INT(50) | PLLB_DIV_FRAC(0));
} else {
/* ref 300 divider for 12MHz */
- writel(REF300_DIV_INT(25) | REF300_DIV_FRAC(0),
- SYS_CTRL_REF300_DIV);
+ regmap_write_bits(oxnas->syscon, REF300_DIV_REGOFFSET, 0xffff, REF300_DIV_INT(25) | REF300_DIV_FRAC(0));
}
/* Ensure the USB block is properly reset */
@@ -65,31 +107,34 @@ static void start_oxnas_usb_ehci(struct oxnas_hcd *oxnas)
/* Force the high speed clock to be generated all the time, via serial
programming of the USB HS PHY */
- writel((2UL << USBHSPHY_TEST_ADD) |
- (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (2UL << USBHSPHY_TEST_ADD) |
+ (0xe0UL << USBHSPHY_TEST_DIN));
- writel((1UL << USBHSPHY_TEST_CLK) |
- (2UL << USBHSPHY_TEST_ADD) |
- (0xe0UL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (1UL << USBHSPHY_TEST_CLK) |
+ (2UL << USBHSPHY_TEST_ADD) |
+ (0xe0UL << USBHSPHY_TEST_DIN));
- writel((0xfUL << USBHSPHY_TEST_ADD) |
- (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (0xfUL << USBHSPHY_TEST_ADD) |
+ (0xaaUL << USBHSPHY_TEST_DIN));
- writel((1UL << USBHSPHY_TEST_CLK) |
- (0xfUL << USBHSPHY_TEST_ADD) |
- (0xaaUL << USBHSPHY_TEST_DIN), SYS_CTRL_USBHSPHY_CTRL);
+ regmap_write_bits(oxnas->syscon, USBHSPHY_CTRL_REGOFFSET, 0xffff,
+ (1UL << USBHSPHY_TEST_CLK) |
+ (0xfUL << USBHSPHY_TEST_ADD) |
+ (0xaaUL << USBHSPHY_TEST_DIN));
if (oxnas->use_pllb) /* use pllb clock */
- writel(USB_CLK_INTERNAL | USB_INT_CLK_PLLB, SYS_CTRL_USB_CTRL);
+ regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
+ USB_CLK_INTERNAL | USB_INT_CLK_PLLB);
else /* use ref300 derived clock */
- writel(USB_CLK_INTERNAL | USB_INT_CLK_REF300,
- SYS_CTRL_USB_CTRL);
+ regmap_write_bits(oxnas->syscon, USB_CTRL_REGOFFSET, 0xffff,
+ USB_CLK_INTERNAL | USB_INT_CLK_REF300);
if (oxnas->use_phya) {
/* Configure USB PHYA as a host */
- reg = readl(SYS_CTRL_USB_CTRL);
- reg &= ~USBAMUX_DEVICE;
- writel(reg, SYS_CTRL_USB_CTRL);
+ regmap_update_bits(oxnas->syscon, USB_CTRL_REGOFFSET, USBAMUX_DEVICE, 0);
}
/* Enable the clock to the USB block */
@@ -172,8 +217,14 @@ static int ehci_oxnas_drv_probe(struct platform_device *ofdev)
oxnas = (struct oxnas_hcd *)hcd_to_ehci(hcd)->priv;
- oxnas->use_pllb = of_property_read_bool(np, "plxtech,ehci_use_pllb");
- oxnas->use_phya = of_property_read_bool(np, "plxtech,ehci_use_phya");
+ oxnas->use_pllb = of_property_read_bool(np, "oxsemi,ehci_use_pllb");
+ oxnas->use_phya = of_property_read_bool(np, "oxsemi,ehci_use_phya");
+
+ oxnas->syscon = syscon_regmap_lookup_by_phandle(np, "oxsemi,sys-ctrl");
+ if (IS_ERR(oxnas->syscon)) {
+ err = PTR_ERR(oxnas->syscon);
+ goto err_syscon;
+ }
oxnas->clk = of_clk_get_by_name(np, "usb");
if (IS_ERR(oxnas->clk)) {
@@ -249,6 +300,7 @@ err_phyref:
clk_put(oxnas->refsrc);
err_refsrc:
clk_put(oxnas->clk);
+err_syscon:
err_clk:
err_ioremap:
err_res: