diff options
Diffstat (limited to 'drivers/ptp')
-rw-r--r-- | drivers/ptp/ptp_clock.c | 38 | ||||
-rw-r--r-- | drivers/ptp/ptp_pch.c | 29 |
2 files changed, 28 insertions, 39 deletions
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 79f4bce061bd..4a8c388364ca 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/bitops.h> +#include <linux/idr.h> #include <linux/device.h> #include <linux/err.h> #include <linux/init.h> @@ -32,7 +32,6 @@ #include "ptp_private.h" #define PTP_MAX_ALARMS 4 -#define PTP_MAX_CLOCKS 8 #define PTP_PPS_DEFAULTS (PPS_CAPTUREASSERT | PPS_OFFSETASSERT) #define PTP_PPS_EVENT PPS_CAPTUREASSERT #define PTP_PPS_MODE (PTP_PPS_DEFAULTS | PPS_CANWAIT | PPS_TSFMT_TSPEC) @@ -42,8 +41,7 @@ static dev_t ptp_devt; static struct class *ptp_class; -static DECLARE_BITMAP(ptp_clocks_map, PTP_MAX_CLOCKS); -static DEFINE_MUTEX(ptp_clocks_mutex); /* protects 'ptp_clocks_map' */ +static DEFINE_IDA(ptp_clocks_map); /* time stamp event queue operations */ @@ -171,12 +169,7 @@ static void delete_ptp_clock(struct posix_clock *pc) struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); mutex_destroy(&ptp->tsevq_mux); - - /* Remove the clock from the bit map. */ - mutex_lock(&ptp_clocks_mutex); - clear_bit(ptp->index, ptp_clocks_map); - mutex_unlock(&ptp_clocks_mutex); - + ida_simple_remove(&ptp_clocks_map, ptp->index); kfree(ptp); } @@ -191,21 +184,18 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, if (info->n_alarm > PTP_MAX_ALARMS) return ERR_PTR(-EINVAL); - /* Find a free clock slot and reserve it. */ - err = -EBUSY; - mutex_lock(&ptp_clocks_mutex); - index = find_first_zero_bit(ptp_clocks_map, PTP_MAX_CLOCKS); - if (index < PTP_MAX_CLOCKS) - set_bit(index, ptp_clocks_map); - else - goto no_slot; - /* Initialize a clock structure. */ err = -ENOMEM; ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL); if (ptp == NULL) goto no_memory; + index = ida_simple_get(&ptp_clocks_map, 0, MINORMASK + 1, GFP_KERNEL); + if (index < 0) { + err = index; + goto no_slot; + } + ptp->clock.ops = ptp_clock_ops; ptp->clock.release = delete_ptp_clock; ptp->info = info; @@ -248,7 +238,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, goto no_clock; } - mutex_unlock(&ptp_clocks_mutex); return ptp; no_clock: @@ -260,11 +249,9 @@ no_sysfs: device_destroy(ptp_class, ptp->devid); no_device: mutex_destroy(&ptp->tsevq_mux); +no_slot: kfree(ptp); no_memory: - clear_bit(index, ptp_clocks_map); -no_slot: - mutex_unlock(&ptp_clocks_mutex); return ERR_PTR(err); } EXPORT_SYMBOL(ptp_clock_register); @@ -323,7 +310,8 @@ EXPORT_SYMBOL(ptp_clock_index); static void __exit ptp_exit(void) { class_destroy(ptp_class); - unregister_chrdev_region(ptp_devt, PTP_MAX_CLOCKS); + unregister_chrdev_region(ptp_devt, MINORMASK + 1); + ida_destroy(&ptp_clocks_map); } static int __init ptp_init(void) @@ -336,7 +324,7 @@ static int __init ptp_init(void) return PTR_ERR(ptp_class); } - err = alloc_chrdev_region(&ptp_devt, 0, PTP_MAX_CLOCKS, "ptp"); + err = alloc_chrdev_region(&ptp_devt, 0, MINORMASK + 1, "ptp"); if (err < 0) { pr_err("ptp: failed to allocate device region\n"); goto no_region; diff --git a/drivers/ptp/ptp_pch.c b/drivers/ptp/ptp_pch.c index 1367655eee39..bea94510ad2d 100644 --- a/drivers/ptp/ptp_pch.c +++ b/drivers/ptp/ptp_pch.c @@ -118,7 +118,7 @@ struct pch_ts_regs { * struct pch_dev - Driver private data */ struct pch_dev { - struct pch_ts_regs *regs; + struct pch_ts_regs __iomem *regs; struct ptp_clock *ptp_clock; struct ptp_clock_info caps; int exts0_enabled; @@ -154,7 +154,7 @@ static inline void pch_eth_enable_set(struct pch_dev *chip) iowrite32(val, (&chip->regs->ts_sel)); } -static u64 pch_systime_read(struct pch_ts_regs *regs) +static u64 pch_systime_read(struct pch_ts_regs __iomem *regs) { u64 ns; u32 lo, hi; @@ -169,7 +169,7 @@ static u64 pch_systime_read(struct pch_ts_regs *regs) return ns; } -static void pch_systime_write(struct pch_ts_regs *regs, u64 ns) +static void pch_systime_write(struct pch_ts_regs __iomem *regs, u64 ns) { u32 hi, lo; @@ -315,7 +315,7 @@ int pch_set_station_address(u8 *addr, struct pci_dev *pdev) struct pch_dev *chip = pci_get_drvdata(pdev); /* Verify the parameter */ - if ((chip->regs == 0) || addr == (u8 *)NULL) { + if ((chip->regs == NULL) || addr == (u8 *)NULL) { dev_err(&pdev->dev, "invalid params returning PCH_INVALIDPARAM\n"); return PCH_INVALIDPARAM; @@ -361,7 +361,7 @@ EXPORT_SYMBOL(pch_set_station_address); static irqreturn_t isr(int irq, void *priv) { struct pch_dev *pch_dev = priv; - struct pch_ts_regs *regs = pch_dev->regs; + struct pch_ts_regs __iomem *regs = pch_dev->regs; struct ptp_clock_event event; u32 ack = 0, lo, hi, val; @@ -415,7 +415,7 @@ static int ptp_pch_adjfreq(struct ptp_clock_info *ptp, s32 ppb) u32 diff, addend; int neg_adj = 0; struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); - struct pch_ts_regs *regs = pch_dev->regs; + struct pch_ts_regs __iomem *regs = pch_dev->regs; if (ppb < 0) { neg_adj = 1; @@ -438,7 +438,7 @@ static int ptp_pch_adjtime(struct ptp_clock_info *ptp, s64 delta) s64 now; unsigned long flags; struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); - struct pch_ts_regs *regs = pch_dev->regs; + struct pch_ts_regs __iomem *regs = pch_dev->regs; spin_lock_irqsave(&pch_dev->register_lock, flags); now = pch_systime_read(regs); @@ -455,7 +455,7 @@ static int ptp_pch_gettime(struct ptp_clock_info *ptp, struct timespec *ts) u32 remainder; unsigned long flags; struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); - struct pch_ts_regs *regs = pch_dev->regs; + struct pch_ts_regs __iomem *regs = pch_dev->regs; spin_lock_irqsave(&pch_dev->register_lock, flags); ns = pch_systime_read(regs); @@ -472,7 +472,7 @@ static int ptp_pch_settime(struct ptp_clock_info *ptp, u64 ns; unsigned long flags; struct pch_dev *pch_dev = container_of(ptp, struct pch_dev, caps); - struct pch_ts_regs *regs = pch_dev->regs; + struct pch_ts_regs __iomem *regs = pch_dev->regs; ns = ts->tv_sec * 1000000000ULL; ns += ts->tv_nsec; @@ -567,9 +567,9 @@ static void pch_remove(struct pci_dev *pdev) free_irq(pdev->irq, chip); /* unmap the virtual IO memory space */ - if (chip->regs != 0) { + if (chip->regs != NULL) { iounmap(chip->regs); - chip->regs = 0; + chip->regs = NULL; } /* release the reserved IO memory space */ if (chip->mem_base != 0) { @@ -670,7 +670,7 @@ pch_probe(struct pci_dev *pdev, const struct pci_device_id *id) err_req_irq: ptp_clock_unregister(chip->ptp_clock); iounmap(chip->regs); - chip->regs = 0; + chip->regs = NULL; err_ioremap: release_mem_region(chip->mem_base, chip->mem_size); @@ -723,9 +723,10 @@ static s32 __init ptp_pch_init(void) module_init(ptp_pch_init); module_exit(ptp_pch_exit); -module_param_string(station, pch_param.station, sizeof pch_param.station, 0444); +module_param_string(station, + pch_param.station, sizeof(pch_param.station), 0444); MODULE_PARM_DESC(station, - "IEEE 1588 station address to use - column separated hex values"); + "IEEE 1588 station address to use - colon separated hex values"); MODULE_AUTHOR("LAPIS SEMICONDUCTOR, <tshimizu818@gmail.com>"); MODULE_DESCRIPTION("PTP clock using the EG20T timer"); |