Loading Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt 0 → 100644 +33 −0 Original line number Diff line number Diff line Binding for Broadcom BCM6328 High Speed SPI controller Required properties: - compatible: must contain of "brcm,bcm6328-hsspi". - reg: Base address and size of the controllers memory area. - interrupts: Interrupt for the SPI block. - clocks: phandles of the SPI clock and the PLL clock. - clock-names: must be "hsspi", "pll". - #address-cells: <1>, as required by generic SPI binding. - #size-cells: <0>, also as required by generic SPI binding. Optional properties: - num-cs: some controllers have less than 8 cs signals. Defaults to 8 if absent. Child nodes as per the generic SPI binding. Example: spi@10001000 { compatible = "brcm,bcm6328-hsspi"; reg = <0x10001000 0x600>; interrupts = <29>; clocks = <&clkctl 9>, <&hsspi_pll>; clock-names = "hsspi", "pll"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>; }; Documentation/devicetree/bindings/spi/spi-bcm63xx.txt 0 → 100644 +33 −0 Original line number Diff line number Diff line Binding for Broadcom BCM6348/BCM6358 SPI controller Required properties: - compatible: must contain one of "brcm,bcm6348-spi", "brcm,bcm6358-spi". - reg: Base address and size of the controllers memory area. - interrupts: Interrupt for the SPI block. - clocks: phandle of the SPI clock. - clock-names: has to be "spi". - #address-cells: <1>, as required by generic SPI binding. - #size-cells: <0>, also as required by generic SPI binding. Optional properties: - num-cs: some controllers have less than 8 cs signals. Defaults to 8 if absent. Child nodes as per the generic SPI binding. Example: spi@10000800 { compatible = "brcm,bcm6368-spi", "brcm,bcm6358-spi"; reg = <0x10000800 0x70c>; interrupts = <1>; clocks = <&clkctl 9>; clock-names = "spi"; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; }; drivers/spi/spi-atmel.c +30 −14 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,25 @@ static int atmel_spi_gpio_cs(struct platform_device *pdev) return 0; } static void atmel_spi_init(struct atmel_spi *as) { spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ if (as->caps.has_wdrbt) { spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) | SPI_BIT(MSTR)); } else { spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); } if (as->use_pdc) spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); if (as->fifo_size) spi_writel(as, CR, SPI_BIT(FIFOEN)); } static int atmel_spi_probe(struct platform_device *pdev) { struct resource *regs; Loading Loading @@ -1572,26 +1591,14 @@ static int atmel_spi_probe(struct platform_device *pdev) as->spi_clk = clk_get_rate(clk); spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ if (as->caps.has_wdrbt) { spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) | SPI_BIT(MSTR)); } else { spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); } if (as->use_pdc) spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); as->fifo_size = 0; if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size", &as->fifo_size)) { dev_info(&pdev->dev, "Using FIFO (%u data)\n", as->fifo_size); spi_writel(as, CR, SPI_BIT(FIFOEN)); } atmel_spi_init(as); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); Loading Loading @@ -1695,8 +1702,17 @@ static int atmel_spi_suspend(struct device *dev) static int atmel_spi_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct atmel_spi *as = spi_master_get_devdata(master); int ret; ret = clk_prepare_enable(as->clk); if (ret) return ret; atmel_spi_init(as); clk_disable_unprepare(as->clk); if (!pm_runtime_suspended(dev)) { ret = atmel_spi_runtime_resume(dev); if (ret) Loading drivers/spi/spi-bcm63xx-hsspi.c +30 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/spi/spi.h> #include <linux/mutex.h> #include <linux/of.h> #define HSSPI_GLOBAL_CTRL_REG 0x0 #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 Loading Loading @@ -91,6 +92,7 @@ #define HSSPI_MAX_SYNC_CLOCK 30000000 #define HSSPI_SPI_MAX_CS 8 #define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */ struct bcm63xx_hsspi { Loading Loading @@ -332,7 +334,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct clk *clk; int irq, ret; u32 reg, rate; u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS; irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading @@ -351,8 +353,16 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) return PTR_ERR(clk); rate = clk_get_rate(clk); if (!rate) { struct clk *pll_clk = devm_clk_get(dev, "pll"); if (IS_ERR(pll_clk)) return PTR_ERR(pll_clk); rate = clk_get_rate(pll_clk); if (!rate) return -EINVAL; } ret = clk_prepare_enable(clk); if (ret) Loading @@ -374,8 +384,17 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) mutex_init(&bs->bus_mutex); init_completion(&bs->done); master->dev.of_node = dev->of_node; if (!dev->of_node) master->bus_num = HSSPI_BUS_NUM; master->num_chipselect = 8; of_property_read_u32(dev->of_node, "num-cs", &num_cs); if (num_cs > 8) { dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n", num_cs); num_cs = HSSPI_SPI_MAX_CS; } master->num_chipselect = num_cs; master->setup = bcm63xx_hsspi_setup; master->transfer_one_message = bcm63xx_hsspi_transfer_one; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | Loading Loading @@ -461,10 +480,16 @@ static int bcm63xx_hsspi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, bcm63xx_hsspi_resume); static const struct of_device_id bcm63xx_hsspi_of_match[] = { { .compatible = "brcm,bcm6328-hsspi", }, { }, }; static struct platform_driver bcm63xx_hsspi_driver = { .driver = { .name = "bcm63xx-hsspi", .pm = &bcm63xx_hsspi_pm_ops, .of_match_table = bcm63xx_hsspi_of_match, }, .probe = bcm63xx_hsspi_probe, .remove = bcm63xx_hsspi_remove, Loading drivers/spi/spi-bcm63xx.c +45 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/completion.h> #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/of.h> /* BCM 6338/6348 SPI core */ #define SPI_6348_RSET_SIZE 64 Loading Loading @@ -428,6 +429,13 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } static size_t bcm63xx_spi_max_length(struct spi_device *spi) { struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); return bs->fifo_size; } static const unsigned long bcm6348_spi_reg_offsets[] = { [SPI_CMD] = SPI_6348_CMD, [SPI_INT_STATUS] = SPI_6348_INT_STATUS, Loading Loading @@ -477,21 +485,48 @@ static const struct platform_device_id bcm63xx_spi_dev_match[] = { }, }; static const struct of_device_id bcm63xx_spi_of_match[] = { { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets }, { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets }, { }, }; static int bcm63xx_spi_probe(struct platform_device *pdev) { struct resource *r; const unsigned long *bcm63xx_spireg; struct device *dev = &pdev->dev; int irq; int irq, bus_num; struct spi_master *master; struct clk *clk; struct bcm63xx_spi *bs; int ret; u32 num_cs = BCM63XX_SPI_MAX_CS; if (dev->of_node) { const struct of_device_id *match; if (!pdev->id_entry->driver_data) match = of_match_node(bcm63xx_spi_of_match, dev->of_node); if (!match) return -EINVAL; bcm63xx_spireg = match->data; of_property_read_u32(dev->of_node, "num-cs", &num_cs); if (num_cs > BCM63XX_SPI_MAX_CS) { dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n", num_cs); num_cs = BCM63XX_SPI_MAX_CS; } bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data; bus_num = -1; } else if (pdev->id_entry->driver_data) { const struct platform_device_id *match = pdev->id_entry; bcm63xx_spireg = (const unsigned long *)match->driver_data; bus_num = BCM63XX_SPI_BUS_NUM; } else { return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading Loading @@ -536,11 +571,14 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) goto out_err; } master->bus_num = BCM63XX_SPI_BUS_NUM; master->num_chipselect = BCM63XX_SPI_MAX_CS; master->dev.of_node = dev->of_node; master->bus_num = bus_num; master->num_chipselect = num_cs; master->transfer_one_message = bcm63xx_spi_transfer_one; master->mode_bits = MODEBITS; master->bits_per_word_mask = SPI_BPW_MASK(8); master->max_transfer_size = bcm63xx_spi_max_length; master->max_message_size = bcm63xx_spi_max_length; master->auto_runtime_pm = true; bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; Loading Loading @@ -624,6 +662,7 @@ static struct platform_driver bcm63xx_spi_driver = { .driver = { .name = "bcm63xx-spi", .pm = &bcm63xx_spi_pm_ops, .of_match_table = bcm63xx_spi_of_match, }, .id_table = bcm63xx_spi_dev_match, .probe = bcm63xx_spi_probe, Loading Loading
Documentation/devicetree/bindings/spi/spi-bcm63xx-hsspi.txt 0 → 100644 +33 −0 Original line number Diff line number Diff line Binding for Broadcom BCM6328 High Speed SPI controller Required properties: - compatible: must contain of "brcm,bcm6328-hsspi". - reg: Base address and size of the controllers memory area. - interrupts: Interrupt for the SPI block. - clocks: phandles of the SPI clock and the PLL clock. - clock-names: must be "hsspi", "pll". - #address-cells: <1>, as required by generic SPI binding. - #size-cells: <0>, also as required by generic SPI binding. Optional properties: - num-cs: some controllers have less than 8 cs signals. Defaults to 8 if absent. Child nodes as per the generic SPI binding. Example: spi@10001000 { compatible = "brcm,bcm6328-hsspi"; reg = <0x10001000 0x600>; interrupts = <29>; clocks = <&clkctl 9>, <&hsspi_pll>; clock-names = "hsspi", "pll"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>; };
Documentation/devicetree/bindings/spi/spi-bcm63xx.txt 0 → 100644 +33 −0 Original line number Diff line number Diff line Binding for Broadcom BCM6348/BCM6358 SPI controller Required properties: - compatible: must contain one of "brcm,bcm6348-spi", "brcm,bcm6358-spi". - reg: Base address and size of the controllers memory area. - interrupts: Interrupt for the SPI block. - clocks: phandle of the SPI clock. - clock-names: has to be "spi". - #address-cells: <1>, as required by generic SPI binding. - #size-cells: <0>, also as required by generic SPI binding. Optional properties: - num-cs: some controllers have less than 8 cs signals. Defaults to 8 if absent. Child nodes as per the generic SPI binding. Example: spi@10000800 { compatible = "brcm,bcm6368-spi", "brcm,bcm6358-spi"; reg = <0x10000800 0x70c>; interrupts = <1>; clocks = <&clkctl 9>; clock-names = "spi"; num-cs = <5>; #address-cells = <1>; #size-cells = <0>; };
drivers/spi/spi-atmel.c +30 −14 Original line number Diff line number Diff line Loading @@ -1464,6 +1464,25 @@ static int atmel_spi_gpio_cs(struct platform_device *pdev) return 0; } static void atmel_spi_init(struct atmel_spi *as) { spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ if (as->caps.has_wdrbt) { spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) | SPI_BIT(MSTR)); } else { spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); } if (as->use_pdc) spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); if (as->fifo_size) spi_writel(as, CR, SPI_BIT(FIFOEN)); } static int atmel_spi_probe(struct platform_device *pdev) { struct resource *regs; Loading Loading @@ -1572,26 +1591,14 @@ static int atmel_spi_probe(struct platform_device *pdev) as->spi_clk = clk_get_rate(clk); spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ if (as->caps.has_wdrbt) { spi_writel(as, MR, SPI_BIT(WDRBT) | SPI_BIT(MODFDIS) | SPI_BIT(MSTR)); } else { spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); } if (as->use_pdc) spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); as->fifo_size = 0; if (!of_property_read_u32(pdev->dev.of_node, "atmel,fifo-size", &as->fifo_size)) { dev_info(&pdev->dev, "Using FIFO (%u data)\n", as->fifo_size); spi_writel(as, CR, SPI_BIT(FIFOEN)); } atmel_spi_init(as); pm_runtime_set_autosuspend_delay(&pdev->dev, AUTOSUSPEND_TIMEOUT); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_active(&pdev->dev); Loading Loading @@ -1695,8 +1702,17 @@ static int atmel_spi_suspend(struct device *dev) static int atmel_spi_resume(struct device *dev) { struct spi_master *master = dev_get_drvdata(dev); struct atmel_spi *as = spi_master_get_devdata(master); int ret; ret = clk_prepare_enable(as->clk); if (ret) return ret; atmel_spi_init(as); clk_disable_unprepare(as->clk); if (!pm_runtime_suspended(dev)) { ret = atmel_spi_runtime_resume(dev); if (ret) Loading
drivers/spi/spi-bcm63xx-hsspi.c +30 −5 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <linux/interrupt.h> #include <linux/spi/spi.h> #include <linux/mutex.h> #include <linux/of.h> #define HSSPI_GLOBAL_CTRL_REG 0x0 #define GLOBAL_CTRL_CS_POLARITY_SHIFT 0 Loading Loading @@ -91,6 +92,7 @@ #define HSSPI_MAX_SYNC_CLOCK 30000000 #define HSSPI_SPI_MAX_CS 8 #define HSSPI_BUS_NUM 1 /* 0 is legacy SPI */ struct bcm63xx_hsspi { Loading Loading @@ -332,7 +334,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct clk *clk; int irq, ret; u32 reg, rate; u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS; irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading @@ -351,8 +353,16 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) return PTR_ERR(clk); rate = clk_get_rate(clk); if (!rate) { struct clk *pll_clk = devm_clk_get(dev, "pll"); if (IS_ERR(pll_clk)) return PTR_ERR(pll_clk); rate = clk_get_rate(pll_clk); if (!rate) return -EINVAL; } ret = clk_prepare_enable(clk); if (ret) Loading @@ -374,8 +384,17 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) mutex_init(&bs->bus_mutex); init_completion(&bs->done); master->dev.of_node = dev->of_node; if (!dev->of_node) master->bus_num = HSSPI_BUS_NUM; master->num_chipselect = 8; of_property_read_u32(dev->of_node, "num-cs", &num_cs); if (num_cs > 8) { dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n", num_cs); num_cs = HSSPI_SPI_MAX_CS; } master->num_chipselect = num_cs; master->setup = bcm63xx_hsspi_setup; master->transfer_one_message = bcm63xx_hsspi_transfer_one; master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | Loading Loading @@ -461,10 +480,16 @@ static int bcm63xx_hsspi_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(bcm63xx_hsspi_pm_ops, bcm63xx_hsspi_suspend, bcm63xx_hsspi_resume); static const struct of_device_id bcm63xx_hsspi_of_match[] = { { .compatible = "brcm,bcm6328-hsspi", }, { }, }; static struct platform_driver bcm63xx_hsspi_driver = { .driver = { .name = "bcm63xx-hsspi", .pm = &bcm63xx_hsspi_pm_ops, .of_match_table = bcm63xx_hsspi_of_match, }, .probe = bcm63xx_hsspi_probe, .remove = bcm63xx_hsspi_remove, Loading
drivers/spi/spi-bcm63xx.c +45 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/completion.h> #include <linux/err.h> #include <linux/pm_runtime.h> #include <linux/of.h> /* BCM 6338/6348 SPI core */ #define SPI_6348_RSET_SIZE 64 Loading Loading @@ -428,6 +429,13 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } static size_t bcm63xx_spi_max_length(struct spi_device *spi) { struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); return bs->fifo_size; } static const unsigned long bcm6348_spi_reg_offsets[] = { [SPI_CMD] = SPI_6348_CMD, [SPI_INT_STATUS] = SPI_6348_INT_STATUS, Loading Loading @@ -477,21 +485,48 @@ static const struct platform_device_id bcm63xx_spi_dev_match[] = { }, }; static const struct of_device_id bcm63xx_spi_of_match[] = { { .compatible = "brcm,bcm6348-spi", .data = &bcm6348_spi_reg_offsets }, { .compatible = "brcm,bcm6358-spi", .data = &bcm6358_spi_reg_offsets }, { }, }; static int bcm63xx_spi_probe(struct platform_device *pdev) { struct resource *r; const unsigned long *bcm63xx_spireg; struct device *dev = &pdev->dev; int irq; int irq, bus_num; struct spi_master *master; struct clk *clk; struct bcm63xx_spi *bs; int ret; u32 num_cs = BCM63XX_SPI_MAX_CS; if (dev->of_node) { const struct of_device_id *match; if (!pdev->id_entry->driver_data) match = of_match_node(bcm63xx_spi_of_match, dev->of_node); if (!match) return -EINVAL; bcm63xx_spireg = match->data; of_property_read_u32(dev->of_node, "num-cs", &num_cs); if (num_cs > BCM63XX_SPI_MAX_CS) { dev_warn(dev, "unsupported number of cs (%i), reducing to 8\n", num_cs); num_cs = BCM63XX_SPI_MAX_CS; } bcm63xx_spireg = (const unsigned long *)pdev->id_entry->driver_data; bus_num = -1; } else if (pdev->id_entry->driver_data) { const struct platform_device_id *match = pdev->id_entry; bcm63xx_spireg = (const unsigned long *)match->driver_data; bus_num = BCM63XX_SPI_BUS_NUM; } else { return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { Loading Loading @@ -536,11 +571,14 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) goto out_err; } master->bus_num = BCM63XX_SPI_BUS_NUM; master->num_chipselect = BCM63XX_SPI_MAX_CS; master->dev.of_node = dev->of_node; master->bus_num = bus_num; master->num_chipselect = num_cs; master->transfer_one_message = bcm63xx_spi_transfer_one; master->mode_bits = MODEBITS; master->bits_per_word_mask = SPI_BPW_MASK(8); master->max_transfer_size = bcm63xx_spi_max_length; master->max_message_size = bcm63xx_spi_max_length; master->auto_runtime_pm = true; bs->msg_type_shift = bs->reg_offsets[SPI_MSG_TYPE_SHIFT]; bs->msg_ctl_width = bs->reg_offsets[SPI_MSG_CTL_WIDTH]; Loading Loading @@ -624,6 +662,7 @@ static struct platform_driver bcm63xx_spi_driver = { .driver = { .name = "bcm63xx-spi", .pm = &bcm63xx_spi_pm_ops, .of_match_table = bcm63xx_spi_of_match, }, .id_table = bcm63xx_spi_dev_match, .probe = bcm63xx_spi_probe, Loading