mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			141 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/drivers/bcma/driver_chipcommon.c
 | |
| +++ b/drivers/bcma/driver_chipcommon.c
 | |
| @@ -70,6 +70,8 @@ void bcma_core_chipcommon_init(struct bc
 | |
|  			 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
 | |
|  	}
 | |
|  
 | |
| +	spin_lock_init(&cc->gpio_lock);
 | |
| +
 | |
|  	cc->setup_done = true;
 | |
|  }
 | |
|  
 | |
| @@ -92,34 +94,81 @@ u32 bcma_chipco_irq_status(struct bcma_d
 | |
|  
 | |
|  u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
 | |
|  {
 | |
| -	return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_in);
 | |
|  
 | |
|  u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
 | |
|  {
 | |
| -	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
 | |
|  
 | |
|  u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
 | |
|  {
 | |
| -	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
 | |
|  
 | |
|  u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
 | |
|  {
 | |
| -	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
|  EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
 | |
|  
 | |
|  u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
 | |
|  {
 | |
| -	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_intmask);
 | |
|  
 | |
|  u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 | |
|  {
 | |
| -	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 | |
| +	unsigned long flags;
 | |
| +	u32 res;
 | |
| +
 | |
| +	spin_lock_irqsave(&cc->gpio_lock, flags);
 | |
| +	res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 | |
| +	spin_unlock_irqrestore(&cc->gpio_lock, flags);
 | |
| +
 | |
| +	return res;
 | |
|  }
 | |
| +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_polarity);
 | |
|  
 | |
|  #ifdef CONFIG_BCMA_DRIVER_MIPS
 | |
|  void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
 | |
| --- a/include/linux/bcma/bcma_driver_chipcommon.h
 | |
| +++ b/include/linux/bcma/bcma_driver_chipcommon.h
 | |
| @@ -551,6 +551,9 @@ struct bcma_drv_cc {
 | |
|  	int nr_serial_ports;
 | |
|  	struct bcma_serial_port serial_ports[4];
 | |
|  #endif /* CONFIG_BCMA_DRIVER_MIPS */
 | |
| +
 | |
| +	/* Lock for GPIO register access. */
 | |
| +	spinlock_t gpio_lock;
 | |
|  };
 | |
|  
 | |
|  /* Register access */
 | |
| @@ -581,13 +584,22 @@ void bcma_chipco_irq_mask(struct bcma_dr
 | |
|  
 | |
|  u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
 | |
|  
 | |
| +#define BCMA_CC_GPIO_LINES	16
 | |
| +
 | |
|  /* Chipcommon GPIO pin access. */
 | |
| -u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
 | |
| -u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| -u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| -u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| -u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| -u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| +extern u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
 | |
| +extern u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| +extern u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
 | |
| +extern u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask,
 | |
| +				    u32 value);
 | |
| +extern u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask,
 | |
| +				    u32 value);
 | |
| +extern u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask,
 | |
| +				     u32 value);
 | |
| +static inline int bcma_chipco_gpio_count(void)
 | |
| +{
 | |
| +	return BCMA_CC_GPIO_LINES;
 | |
| +}
 | |
|  
 | |
|  /* PMU support */
 | |
|  extern void bcma_pmu_init(struct bcma_drv_cc *cc);
 |