Skip to content

Commit

Permalink
ARM: sa1111: add platform enable/disable functions
Browse files Browse the repository at this point in the history
Add platform hooks to be called when individual sa1111 devices are
enabled and disabled.  This will allow us to move some platform
specifics out of the individual drivers.

Acked-by: Nicolas Pitre <[email protected]>
Signed-off-by: Russell King <[email protected]>
  • Loading branch information
Russell King committed Feb 9, 2012
1 parent 6bd72f0 commit ae99ddb
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 15 deletions.
22 changes: 17 additions & 5 deletions arch/arm/common/sa1111.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ struct sa1111 {
int irq_base; /* base for cascaded on-chip IRQs */
spinlock_t lock;
void __iomem *base;
struct sa1111_platform_data *pdata;
#ifdef CONFIG_PM
void *saved_state;
#endif
Expand Down Expand Up @@ -756,6 +757,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
sachip->dev = me;
dev_set_drvdata(sachip->dev, sachip);

sachip->pdata = pd;
sachip->phys = mem->start;
sachip->irq = irq;

Expand Down Expand Up @@ -1282,16 +1284,23 @@ EXPORT_SYMBOL(sa1111_set_sleep_io);
* sa1111_enable_device - enable an on-chip SA1111 function block
* @sadev: SA1111 function block device to enable
*/
void sa1111_enable_device(struct sa1111_dev *sadev)
int sa1111_enable_device(struct sa1111_dev *sadev)
{
struct sa1111 *sachip = sa1111_chip_driver(sadev);
unsigned long flags;
unsigned int val;
int ret = 0;

spin_lock_irqsave(&sachip->lock, flags);
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
if (sachip->pdata && sachip->pdata->enable)
ret = sachip->pdata->enable(sachip->pdata->data, sadev->devid);

if (ret == 0) {
spin_lock_irqsave(&sachip->lock, flags);
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
return ret;
}
EXPORT_SYMBOL(sa1111_enable_device);

Expand All @@ -1309,6 +1318,9 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);

if (sachip->pdata && sachip->pdata->disable)
sachip->pdata->disable(sachip->pdata->data, sadev->devid);
}
EXPORT_SYMBOL(sa1111_disable_device);

Expand Down
8 changes: 6 additions & 2 deletions arch/arm/include/asm/hardware/sa1111.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,9 +556,10 @@ struct sa1111_driver {
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)

/*
* These frob the SKPCR register.
* These frob the SKPCR register, and call platform specific
* enable/disable functions.
*/
void sa1111_enable_device(struct sa1111_dev *);
int sa1111_enable_device(struct sa1111_dev *);
void sa1111_disable_device(struct sa1111_dev *);

unsigned int sa1111_pll_clock(struct sa1111_dev *);
Expand All @@ -581,6 +582,9 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i

struct sa1111_platform_data {
int irq_base; /* base for cascaded on-chip IRQs */
void *data;
int (*enable)(void *, unsigned);
void (*disable)(void *, unsigned);
};

#endif /* _ASM_ARCH_SA1111 */
6 changes: 5 additions & 1 deletion drivers/input/serio/sa1111ps2.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,16 @@ static int ps2_open(struct serio *io)
struct ps2if *ps2if = io->port_data;
int ret;

sa1111_enable_device(ps2if->dev);
ret = sa1111_enable_device(ps2if->dev);
if (ret)
return ret;

ret = request_irq(ps2if->dev->irq[0], ps2_rxint, 0,
SA1111_DRIVER_NAME(ps2if->dev), ps2if);
if (ret) {
printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
ps2if->dev->irq[0], ret);
sa1111_disable_device(ps2if->dev);
return ret;
}

Expand All @@ -140,6 +143,7 @@ static int ps2_open(struct serio *io)
printk(KERN_ERR "sa1111ps2: could not allocate IRQ%d: %d\n",
ps2if->dev->irq[1], ret);
free_irq(ps2if->dev->irq[0], ps2if);
sa1111_disable_device(ps2if->dev);
return ret;
}

Expand Down
11 changes: 9 additions & 2 deletions drivers/pcmcia/sa1111_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,18 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
static int pcmcia_probe(struct sa1111_dev *dev)
{
void __iomem *base;
int ret;

ret = sa1111_enable_device(dev);
if (ret)
return ret;

dev_set_drvdata(&dev->dev, NULL);

if (!request_mem_region(dev->res.start, 512,
SA1111_DRIVER_NAME(dev)))
if (!request_mem_region(dev->res.start, 512, SA1111_DRIVER_NAME(dev))) {
sa1111_disable_device(dev);
return -EBUSY;
}

base = dev->mapbase;

Expand Down Expand Up @@ -212,6 +218,7 @@ static int __devexit pcmcia_remove(struct sa1111_dev *dev)
}

release_mem_region(dev->res.start, 512);
sa1111_disable_device(dev);
return 0;
}

Expand Down
19 changes: 14 additions & 5 deletions drivers/usb/host/ohci-sa1111.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ extern int usb_disabled(void);

/*-------------------------------------------------------------------------*/

static void sa1111_start_hc(struct sa1111_dev *dev)
static int sa1111_start_hc(struct sa1111_dev *dev)
{
unsigned int usb_rst = 0;
int ret;

printk(KERN_DEBUG "%s: starting SA-1111 OHCI USB Controller\n",
__FILE__);
Expand Down Expand Up @@ -57,9 +58,13 @@ static void sa1111_start_hc(struct sa1111_dev *dev)
* Now, carefully enable the USB clock, and take
* the USB host controller out of reset.
*/
sa1111_enable_device(dev);
udelay(11);
sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET);
ret = sa1111_enable_device(dev);
if (ret == 0) {
udelay(11);
sa1111_writel(usb_rst, dev->mapbase + SA1111_USB_RESET);
}

return ret;
}

static void sa1111_stop_hc(struct sa1111_dev *dev)
Expand Down Expand Up @@ -140,14 +145,18 @@ int usb_hcd_sa1111_probe (const struct hc_driver *driver,
}
hcd->regs = dev->mapbase;

sa1111_start_hc(dev);
ret = sa1111_start_hc(dev);
if (ret)
goto err2;

ohci_hcd_init(hcd_to_ohci(hcd));

retval = usb_add_hcd(hcd, dev->irq[1], 0);
if (retval == 0)
return retval;

sa1111_stop_hc(dev);
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
usb_put_hcd(hcd);
Expand Down

0 comments on commit ae99ddb

Please sign in to comment.