Re: [PATCH 2/2] gpio: tb10x: Use GENERIC_GPIO
Acked-by: Christian Ruppert On 06.08.2018 17:12, Linus Walleij wrote: > Instead of open coding logic for reading and writing GPIO lines, > use the generic GPIO library. Also switch to using the spinlock > from the generic GPIO to protect the registers. > > Cc: linux-snps-arc@lists.infradead.org > Cc: Christian Ruppert > Signed-off-by: Linus Walleij > --- > drivers/gpio/Kconfig | 1 + > drivers/gpio/gpio-tb10x.c | 96 --- > 2 files changed, 31 insertions(+), 66 deletions(-) > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig > index 7429b30e61b0..d351548d0257 100644 > --- a/drivers/gpio/Kconfig > +++ b/drivers/gpio/Kconfig > @@ -480,6 +480,7 @@ config GPIO_SYSCON > > config GPIO_TB10X > bool > + select GPIO_GENERIC > select GENERIC_IRQ_CHIP > select OF_GPIO > > diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c > index 422b0ac5a9de..d5e5d19f4c0a 100644 > --- a/drivers/gpio/gpio-tb10x.c > +++ b/drivers/gpio/gpio-tb10x.c > @@ -45,14 +45,12 @@ > > > /** > - * @spinlock: used for atomic read/modify/write of registers > * @base: register base address > * @domain: IRQ domain of GPIO generated interrupts managed by this > controller > * @irq: Interrupt line of parent interrupt controller > * @gc: gpio_chip structure associated to this GPIO controller > */ > struct tb10x_gpio { > - spinlock_t spinlock; > void __iomem *base; > struct irq_domain *domain; > int irq; > @@ -76,60 +74,14 @@ static inline void tb10x_set_bits(struct tb10x_gpio > *gpio, unsigned int offs, > u32 r; > unsigned long flags; > > - spin_lock_irqsave(&gpio->spinlock, flags); > + spin_lock_irqsave(&gpio->gc.bgpio_lock, flags); > > r = tb10x_reg_read(gpio, offs); > r = (r & ~mask) | (val & mask); > > tb10x_reg_write(gpio, offs, r); > > - spin_unlock_irqrestore(&gpio->spinlock, flags); > -} > - > -static int tb10x_gpio_direction_in(struct gpio_chip *chip, unsigned offset) > -{ > - struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip); > - int mask = BIT(offset); > - int val = TB10X_GPIO_DIR_IN << offset; > - > - tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val); > - > - return 0; > -} > - > -static int tb10x_gpio_get(struct gpio_chip *chip, unsigned offset) > -{ > - struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip); > - int val; > - > - val = tb10x_reg_read(tb10x_gpio, OFFSET_TO_REG_DATA); > - > - if (val & BIT(offset)) > - return 1; > - else > - return 0; > -} > - > -static void tb10x_gpio_set(struct gpio_chip *chip, unsigned offset, int > value) > -{ > - struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip); > - int mask = BIT(offset); > - int val = value << offset; > - > - tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DATA, mask, val); > -} > - > -static int tb10x_gpio_direction_out(struct gpio_chip *chip, > - unsigned offset, int value) > -{ > - struct tb10x_gpio *tb10x_gpio = gpiochip_get_data(chip); > - int mask = BIT(offset); > - int val = TB10X_GPIO_DIR_OUT << offset; > - > - tb10x_gpio_set(chip, offset, value); > - tb10x_set_bits(tb10x_gpio, OFFSET_TO_REG_DDR, mask, val); > - > - return 0; > + spin_unlock_irqrestore(&gpio->gc.bgpio_lock, flags); > } > > static int tb10x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) > @@ -184,8 +136,6 @@ static int tb10x_gpio_probe(struct platform_device *pdev) > if (tb10x_gpio == NULL) > return -ENOMEM; > > - spin_lock_init(&tb10x_gpio->spinlock); > - > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > tb10x_gpio->base = devm_ioremap_resource(dev, mem); > if (IS_ERR(tb10x_gpio->base)) > @@ -196,20 +146,34 @@ static int tb10x_gpio_probe(struct platform_device > *pdev) > if (!tb10x_gpio->gc.label) > return -ENOMEM; > > - tb10x_gpio->gc.parent = &pdev->dev; > - tb10x_gpio->gc.owner= THIS_MODULE; > - tb10x_gpio->gc.direction_input = tb10x_gpio_direction_in; > - tb10x_gpio->gc.get = tb10x_gpio_get; > - tb10x_gpio->gc.direction_output = tb10x_gpio_direction_out; > - tb10x_gpio->gc.set = tb10x_gpio_set; > - tb10x_gpio->gc.request = gpiochip_generic_request; > - tb10x_gpio->gc.free = gpiochip_generic_free; > - tb10x_gpio->gc.base = -1; > - tb10x_gpio->gc.ngpio= ngpio; > - tb10x_gpio->gc.can_sleep= false; > - > - > - ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio); > + /* > + * Initialize generic GPIO with one single register for reading and > setting > + * the lines, no special set or clear registers and a data direction > register > + * wher 1 means "output". > + */ > + ret = bgpio_init(&tb10x
Re: [PATCH] gpio: tb10x: Use the right include
Acked-by: Christian Ruppert On 06.08.2018 16:23, Linus Walleij wrote: > This driver includes the legacy and > but all it needs is really . > > Cc: linux-snps-arc@lists.infradead.org > Cc: Christian Ruppert > Signed-off-by: Linus Walleij > --- > drivers/gpio/gpio-tb10x.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c > index ac6f2a9841e5..a12cd0b5c972 100644 > --- a/drivers/gpio/gpio-tb10x.c > +++ b/drivers/gpio/gpio-tb10x.c > @@ -22,7 +22,7 @@ > #include > #include > #include > -#include > +#include > #include > #include > #include > @@ -30,7 +30,6 @@ > #include > #include > #include > -#include > #include > #include > #include > ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH 1/2] gpio: tb10x: Create local helper variables
Acked-by: Christian Ruppert On 06.08.2018 17:12, Linus Walleij wrote: > Create a local struct device *dev helper variable to make the code > easier to read. > > Most GPIO drivers use "np" (node pointer) rather than "dn" (device node) > to point to the device tree node. Let's follow this convention. > > Cc: linux-snps-arc@lists.infradead.org > Cc: Christian Ruppert > Signed-off-by: Linus Walleij > --- > drivers/gpio/gpio-tb10x.c | 27 ++- > 1 file changed, 14 insertions(+), 13 deletions(-) > > diff --git a/drivers/gpio/gpio-tb10x.c b/drivers/gpio/gpio-tb10x.c > index a12cd0b5c972..422b0ac5a9de 100644 > --- a/drivers/gpio/gpio-tb10x.c > +++ b/drivers/gpio/gpio-tb10x.c > @@ -169,29 +169,30 @@ static int tb10x_gpio_probe(struct platform_device > *pdev) > { > struct tb10x_gpio *tb10x_gpio; > struct resource *mem; > - struct device_node *dn = pdev->dev.of_node; > + struct device *dev = &pdev->dev; > + struct device_node *np = dev->of_node; > int ret = -EBUSY; > u32 ngpio; > > - if (!dn) > + if (!np) > return -EINVAL; > > - if (of_property_read_u32(dn, "abilis,ngpio", &ngpio)) > + if (of_property_read_u32(np, "abilis,ngpio", &ngpio)) > return -EINVAL; > > - tb10x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tb10x_gpio), GFP_KERNEL); > + tb10x_gpio = devm_kzalloc(dev, sizeof(*tb10x_gpio), GFP_KERNEL); > if (tb10x_gpio == NULL) > return -ENOMEM; > > spin_lock_init(&tb10x_gpio->spinlock); > > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - tb10x_gpio->base = devm_ioremap_resource(&pdev->dev, mem); > + tb10x_gpio->base = devm_ioremap_resource(dev, mem); > if (IS_ERR(tb10x_gpio->base)) > return PTR_ERR(tb10x_gpio->base); > > - tb10x_gpio->gc.label= > - devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOF", > pdev->dev.of_node); > + tb10x_gpio->gc.label = > + devm_kasprintf(dev, GFP_KERNEL, "%pOF", pdev->dev.of_node); > if (!tb10x_gpio->gc.label) > return -ENOMEM; > > @@ -210,31 +211,31 @@ static int tb10x_gpio_probe(struct platform_device > *pdev) > > ret = devm_gpiochip_add_data(&pdev->dev, &tb10x_gpio->gc, tb10x_gpio); > if (ret < 0) { > - dev_err(&pdev->dev, "Could not add gpiochip.\n"); > + dev_err(dev, "Could not add gpiochip.\n"); > return ret; > } > > platform_set_drvdata(pdev, tb10x_gpio); > > - if (of_find_property(dn, "interrupt-controller", NULL)) { > + if (of_find_property(np, "interrupt-controller", NULL)) { > struct irq_chip_generic *gc; > > ret = platform_get_irq(pdev, 0); > if (ret < 0) { > - dev_err(&pdev->dev, "No interrupt specified.\n"); > + dev_err(dev, "No interrupt specified.\n"); > return ret; > } > > tb10x_gpio->gc.to_irq = tb10x_gpio_to_irq; > tb10x_gpio->irq = ret; > > - ret = devm_request_irq(&pdev->dev, ret, tb10x_gpio_irq_cascade, > + ret = devm_request_irq(dev, ret, tb10x_gpio_irq_cascade, > IRQF_TRIGGER_NONE | IRQF_SHARED, > - dev_name(&pdev->dev), tb10x_gpio); > + dev_name(dev), tb10x_gpio); > if (ret != 0) > return ret; > > - tb10x_gpio->domain = irq_domain_add_linear(dn, > + tb10x_gpio->domain = irq_domain_add_linear(np, > tb10x_gpio->gc.ngpio, > &irq_generic_chip_ops, NULL); > if (!tb10x_gpio->domain) { > ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH v2 2/4] ARC: allow to use IOC and non-IOC DMA devices simultaneously
On 08/13/2018 10:08 AM, Eugeniy Paltsev wrote: > On Mon, 2018-08-13 at 16:24 +, Vineet Gupta wrote: >> On 07/30/2018 09:26 AM, Eugeniy Paltsev wrote: >>> @@ -1263,11 +1254,7 @@ void __init arc_cache_init_master(void) >>> if (is_isa_arcv2() && ioc_enable) >>> arc_ioc_setup(); >>> >>> - if (is_isa_arcv2() && ioc_enable) { >>> - __dma_cache_wback_inv = __dma_cache_wback_inv_ioc; >>> - __dma_cache_inv = __dma_cache_inv_ioc; >>> - __dma_cache_wback = __dma_cache_wback_ioc; >>> - } else if (is_isa_arcv2() && l2_line_sz && slc_enable) { For the casual reader I'd add a comment why this was deleted. >>> + if (is_isa_arcv2() && l2_line_sz && slc_enable) { >>> __dma_cache_wback_inv = __dma_cache_wback_inv_slc; >>> __dma_cache_inv = __dma_cache_inv_slc; >>> __dma_cache_wback = __dma_cache_wback_slc; [snip] >>> >>> - /* >>> -* IOC relies on all data (even coherent DMA data) being in cache >>> -* Thus allocate normal cached memory >>> -* >>> -* The gains with IOC are two pronged: >>> -* -For streaming data, elides need for cache maintenance, saving >>> -*cycles in flush code, and bus bandwidth as all the lines of a >>> -*buffer need to be flushed out to memory >>> -* -For coherent data, Read/Write to buffers terminate early in cache >>> -* (vs. always going to memory - thus are faster) >>> -*/ >>> - if ((is_isa_arcv2() && ioc_enable) || >>> - (attrs & DMA_ATTR_NON_CONSISTENT)) >>> + if (attrs & DMA_ATTR_NON_CONSISTENT) >>> need_coh = 0; >>> [snip] > Yep, I tested that. > And it works fine with both @ioc_enable == 0 and @ioc_enable == 1 > Note that we check this variable in arch_setup_dma_ops() function now. > > So this arch_dma_{alloc,free} are used ONLY in case of software assisted > cache maintenance. > That's why we had to do MMU mapping to enforce non-cachability regardless of > @ioc_enable. Reading kernel/dma/* I see what you mean. We check @ioc_enable at the time of registering the dma op for coherent vs. non coherent case, so there's common vs. ARC versions of alloc/free for coherent vs. noncoherent. But then I'm curious why do we bother to check the following in new arch_dma_(alloc|free) at all. if (attrs & DMA_ATTR_NON_CONSISTENT) Isn't it supposed to be NON_CONSISTENT always given the way new code works ? ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc